개인 자료란 (JE)

  서버 커뮤니티

한국 마인크래프트 포럼

마인크래프트 자료 및 커뮤니티 플랫폼

전체 회원수 122,901명 ( +21명 )

※ 장기간 미활동 회원 제외

Profile 분열 대표칭호 없음
Profile

커뮤니티new 개발자란new 개발자 강좌new 플러그인

벡터를 이용해서 호밍을 해보자

2020.04.23 조회 수 512 추천 수 0

둘어가기에 앞서 벡터개념은 저도 아직 배우는 단계라 미숙한점 양해 바랍니다.


일반적으로 매직스펠이나 기타 플러그인을 보다보면 화살 혹은 눈덩이를 발사했을때, 그 투사체가 대상을 쫒아가는 경우가 있죠?

이걸 호밍 (투사체 추적)이라고 합니다. 

마인크래프트 상에서 발사되는 투사체는 방향과 속력을 가진 벡터로 나타낼 수 있으며, 이 '벡터'값을 변경함으로써 투사체가 날아가는 방향을 변경할 수 있습니다.

 예를 들어, 눈덩이를 던졌을때 눈덩이가 가진 벡터를 2배로 설정하면 속력이 2배가 되어 더 빠르고 멀리 날아가게 됩니다. 또한,  눈덩이가 가진 벡터와 방향이 반대인 벡터로 설정하면 (혹은 -1배) 투사체가 거꾸로 날아가게 됩니다. 

그러면 무언가를 발사했을때, 그 투사체가 대상에게 무조건 맞을려면 어떻게 해야할까요?


1. 발사하자마자 대상을 향하는 벡터를 생성한다음 가속시켜(10배정도) 투사체에게 씌운다.

2. 주기적으로 투사체에서 대상으로 향하는 벡터를 생성한다음 투사체에게 씌운다.


1번의 경우 발사즉시 대상에게 투사체가 날아가 꽂히게 되지만, 호밍의 느낌이 살지 않습니다. 

2번의 경우 속도가 느리긴 하지만, 대상을 추적한다는 느낌이 강하게 듭니다.


아래는 코드 예시입니다.

1. 즉시 가속

@EventHandler (priority = EventPriority.LOWEST) //왠지 써야할거 같은 annotation
public void onProjectileLaunch(ProjectileLaunchEvent e){
     Player p = Bukkit.getServer().getPlayer("닉네임"); 
     //Raycast를 못써서 타겟을 처음부터 지정합니다..ㅜㅜ
     Location loc = p.getEyeLocation();
     Location loc1 = e.getEntity().getLocation();
     Vector vector = new Vector(loc.getX()-loc1.getX(), loc.getY()-loc1.getY(), loc.getZ()-loc1.getZ()).normalize();
     //투사체에서 타겟의 위치로 향하는 벡터를 생성후 일반화 시킵니다. (단위벡터화..?)
     e.getEntity().setVelocity(vector.multiply(10));
     //투사체에게 10배로 가속시킨 벡터를 씌웁니다.
     
}

벡터의 경우 대상의 X-투사체X, 대상의Y-투사체Y, 대상의Z-투사체Z를 뺀 값을 벡터로 생성하면 투사체에서 대상으로 향하는 벡터가 생성됩니다.

이 코드를 적용후 화살을 쏘면 즉시 대상에게 날아가 즉사시키는걸 볼 수 있습니다.

ac4ee45f316973478c42c43fe3496f61.png

대충 날아가자마자 즉사되는 모습 (마인크래프트 자체 버그로 투사체의 속도가 일정 수준 이상을 넘어가면 이상하게 보입니다.)

2. 느린 호밍

@EventHandler (priority = EventPriority.LOWEST)
public void onProjectileShoot(ProjectileLaunchEvent e){
    Player p = Bukkit.getServer().getPlayer("닉네임");
    Bukkit.getScheduler().scheduleSyncRepeatingTask(main.instance, new Runnable() {
        //대충 0.25초 주기로 반복하는 스케줄러 이벤트
        int count = 0;
        //과부화 방지를 위한 카운트
        @Override
        public void run() {
            count++;
            if (count == 100)
                //카운트가 100이 될경우 강제중단 (귀찮아서 모두 중단으로 변경 = 25초)
                Bukkit.getScheduler().cancelAllTasks();
            Location loc = p.getEyeLocation();
            Location loc1 = e.getEntity().getLocation();
            Vector vector = new Vector(loc.getX()-loc1.getX(), loc.getY()-loc1.getY(), loc.getZ()-loc1.getZ()).normalize();
            //매번 투사체에서 대상을 향하는 벡터 생성
            e.getEntity().setVelocity(vector);
            //벡터씌우기
        }
    },0L,5L);
}

이 코드를 적용하면 모든 투사체들이 천천히 대상을 향해 날아가는 모습을 보실 수 있습니다.

e1c68002f3ec8ff63801d949565d1b7d.png4bb865ef672c8923dcba1a49eed12875.png43f70a9907ca1f0e7d15ad87162c99d4.png0210f1242e22a3864fc2a33e08812ad5.png

대충 역동적인 스샷

하지만 호밍의 가장 큰 단점이라고 하면, 장애물이 있는경우 해당 대상을 타격 못한다는것을 들 수 있겠네요.

이것도 pathfinding이라는 길찾기 알고리즘을 이용한다면 가능하겠지만, 저는 그런 능력자가 아니기때문에 패쓰


+ Skript ver (Skquery필요)

make %entity% home towards %location% 
//1번
make %entities% home towards %location% normally
//2번, 루프문 돌려서 계속 따라가게 만들면 깔끔

오늘도 글 봐주셔서 감사합니당


Warning
댓글이 없습니다.

새로운 댓글을 등록해 주세요!

컨텐츠
https://www.koreaminecraft.net/files/thumbnails/180/890/002/262x150.crop.jpg?20211025201038

시험지

한마탐 5주차 (한마포 마인크래프트 탐구 영역) (10 / 25) 3

베개냥이

2021-10-25

2

https://www.koreaminecraft.net/files/thumbnails/291/881/002/262x150.crop.jpg?20211021165153

데일리픽

초간단 전투기 만들기 8

megat88

2021-10-20

4

https://www.koreaminecraft.net/files/thumbnails/850/878/002/262x150.crop.jpg?20211018191640
(포션 시리즈) 3편 - 비 3

GlassesFilm

2021-10-18

4