본문 바로가기
프로그래밍/유니티

[Unity NavMesh] 확장: 움직이는 길을 네비게이션 메쉬 영역으로 설정하기 (1 - 기본 베이크)

by 김시루시루르 2021. 11. 17.

움직이는 메쉬를 네비메쉬 (네브메쉬? 내비메쉬?) 영역으로 설정한다? 이걸 보신 분들은 대충

아 실시간 Bake 인 건가? 하실 수 있습니다.

 

하지만 유니티에 실시간 베이크따위는 존재하지 않습니다. (있었으면 레테가 좀 더 편했을텐데요)

그래서 실시간 베이크도 할 수 없고

그렇다고 뭔가 다른 방법의 툴을 만들기엔 시간이 너무 부족하고

에셋을 사기엔 돈이 너무 없었던 제가 선택한 방법을 적어보려고 합니다.

 

기록용이라.. 별 .. 정보값은 없을 수도 있어요

그런데 이래저래 부가적인 내용은 많아서 꽤 긴 시리즈물이 될듯 (?)


계기

여러분이 마주한 문제가 이 문제가 맞는지 확인하셔야 하니 문제상황을 적습니다...

 

Lethe-레테의 가장 기본적인 로직을 설정하려고 할 때의 일인데

레테가 '걸어다닐 수 있는 큐브 위를 걷는다'는 전제 하에,

플레이어가 선택한 곳으로 자동으로 이동하게 하고 싶었어요. 편의성이랄까?
보이지 않는 길을 그냥 방향키 눌러서 갈 수 있다면 재미가 없을거라고 생각했거든요

지금이니 하는 말이지만 큐브 뒤에 숨겨둔 것도 꽤 많고 (큭큭)

 

그래서? 자동 이동을 쓴다? 그럼 NavMesh를 지금이야말로!

라고 생각해서 네비메쉬를 본격적으로 만지게 됐는데...

움직이는건 뭐 좀 만지니까 됐어요 그런데 큰 문제는 당연히 이거였죠

"움직이는 길은 어떻게 하지?"

원래는 여기에 길이 없는데, 큐브를 움직여서 여기에 길이 생겨

그런데 네비메쉬는 미리 베이크해둔 길을 따라서 이동경로를 계산하는거란 말이죠

그러니 내가 여기에 길을 안 만들어두면 레테는 이 움직이는 큐브 위에 절대 탈 수가 없는거예요

 

지형이나 장애물로 설정하기에도 크게 달라지는 게 없고 정말 .. 의미가 없어서

크윽 대체 어떻게 해야한단 말이냐! 싶을 때 문득.. 뇌리를 스쳐간 해결법

이렇게 거창하게 적긴 했지만 정말 별 거 아닙니다


해결! 미리 베이크하기

ㅋㅋㅋㅋ

근데 정말 이것뿐이었어요 네비메쉬를 쓴다면 말이죠...

 

레테의 경우 퍼즐 내의 큐브를 움직일 수 있는 방향이 전후상하좌후,

즉 x·y·z축으로 고정되어있었고, 큐브를 이동할 수 있는 조건이 제법 한정되어 있기 때문에

이 방법이 더 유용하게 작용했는지도 모르겠습니다.

 

플레이어가 움직일 수 있는 큐브의 경우의 수를 전부 계산하는거죠

이렇게 들으면 엄청 많아보이는데 사실 그렇지도 않은 게

결과적으로 '레테가 이 길을 갈 수 있는가?'만 따지면 되거든요

그러니까 아무리 저 멀리에서 큐브가 어디로 움직일 수 있든 간에,

레테가 그 큐브에 갈 수 없다면 그 길은 의미 없는 길인 셈이죠...

 

그래서 큐브가 이동할 수 있는 경로 중 레테가 갈 수 있는 경로만을 남기고...

그 경로에 메쉬가 없다면 메쉬를 깔아줍니다 (?)

저는 이걸 제 머릿속 작업으로 해서 실수도 자주 나왔는데, 계산 알고리즘을 짜는 것도 좋을 것 같아요.

저는 큐브와 똑같은 크기의 육면체를 만들어서 메쉬를 배치했습니다.

 

이 스테이지의 네비메쉬에서는 플레이어의 실수도 계산되어있습니다.

레테가 있는 쪽의 큐브를 움직인 게 아니라, 반대쪽의 큐브를 움직였을 때의 실수입니다.

플레이어가 실수를 했든 아니든간에 레테의 이동은 자연스러워야 하므로,

플레이어의 실수도 계산에 넣어 베이크한 것입니다.

그리고 그 임시 메쉬에도 Navigation Static을 부여해줍니다.

그래야 네비메쉬 베이크에서 이 메쉬도 함께 베이크되니까요.

그리고 베이크 설정을 손봐준 뒤, 임시 메쉬와 함께 베이크합니다.

그럼 왼쪽과 같은 형태로 베이크가 되겠죠? 그 상태에서 임시 메쉬를 비활성화 합니다.

그래도 베이크 정보는 그대로 남아있기 때문에, 여전히 레테는 파랗게 베이크된 곳을 지나갈 수 있습니다.

밟을 수 있는 진짜 메쉬가 거기 없더라도요.


 

베이크 문제 (Lethe-레테 제작과정에서)

1. 상하 이동

별 큰 문제는 아니었지만 문제였던 것.

레테가 위아래로 움직이는 경우도 게임에 존재합니다.

그래서 위아래로 움직일 때도 그 길을 예상하고 베이크를 해줘야 하는데...

위와 같이 1:1:1의, 높이가 좀 있는 임시 메쉬로는 불가능하더라고요 (당연함. 메쉬가 한 칸이니까요.)

