네비게이션 기능중 특정 경로에 가중치를 적용해 NavMeshAgent에서 최단 거리를 계산할 때 경로의 가중치를 줄수 있다. 예를 들어 평지와 진흙길에 가중치를 줘 쉬운길로 갈 수 있게 한다.

 

경로의 가중치

내비게이션뷰의 Ares탭을 클릭하면 Area Mask와 Cost를 설정할 수 있다. 여기에 다음과 같이 3개의 Area Mask를 지정하고 각각 Cost를 입력한다.

스테이지에 다음과 같이 세 갈래 길을 구현하고 각각 Area Mak를 Road, Mud, Water,Stair로 지정한다.

교재에서는 패스를 3개 만들라고 했는데 그냥 하이라키뷰에서 Stair를 선택하고 내비게이션 뷰의 Object탭에서 Area Mask를 선택할 수 있다. 

 

교재에 의하면 Bake후 가중치에 따라 색깔도 바뀐다고 한다.

몬스터의 이동은 NavMeshAgent에 의해 관리되고 있다. 이동하면서 회전하기 때문에 회전이 부자연스럽다. 좀더 빠르게 회전하도록 직접 회전로직을 구현해본다.

MonsterCtrl 스크립트의 Awake함수를 수정하고 Update함수를 다음과 같이 추가한다.

updaterotation=false로 자동회전기능을 비활성화 시켰다. updatePosition=false로 자동 추적기능을 끌수도 있다.

void Awake() {
	//중략
    agent = GetComponent<NavMeshAgent>(); //NavMeshAgent 할당
    agent.updateRotation= false; // 자동회전기능 비활성화
	//중략   
}

agent.remaingDistance는 타겟까지 남은 거리이다. agent.desiredVelocity는 장애물을 고려한 이동방향이다.

private void Update() {
    //목적지 까지 남은 거리로 회전여부 체크
    if(agent.remainingDistance >= 2.0f) {
        Vector3 direction = agent.desiredVelocity;
        Quaternion rot = Quaternion.LookRotation(direction);
        monsterTr.rotation = Quaternion.Slerp(monsterTr.rotation, rot, Time.deltaTime * 10.0f);
    }
}

이외 velocity, pathPending, isPathStale 등의 속성이 있다.

 

자동 생성된 Off Mesh Link는 Drop Height 높이 이내면 무조건 생성되어 특정지점만 만들고 싶을 경우 적합하지 않다. 이제부터 계단 상단에서 바닥으로 연결하는 하나의 사용자정의 Off Mesh Link를 만들어 보자.

Stair선택후 네비게이션뷰의 [Object]탭에서 Generate OffMeshLinks 속성을 언체크하고 [Bake]탭을 눌러 다시 베이크하면 앞서 생성되었던 Off Mesh Link들이 모두 사라진다.

 

Stair 하위에 빈 게임오브젝트를 2개 만들어 StartPos,EndPos로 이름을 바꾸고 StartPos는 계단 맨위, 착지할  EndPos는 그 아래 바닥에 겹치게 배치한다.  관찰하기 좋게 MyGizmo 스크립트를 추가한다.

교재에서는 Off Mesh Link가 자동으로 연결된다는데 실수로 지웠는지 Stair 인스펙터뷰에 Off Mesh Link컴포넌트를 추가해주고 Start,End가 자동으로 연결안되어 있으면 연결해 줬다.

Bidirectional 은 양방향으로 점프할수 있다는 뜻이고 Activated는 Run Time시 Off Mesh Link를 활성화 하는 것이다. Auto Update Positions는 RunTime시 링크위치가 동적으로 바뀌는 것에 대응한다.

 

 

내비게이션은 3D메시의 정보를 기반으로 네비메시를 생성한다. 따라서 분리된 메시는 추적할 수 없다. 이때 Off Mesh Link를 통해 서로 분리된 메시를 연결할 수 있다. 즉, 추적이 가능하게 연결고리를 생성할 수 있다.

다운로드한 Resources/Models 폴더에 있는 Stair패키지를 설치한다.

프로젝트뷰에 임포트된  Stair폴더는 05.Models로 옮긴다.

Stair 폴더 하위에 있는 Stair모델을 씬뷰로 드래그해서 적절한 위치에 배치한다. 아래부분이 바닥에 묻히게 조절한다.

추가한 Stair는 _STAGE하위로 차일드화 한다. Stair를 선택후 인스펙터뷰에서 Navigation Static과 Off Mesh Link를 선택한다. 인스펙터뷰 Navigation탭에서도 선택할 수 있다.

Navigation Bake TAB을 클릭후 Generated Off Mesh Links-Drop Height을 5로 설정한다. 이는 Off Mesh Link가 생성되는 최대 높이를 지정하는 것이다.

 Bake를 눌러 내비메시를 생성하면 다음과 같이 연결선이 보인다.

계단에 Collider를 추가해 올라갈수 있게 해준다. 연산부하를 줄이기 위해 Mesh Collider컴포넌트의 Convex속성을 체크해 폴리곤수를 낮춘다.

Navigation뷰의 Bake탭의 Agent Radius를 0.2로 변경후 Bake하면 좀더 촘촘하게 Off Mesh Link가 생성된다.

이제 실행해서 계단을 올라가면 몬스터들이 따라온다.

처음에 Player가 계단을 못올라 가서 헤맸는데 다음과 같이  Player collider의 Trigger를 꺼주고 해결하였다. 그리고 교재와 Rigidbody 속성이 달라 수정하였다

드럼통 폭발이후에도 적 몬스터는 그 지점을 장애물로 인식하는 문제점이 있다. 이는 내비게이션 메시가 정적으로 Bake되어 졌기 때문이다. 이 문제는 NavMeshObstacle 컴포넌트로 해결할 수 있다.

Barrel Prefab을 선택후 이름 우측 Static을 Off한후 children에 반영시킨다.

메뉴>window>AI>Navigation을 선택해 뷰에서 Bake탭을 선택후 아래 베이크 버튼을 클릭한다.

씬뷰에서 보면 Floor바닥 전체가 내비메시로 베이크된다.

배럴 프리팹 원본을 선택후 인스펙터뷰 이름옆 Open을 눌러 에디트 모드로 전환된다. NavMeshObstacle을 추가한다.

 NavMeshObstacle 속성을 다음과 같이 변경한다.  Auto save기능이 있기 때문에 하이라키뷰"<"나 씬뷰[Scenes]을 클릭해 돌아가도 자동으로 저장된다.

Carve옵션을 체크하면 실시간으로 내비메시가 변경되지만 부하를 줄이기 위해 최적의 옵션값을 설정해야한다. 

Move Threshold : 갱신할 최소거리

Time To Stationary : 갱신한 최소 정지시간

Carve Only Stationary : 정지 상태에서만 내비메시를 갱신한다.

 

 

+ Recent posts