Navigation Mesh 이용하여 이동할 수 없는 구역 막기
Window - AI - Navigation 을 누른뒤
Navigation탭의 Bake 버튼을 눌러준다.
시간이 지나면 이렇게 플레이어가 이동할 수 있는 구역을 자동으로 계산해주는 것을 알 수 있다.
사전에 올라갈 수 있는 각도와 높이를 설정하면 그것을 계산해주는 것이다.
그 다음은 NavMesh Component를 이용한다.
코드를 아래와 같이 변경하면 건물에 부딪혔을때 여전히 이동모션을 보인다.
Vector3 dir = _destPos - transform.position;
if (dir.magnitude < 0.1f)
{
State = PlayerState.Idle;
}
else
{
NavMeshAgent nma = gameObject.GetOrAddComponent<NavMeshAgent>();
float moveDist = Mathf.Clamp(_stat.MoveSpeed * Time.deltaTime, 0, dir.magnitude);
nma.Move(dir.normalized * moveDist);
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(dir), 20 * Time.deltaTime);
}
이를 해결하기 위해
이동하지 말아야할 오브젝트들을 Block이라는 이름의 Layer로 지정해두자.
이제 Block Layer에 있는 물체에 RayCast를 해서 앞에 물체가 있으면 Idle 상태가 되도록 코드를 수정한다.
Vector3 dir = _destPos - transform.position;
if (dir.magnitude < 0.1f)
{
State = PlayerState.Idle;
}
else
{
NavMeshAgent nma = gameObject.GetOrAddComponent<NavMeshAgent>();
float moveDist = Mathf.Clamp(_stat.MoveSpeed * Time.deltaTime, 0, dir.magnitude);
nma.Move(dir.normalized * moveDist);
Debug.DrawRay(transform.position + Vector3.up * 0.5f, dir.normalized, Color.green);
if (Physics.Raycast(transform.position + Vector3.up * 0.5f, dir, 1.0f, LayerMask.GetMask("Block")))
{
if (Input.GetMouseButton(0) == false)
State = PlayerState.Idle;
return;
}
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(dir), 20 * Time.deltaTime);
}