그래서 메쉬 높이를 줄이고, 네비메쉬 설정에서 에이전트의 높이도 그 사이를 지나갈 수 있게 줄였습니다.

실제 레테의 메쉬 크기와는 별개로요 (ㅋㅋ) 기계를 이렇게 속이세요 (?)

그러면 왼쪽처럼, 같은 x, z 좌표상에 있고 y값이 1씩 차이나는 큐브들의 위를 전부 지나게 할 수도 있습니다.

 

참고로 이 이미지는 22-2스테이지의 네비메쉬 이미지입니다만,

다른 곳에 사용할 목적으로 캡쳐해뒀던거기도 해서 편집 및 단순화되어있습니다.

인게임의 메쉬는.. 저렇게 되어있지 않다는거죠 (크하핫)


2. 숨은 길

이것도 큰 문제는 아니지만...

특정 큐브를 치워야만 마침내 지나갈 수 있는 길이 종종 존재합니다.

가령 이 이미지의 예시에서 보면, 오른쪽의 열쇠가 있는 큐브가 치워져야 저 길을 갈 수 있게 되겠죠.

(이것도 편집된 예시라 실제 게임에선 다를 수도 있습니다.)

 

그럴 땐 베이크할 때 살짝, 그 위를 덮는 메쉬를 치워준 뒤 베이크하고, 베이크한 뒤에 다시 제 자리에 둡니다.

이 메쉬의 Static 설정을 빼는 방법도 있긴 합니다만 전 .. 그냥 치웠다가 다시 올렸어요.

이 해결방법 자체가 기본적으로 "한 번 베이크 하면 그 베이크가 유지된다!"를 이용하는 것이므로,

그걸 잘 생각해서 해주시면 됩니다.


3. 메쉬 면적이 너무 좁을 때

이건 이 해결방법의 문제만은 아니겠지만.

에이전트 설정을 어떻게 하든간에, 메쉬 면적이 너무 좁아서 마음처럼 베이크가 되지 않을 때도 있어요.

(심지어 면적이 너무 좁으면 x·y·z 값에도 영향 받는 것 같더라고요)

 

레테에서는 모든 큐브가 유니티 스케일 1:1:1정도의 크기였기 때문에

네비메쉬가 '작다!'고 인식한 것 같더라고요.

하긴 애초에.. 이 시스템은 이렇게 쓰라고 있는 게 아니니깐...

 

근데 여기서 에이전트 지름을 줄이면 내가 원하는대로 베이크가 안 되는거야 (너무 넓어)

그럼 또 문제가 될 수 있다고 생각해서... 다른 방법을 찾았어요

면적을 그냥 늘려주는거야

이 글 점점 꼼수 글이 되어가는것같아 하지만 어쩌겠습니까? 제가 그렇게 한 거를...

 

왼쪽처럼 그냥 한 칸의 큐브 위에 있을 때 그냥 하면 베이크가 안 됩니다.

그런데 이 때 임시 메쉬를 좀 더 붙여주면? 면적이 넓다고 계산되면서 네비메쉬 영역에 포함되는거죠.

오른쪽처럼 됩니다.

 

이 때 주의해주셔야 할 점이라면...

네비메쉬 자체가 '목적지에 갈 수 없다면 가장 가까운 곳으로라도!' 식으로 작동하기 때문에

길과는 전혀 무관한 임시 메쉬를 붙일 때에는 최대한 맵 바깥쪽으로,

다른 메쉬가 없는 쪽으로 붙여주는게 좋습니다.


게임 문제

네비메쉬를 이렇게 계속 사용하게 되면서 아래의 문제들이 발생했습니다.

 

1. 큐브는 없지만 메쉬 설정이 되어있어 하늘을 걷는 레테

2. 이동하는 큐브 위에 레테가 있을 때

 

사실 이 두 개는 아직 완벽하게 해결했다고 하긴 어렵지만 (특히 1번)

그래도 어느정도.. 고치기는 했으므로?

 

 

[Unity NavMesh] 움직이는 길을 네비게이션 메쉬 영역으로 설정하기 (2 - 이동 제한)

바로 전 글이었던 "움직이는 길을 네비게이션 메쉬 영역으로 설정하기 (1)"에서 이어지는것입니다. 거기서 언급했던 문제들이 있는데요... 2번에선 예정대로 그걸 써볼까 하고 [Unity NavMesh] 움직이

drybone-developer.tistory.com


다른 해결법

1. 직접 A*를 구현하기

구현하면서 이제 큐브마다 노드를 배치하고, 이동 가능 여부 계산을 실시간에 가깝게 하는거예요

예를 들면 큐브가 움직였다! = 지형에 변화가 생겼다니까

그때 다시 노드의 연결관계를 계산하는거죠.

사실 레테는 이동 가능한 거리가 무조건 1 내외로 정리될테니까 계산도 그다지 어렵지 않을지도

하지만 이걸 그때부터 만들기엔 시간이 너무 모자랐어

 

2. 에셋

실시간으로 노드 계산을 하는 A* 에셋이 있더라고요 (가격은 꽤.. 함)

사업 참여할 때 사업비로 이거 산다고 올렸는데 결재가 늦게돼서 결국 못했어 (음악도 부랴부랴 외주넣음ㅋㅋ)

게임 완성은 해야하잖아요 흑흑.

하지만 지금도 가끔 짬내서 연구중이긴 합니다. 더 깔끔한 게임 경험을 위해서...

여러분도 참고해보세요.

 

A* Pathfinding Project Pro | AI | Unity Asset Store

Get the A* Pathfinding Project Pro package from Aron Granberg and speed up your game development process. Find this & other AI options on the Unity Asset Store.

assetstore.unity.com

댓글