개인 자료란 (JE)

  서버 커뮤니티

Profile 분열 대표칭호 없음
Profile

강좌 자바 에디션(JE) 플러그인 개발

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

2020.04.23 조회 수 1201 추천 수 1
분야 플러그인 
장르 개발자 툴 
게임버전 모든버전 
API 스피곳, 페이퍼 

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


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

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

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

 예를 들어, 눈덩이를 던졌을때 눈덩이가 가진 벡터를 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번, 루프문 돌려서 계속 따라가게 만들면 깔끔

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




1개의 댓글

Edeep
2022.02.23

신기하네요ㅋㅋㅋ

뉴스 및 창작물
/files/thumbnails/268/789/003/262x150.crop.jpg?20240515192032

레드스톤

벌레먹은 돌 빠르게 제거하는 법

GlassesFilm

2024-05-15

0

/files/thumbnails/797/788/003/262x150.crop.jpg?20240515090924

건축

마인크래프트로 구현한 카르카손 보드게임

Warak

2024-05-15

1

/files/thumbnails/487/784/003/262x150.crop.jpg?20240508233607

모드

Windows Borderless 모드에서 악성코드 발견

학교가기싫다

2024-05-08

1

/files/thumbnails/384/778/003/262x150.crop.jpg?20240512002324

업데이트

마인크래프트 자바 에디션 스냅샷 24w18a

학교가기싫다

2024-05-06

0

/files/thumbnails/855/781/003/262x150.crop.jpg?20240505141129

레드스톤

레이저 클리너

GlassesFilm

2024-05-05

1

/files/thumbnails/576/775/003/262x150.crop.jpg?20240426232553

아티클

이달의 블록: 단단한 진흙

학교가기싫다

2024-04-26

0

/files/thumbnails/115/774/003/262x150.crop.jpg?20240428135129

업데이트

마인크래프트 1.20.5 정식 업데이트

학교가기싫다

2024-04-24

0