내일배움캠프 51일차 6/27 TIL + NavMesh2D
NavMesh Plus
2D용 NavMesh 사용법 정리 원본 깃허브 : NavMesh Plus GitHub Wiki
INTRO
먼저 Unity의 “2D 템플릿”에서 새 프로젝트를 생성합니다. NavMeshPlus를 다운로드하여 NavMeshComponents를 Assets 폴더에 복사합니다. 이제 씬에서 마우스 오른쪽 버튼을 클릭하고 메뉴에서 Create Empty를 선택하여 씬의 루트에 빈 GameObject를 추가합니다. 새 빈 GameObject의 이름을 “NavMesh”로 지정합니다.
NAV MESH BASICS
- 레이아웃 설정:
- “Layout”이라는 새로운 루트 GameObject를 만들고, 그 아래에 “GameFloor”라는 자식 GameObject를 추가합니다.
- “GameFloor”에 스프라이트를 드래그 앤 드롭하면 SpriteRenderer 컴포넌트가 자동으로 추가됩니다.
- “GameFloor”에 NavigationModifier 컴포넌트를 추가하여 탐색 소스로 표시합니다.
- NavMeshSurface 추가:
- “NavMesh” 오브젝트를 선택하고, 인스펙터에서 Add Component를 클릭한 다음 NavigationSurface를 선택합니다.
- NavigationCollectSources2d 컴포넌트를 추가하고 Surface를 XY로 회전한 후 Bake를 클릭하여 탐색 가능한 평면을 빌드합니다.
- 장애물 추가:
- “Layout”에 “Pond”라는 이름의 오브젝트를 추가하고, 작은 스프라이트를 드롭합니다.
- NavigationModifier 컴포넌트를 추가하고 Override Area를 체크한 다음 Area Type 필드에서 Not Walkable을 선택합니다.
- 다시 “NavMesh” 오브젝트에서 Bake를 클릭하여 “Pond”를 탐색 영역에서 제외시킵니다.
- NavMeshAgent 설정:
- NavMeshAgent 컴포넌트를 가진 GameObject를 추가합니다.
-
NavMeshAgent 컴포넌트가 GameObject를 회전시키는 것을 방지하려면 다음 스크립트를 추가합니다:
void Start() { var agent = GetComponent<NavMeshAgent>(); agent.updateRotation = false; agent.updateUpAxis = false; }
GEOMETRY OPTIONS
Unity 2019.3에서 도입된 새로운 API를 사용하면 사용할 지오메트리 소스를 선택할 수 있습니다.
- Physics Colliders 사용:
- 모든 2D 콜라이더를 NavigationModifier와 함께 “Layout” GameObject에 자식으로 배치합니다.
- Use Geometry 옵션을 Render Meshes에서 Physics Colliders로 변경하고 Bake를 클릭합니다.
TILED
Tilemap 시스템의 일부인 오브젝트를 베이크할 수 있습니다.
- Tilemap 설정:
- 씬에 Tilemap GameObject를 추가합니다.
- Grid 오브젝트의 자식으로 Tilemap GameObject를 추가하고 각각 “Ground”, “Walls”, “Pond”로 이름을 지정합니다.
- NavigationModifier를 각 Tilemap에 추가하고 해당 영역을 Walkable 및 Not Walkable로 오버라이드합니다.
- Bake를 클릭하여 NavMesh를 빌드합니다.
TILE MODIFIER
각 타일이 세계의 속성을 나타내므로, TileSet의 각 타일에 네비게이션 수정자를 할당할 수 있습니다.
- NavigationModifierTilemap 사용:
- NavigationModifierTilemap에 새 요소를 추가하고 자산에서 타일을 선택합니다.
- 각 타일을 NavigationModifier 위에 오버라이드하거나 기본 상태로 유지합니다.
- Bake를 클릭하여 단일 TileMap에 레이어가 없는 결과를 얻습니다.
MAZES
미로를 통해 탐색할 수 있도록 설정할 수 있습니다.
- 기본 설정:
- “NavMesh”를 Not Walkable로 설정하고 NavigationModifier 컴포넌트를 Walkable로 설정합니다.
- Bake를 클릭하여 미로 내에서 탐색할 수 있도록 합니다.
OTHER GRIDS
NavMeshPlus는 육각형, 등각, 다이아몬드형 그리드와 같은 다른 유형의 그리드도 지원합니다.
OVERRIDE BY
타일 맵을 통해 네비게이션할 때는 스프라이트 메쉬를 재정의할 수 있습니다.
- 스프라이트 메쉬 재정의:
- 타일 형태의 메쉬를 가져와 씬에 추가하고, NavMeshCollectSources2d 컴포넌트의 Override By Grid를 체크합니다.
- Bake를 클릭하여 타일의 메쉬 모양을 사용합니다.
BAKE AT RUNTIME
프로시저 생성된 월드를 가지고 있을 때 런타임에 NavMesh를 빌드할 수 있습니다.
- 런타임 베이크:
-
BuildNavMeshAsync 메서드를 호출하여 NavMesh를 빌드합니다.
public NavMeshSurface Surface2D; void Start() { Surface2D.BuildNavMeshAsync(); }
-
- 업데이트:
-
동적 월드의 경우 UpdateNavMesh를 호출하여 CPU 활용을 절약합니다.
public NavMeshSurface Surface2D; void Update() { Surface2D.UpdateNavMesh(Surface2D.navMeshData); }
-
KNOWN ISSUES
NavMeshAgent 컴포넌트가 Y 축을 따라 이동할 때 멈추거나 설정된 agent.velocity가 작동하지 않는 문제가 있습니다. 이러한 경우를 해결하려면 에이전트의 이동을 조정하는 스크립트를 추가해야 합니다.
static float agentDrift = 0.0001f; // 최소 드리프트 값
void SetDestination(GameObject target)
{
if (Mathf.Abs(transform.position.x - target.transform.position.x) < agentDrift)
{
var driftPos = target.transform.position + new Vector3(agentDrift, 0f, 0f);
agent.SetDestination(driftPos);
}
}