원래 기능
이전 코드는 플레이어 오브젝트와 enemy 오브젝트간의 거리를 계산하여 플레이어가 적에게 설정해놓은 반경에 들어오면 적이 따라가거나 공격하는 상태로 변환
레이캐스팅을 이용한 플레이어 감지
플레이어를 공격하는 상태로 변환하는 조건에 레이캐스팅을 추가하여 플리에어가 레이에 부딪히면 공격상태로 전환
protected bool IsInAttackRange() { Vector3 enemyPosition = stateMachine.Enemy.transform.position + new Vector3(0, 1f, 0); float attackRange = stateMachine.Enemy.Data.AttackRange; Vector3 RayDirection = stateMachine.Enemy.transform.forward; // 레이캐스트를 사용하여 장애물 검출 Ray ray = new Ray(enemyPosition, RayDirection); RaycastHit hit; if (Physics.Raycast(ray, out hit, attackRange)) { if (hit.collider.CompareTag("Player")) { float playerDistanceSqr = (stateMachine.Target.transform.position - stateMachine.Enemy.transform.position).sqrMagnitude; return playerDistanceSqr <= stateMachine.Enemy.Data.AttackRange * stateMachine.Enemy.Data.AttackRange; } } return false; }
두 번째 문제점
위 방법으로 구현을 했을 때 벽 너머의 플레이어를 공격하지는 않았지만 플레이어를 감지하고 따라가는 상태가 벽 바깥에 있는 플레이어 방향으로 계속해서 움직여서 enemy가 벽쪽으로 계속해서 뛰어가는 문제 발생
내비게이션 시스템 이용
유니티 패키지의 내비게이션을 이용하여 벽이나 장애물들을 피해서 움직이도록 설정
패키지 설치
Window - Package Manager - Packages:Unity Registry로 변경 후 Navigation 검색 - AI Navigation 설치
내비게이션 창
상단 메뉴바에서 [Window > AI > Navigation(Obsolete)] 선택
Bake를 누르고 릭터가 길을 찾아서 이동할 수 있는 영역을 생성
enemy에게 Nav Mesh Agent 할당
코드 수정
적이 움직이는 코드가 있는 스크립트에
protected NavMeshAgent navMeshAgent;
navMeshAgent = stateMachine.Enemy.GetComponent();
를 선언한 후 초기화 해주고 갈 방향을 정해주는
private Vector3 GetMovementDirection() { return navMeshAgent.desiredVelocity.normalized; }
GetMovementDirection 수정
이제 벽 너머의 적을 공격하지도 않고 벽을 계속해서 돌진하지도 않도록 변경되었습니다.
Bake 탭에서는 NavMesh의 속성을 설정
출처 : https://youtu.be/kq2WLo3nSOk
navMeshAgent.desiredVelocity는 네비게이션 시스템에서 에이전트가 현재 이동하려는 방향의 속도 벡터
navMeshAgent.desiredVelocity.normalized는 현재 네비게이션 에이전트가 이동하려는 방향을 단위 벡터로 반환하며, 에이전트의 이동 방향을 나타내게 됨.