Chapter 7-5. AI : Navigation AI
카테고리: Unity Lesson 3
태그: Unity Game Engine
인프런에 있는 케이디님의 [유니티 3D] 실전! 생존게임 만들기 - Advanced 강의를 듣고 정리한 필기입니다. 😀
🌜 강의 들으러 가기 Click
Chapter 7. 동물들의 공격형 AI, 도망형 AI 구현
🚖 Nav Mesh Agent 컴포넌트
장애물, 혹은 갈수 없는 곳을 스스로 인식하고 피해가게 한다.
이전까지 직접 스크립트에 의하여 돼지를 움직이게 했을 땐, 돼지가 장애물이 있더라도 장애물을 뚫으려고 하고 장애물을 피해가지 않았었다. 장애물을 인식 처리를 못해서 그냥 가야할 방향으로 가려고만 했기 때문이다. 👉 Nav Mesh Agent 를 사용하여 돼지가 장애물을 스스로 인식하도록 만들기.
- Nav Mesh Agent 을 통하여 스스로
- 장애물을 인식한다.
- 못 갈 것 같은 곳이면 가지 않는다. (너무 좁은 곳이라거나 등등)
Pig
에게 Nav Mesh Agent 컴포넌트 추가
원기둥 같은 이 영역의 크기를 기준으로 돼지가 통과할 수 있는 곳 인지를 연산하게 된다. 이 원기둥이 돼지의 Nav Mesh Agent
이다. Nav Mesh Agent
는 돼지에게 붙어 다니며 이 Nav Mesh Agent
크기를 바탕으로 갈 수 있는 곳인지 없는 곳인지를 체크한다.
돼지 오브젝트 크기에 맞게 설정해주었다.
- Base Offset
Nav Mesh Agent
이 Y 축 방향 위치.
- Radius
Nav Mesh Agent
반지름
- Height
Nav Mesh Agent
높이
🚖 Navigation : 돼지가 갈 수 있는 곳 설정
Window - AI - Navigation - Bake
Bake
구워서 현재 Terrain 에서 Nav Mesh Agent
가 갈 수 있는 곳 연산.
구우니 이런 결과가 나왔다. 파란색 영역들은 돼지. 즉 Nav Mesh Agent
가 갈 수 있는 지역이다. 너무 가파르거나 도달할 수 없는 지역은 파란색이 적용되지 않았다. 파란색이 적용되지 않은 부분은 장애물로 판단한다. Step Height
로 장애물로 판단할 경사를 수정할 수 있다.
Nav Mesh Agent
가 붙어 있는 오브젝트는 Bake 된 파란 지형들만 갈 수 있다.
장애물로 판단할 오브젝트 설정
돼지가 나무와 돌 오브젝트를 장애물로 판단하고 피해갈 수 있도록 할 것이다.
- 나무와 돌 오브젝트를
static
에서Navigation static
으로 변경해준다.- 자식들까지 전부 적용
- Navigation - Bake 에서 다시 구워준다.
나무와 돌을 장애물로 인식하게 되었기 때문에, 나무와 돌 주변은 더 이상 파란색이 아니다. 이 부분은 이제 Nav Mesh Agent
가 가지 못한다. Bake 구울 때 Agent Radius
값을 크게 하면 이 나무와 돌 주변에 파랗지 않은 영역이 더 넓어진다.
🚖 SetDestination : Nav Mesh Agent 에 의한 이동으로 바꾸기
📜Animal.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class Animal : MonoBehaviour
{
protected Vector3 destination; // 목적지
// 필요한 컴포넌트
protected NavMeshAgent nav;
protected void Start()
{
currentTime = waitTime; // 대기 시작
isAction = true; // 대기도 행동
theAudio = GetComponent<AudioSource>();
nav = GetComponent<NavMeshAgent>();
}
protected void Update()
{
if (!isDead)
{
Move();
ElapseTime();
}
}
protected void Move()
{
if (isWalking || isRunning)
nav.SetDestination(transform.position + destination * 5f);
//rigid.MovePosition(transform.position + transform.forward * applySpeed * Time.deltaTime);
}
protected virtual void ReSet() // 다음 행동 준비
{
isAction = true;
nav.ResetPath();
isWalking = false;
anim.SetBool("Walking", isWalking);
isRunning = false;
anim.SetBool("Running", isRunning);
nav.speed = walkSpeed;
destination.Set(Random.Range(-0.2f, 0.2f), 0f, Random.Range(0.5f, 1f));
}
protected void TryWalk() // 걷기
{
currentTime = walkTime;
isWalking = true;
anim.SetBool("Walking", isWalking);
nav.speed = walkSpeed;
Debug.Log("걷기");
}
}
Rigidbody 보다 Nav Mesh Agent 가 우선시 되기 때문에, Nav Mesh Agent 컴포넌트가 붙게 되면 더 이상 rigid.MovePosition, rigid.MoveRotation 함수로 이동, 회전 할 수 없게 된다. ⭐이 Rigidbody 함수들이 freeze 되어 먹히지 않는다.⭐ 따라서 돼지를 Nav Mesh Agent 전용 이동 함수를 사용하여 이동시켜야 한다. 👉 SetDestination(Vector3)
- nav.SetDestination(Vector3)
- 인수로 들어간 Vector3 를 목적지로 하여 그 위치로
Nav Mesh Agent
(돼지)가 이동하게 한다.- 해당 목적지로 이동하기 위해 새로운 Path 경로를 최단경로로 찾아 설정한다.
- 이 함수를 사용하면 회전도 자동으로 이루어진다. 목적지를 바라보도록 자연스럽게 회전도 같이 이루어짐.
- 따라서 Rotation() 함수는 이제 지워주었다.
- 해당 목적지로 갈 수 있는 최단 경로로 이동한다.
- Bake 한 지형들을 바탕으로 해당 목적지까지의 최단 경로를 계산 함.
- 이동 속도 값은
Nav Mesh Agent
컴포넌트에 속성으로 있는 최대 이동 속도Speed
, 회전 속도Angular Speed
값을 속도로 하여 목적지로 알아서 이동한다.
- 인수로 들어간 Vector3 를 목적지로 하여 그 위치로
- nav.ResetPath()
- SetDestination(Vector3) 함수로 인하여 현재 설정되어 있던 경로를 지운다.
- 이에 따라, 현재 이동중이었다면 이동을 멈추게 된다.
- 해당
Nav Mesh Agent
는 새로운 SetDestination(Vector3) 호출이 있을 때까지 경로를 찾지 않는다. 이동도 하지 않는다.
- SetDestination(Vector3) 함수로 인하여 현재 설정되어 있던 경로를 지운다.
Nav Mesh Agent
는 Bake 된 지형을 기반으로, 이동시 최단 거리를 찾아 이동하게 한다. 목적지만 SetDestination 함수에게 알려주면, 알아서 그 목적지로 회전하고 이동한다. 그것도 최단 경로로! 이동 회전 ‘속도’값은 컴포넌트에서 설정할 수 있다.
- Start
nac
에 Nav Mesh Agent 컴포넌트 로딩
- Update
- Rotate 함수는 삭제하였다. 더 이상 사용하지 않음.
Nav Mesh Agent
의 SetDestination 함수로 해당 목적지로 이동시킬 때 회전도 자동으로 같이 하기 때문이다.
- Rotate 함수는 삭제하였다. 더 이상 사용하지 않음.
- Move
- 이제 rigid.MovePosition 가 아닌 nav.SetDestination을 사용한다.
Nav Mesh Agent
가 인수에 해당하는 해당 목적지로 최단 경로로, 컴포넌트에서 설정되있는 속도 값으로, 알아서 회전하고 알아서 이동한다. 목적지를 향하여.- 목적지 👉 돼지의 위치에서
destination * 5f
만큼 떨어진 곳destination
값은- 그냥 TryWalk 상태일 경우
- 랜덤한
x
,z
위치를 가진 벡터
- 랜덤한
- Run 상태일 경우 (플레이어로부터 도망갈 때)
- (플레이어👉돼지) 방향 벡터로 설정 in 📜WeakAnimal.cs
- 그냥 TryWalk 상태일 경우
- 목적지 👉 돼지의 위치에서
- Reset
- 현재
Nav Mesh Agent
가 목적지로 가기 위해 이동중이었을 경우를 대비하여 nav.ResetPath() 더 이상 이동하지 않도록 리셋. - TryWalk 상태를 대비하여 이제 랜덤한 방향으로 걸어야 하므로
destination
을 새롭게 설정한다.- 랜덤한
x
,z
위치를 가진 벡터
- 랜덤한
- 현재
- TryWalk()
Nav Mesh Agent
의 이동 속도를walkTime
으로- nav.speed = walkSpeed
📜WeakAnimal.cs
public class WeakAnimal : Animal
{
public void Run(Vector3 _targetPos)
{
destination = new Vector3(transform.position.x - _targetPos.x, 0f, transform.position.z - _targetPos.z).normalized;
currentTime = runTime;
isWalking = false;
isRunning = true;
nav.speed = runSpeed;
anim.SetBool("Running", isRunning);
}
}
destination = new Vector3(transform.position.x - _targetPos.x, 0f, transform.position.z - _targetPos.z).normalized;
nav.speed = runSpeed;
- 도망가는건 약한 동물들 뿐
- 도망갈 떄 목적지
- (플레이어👉돼지) 플레이어가 돼지를 향하는 방향으로 도망가야 한다.
normalized
를 1 로 하여 크기를 1 로 하였고 추후 Move 에서 목적지에 5 를 곱하니, 거리 5 로 도망가게 될 것이다.
- 도망갈 때 이동 속도는
- nav.speed = runSpeed
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기