티스토리 뷰

이전에, AI Navigation에 대해서 정리한 적이 있다. [알고 보니, 정리를 안했었다...;;]

[참고 URL: https://lsu0503.tistory.com/140]

nav Mesh라는 기능을 이용해서 각 영역에 대한 가중치를 설정했다면 목적지로 향하는 최적 경로를 찾아내어 오브젝트를 이동시키는 기능으로, 복잡한 지형이나 벽 등을 구현할 때에 유용한 패키지인데...

이 패키지는 3D 환경 만 지원한다.

즉, 2D 환경에서는 다른 방법을 찾아야 한다는 것이다.

 

그렇다면, 2D게임을 제작할 때에는 최적 경로 탐색 알고리즘을 직접 작성해야 하는 것일까.

물론, 그렇게 하는 방법도 있다. 최적 경로 탐색 알고리즘은 이젠 검색 만 해도 찾아볼 수 있는 실정이고, 타일 맵으로 작업되는 경우가 많은 2D 환경에서는 거리에 대한 기준도 명확한 편이라, 상대적으로 최적 경로 탐색 알고리즘을 편성하기가 수월한 편이다.

다만, 그렇다고 하더라도 최적 경로 탐색 알고리즘을 처음 부터 작성하는 것은 매우 수고스러운 방법이다.

 

그렇기에, 어떠한 능력자는 이러한 AI Navigation을 2D에서도 활용할 수 있는 패키지를 제작하였다.

바로 NavMeshPlus다.

[패키지 Git URL: https://github.com/h8man/NavMeshPlus]

※ 설치 및 적용법은 해당 Git의 Readme에 작성이 되어 있다.


NavMeshPlus

간단하게 말하면, AI Navigation의 구성요소들을 2D 환경에서도 다룰 수 있게 해 주는 패키지다.

다만, 기본적으로 AI Navigation의 구성요소들이 2D 환경을 지원하지 않다 보니, 사용법에 차이가 좀 있는 편.

특히, NavMeshPlus라는 점을 보면 알겠지만, 기본적으로 '영역 지정'에 추가 효과를 주는 패키지라서 안의 객체에 해당하는 agent나 obstacle은 AI Navigation의 것을 그대로 사용하는 덕분에, 설정해 줄 부분이 좀 더 있는 편이다.

그럼, 사용법을 알아보자.


Navigation Surface

NavMeshPlus에서 에어리어 정보를 담당하는 컨포넌트.

AI Navigation과는 달리 NavMeshPlus는 이 컴포넌트에서 Bake를 진행한다.

즉, NavMeshPlus에서 반드시 필요한 컴포넌트이자 최종적으로 마무리하는 컴포넌트인 셈이다.

 

참고로, Use Geometry를 조정하면 Nav Mesh의 생성 기준을 변경할 수 있다. SpriteRenderer를 기준으로 Bake 하려면  Render Meshes로 두면 되고, Collider를 기준으로 bake 하려면 Physics Colliders로 두면 된다.


Navigation CollectSources2d

Navigation Surface와 함께 사용하여 영역을 지정할 정보를 가져오는 역할을 하는 컴포넌트.

기본적으로 XZ평면을 기준으로 구성되어 있으며, 이를 RotateSurface to XY 버튼으로 XY평면을 기준으로 하게끔 돌릴 수 있다.

다만, Rotation의 x값을 -90으로 돌리는 방식이라 NavMeshPlus를 위한 오브젝트를 따로 둬야 하는 편이라는 점은 주의하자.


Navigation Modifier

개별 '필드'에 영역 정보를 적용하는 용도의 컴포넌트.

기본적으로 이 컴포넌트가 설정된 SpriteRenderer를 기준으로 Nav Mesh가 설정된다.

 Override Area를 체크하면 Area 항목이 추가되는데, 여기서 해당 오브젝트의 Area 구분을 변경할 수 있다.

즉, 이동 불가 영역을 설정할 수도 있고, 가중치의 설정도 가능하다는 것.


Nav Mesh Agent

AI Navigation에서 사용했던 그 Nav Mesh Agent가 맞다.

이것과 Nav Mesh Obstacle은 AI Navigation 패키지의 컴포넌트를 그대로 사용한다.

그렇다 보니 3D 기준으로 되어있는 특성 덕분에 약간 난감한 점이 있는데, 아무런 설정이 없다면 자동으로 XYZ 기준으로 돌아가 버려서 화면에 완전히 수직이 되어, 보이지를 않게 된다.

때문에, 위 구문을 통해서 자동 회전을 막아줘야 하며[updateRotation], 추가로 Z축 이동도 막아줘야 한다.[updateUpAxis]


이렇게만 설정하면 AI Navigation과 같은 방식으로 사용할 수 있게 된다.

그렇다 보니 난점도 AI Navigation과 동일한데, 그에 대해서도 살~짝 알아보자.


Nav Mesh Agent는 '밀려나'지 않는다.

이게 무슨 말인가 싶을 것이다. 그도 그럴 게, 같은 목적지를 가진 복수 오브젝트들 끼리 흔히 말하는 '비비기'가 발생하기 때문. 다만, Nav Mesh Agent의 velocity 값을 변경해 보면 바로 알 수 있는데, 경로를 벗어나지 않는다.

즉, 넉백도 구현이 불가능하고, 대시를 통해서 목적지를 초과해서 진행하는 것도 구현이 불가능하다.

특히나 NavMeshAgent가 Rigidbody보다 우선도가 높아서 Rigidbody를 조작해도 상술한 부분은 구현이 불가능하다.

 

그렇다면, 어떻게 해야지 구현이 가능한 것일까.

사실 간단하다. Nav Mesh Agent를 끄고, Rigidbody로 이동시키면 된다.

Rigidbody 자체는 기본적으로 Kinematic으로 설정했다가 상술한 넉백이나 대시 발생 시 Dynamic으로 바꾼 뒤 Nav Mesh Agent를 agent.enabled = false로 비활성화한다.

이후 넉백과 대시를 적용하면 된다.

당연히 넉백과 대시가 끝난 뒤에는 원상 복구 시키는 것도 잊지 말자.

그리고 경로에서 벗어났으니 Nav Mesh Agent의 경로도 재 설정해 주는 것도 잊어서는 안될 것이다.

 

이렇게 구성하면 정상적으로 넉백과 대시를 구현할 수 있게 된다.

Finite State Machine으로 구현하면 이런 요소의 조절도 매우 편해지니까 참고하도록 하자.


이것으로 2D 환경에서 최적 경로 알고리즘을 편하게 쓸 수 있는 방법을 알아보았다.

지금 진행 중인 최종 프로젝트에서도 해당 기능을 활용하고 있는데, 본인은 마지막의 Rigidbody 동시 적용을 찾아내느라 꽤 고생했었고, 사실 그렇기 때문에 정리한 글이었다.

[사실, Nav Mesh Agent가 경로 밖으로 나갈 수 없다는 점만 알면 바로 알 수 있는 점이기는 했다.]

 

2D 게임에서도 최적 경로 알고리즘은 매우 흔하게 사용되는 기능이다.

그러니, 그 구현법에 대해서도 익숙해지자. 분명 필요할 것이다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함