Chapter 7-1. AI : 동물 AI
카테고리: Unity Lesson 3
태그: Unity Game Engine
인프런에 있는 케이디님의 [유니티 3D] 실전! 생존게임 만들기 - Advanced 강의를 듣고 정리한 필기입니다. 😀
🌜 강의 들으러 가기 Click
Chapter 7. 동물들의 공격형 AI, 도망형 AI 구현
🚖 돼지 3D 모델 설정
돼지 입장에서 보는 방향이 돼지 기준에서 앞 방향이어야 해서 z
축이 돼지를 향해 있어야 하는데, 돼지 3 D 모델 pig
오브젝트는 z
축이 돼지의 왼쪽에 있었다. 따라서 pig
오브젝트를 y 축으로 -90 도 회전시켜 주어 z
축이 돼지가 바라보는 방향과 일치하게 해주었다. 돼지가 바라보는 방향이 돼지 기준의 앞 방향이어야 하므로.
돼지 3 D 모델 pig
오브젝트는 y 축으로 90도 회전되었으므로 나중에 회전 값에 연산을 하게 되면 이에 맞춰서 연산해야 하는 불편함이 따르게 된다. 따라서 부모 오브젝트로 원점 회전값(0, 0, 0)을 가진 Pig
빈 오브젝트를 만들었다. 실질적으로 돼지의 Mesh 를 가진 pig
오브젝트의 트랜스폼을 부모인 Pig
에서 관리하도록. 원점 회전값(0, 0, 0)을 가진 이 부모 Pig
오브젝트로 돼지의 이동, 회전 같은 트랜스폼을 대신 담당할 것이다.
컴포넌트 설정
Pig
👉 빈 오브젝트. 돼지의 트랜스폼, Collider 등을 대신 담당하게 될 것.- Box Collider - 돼지가 땅을 뚫고 떨어진다던지 관통된다던지 하지 않게 하기 위해
- Rigidbody - 중력과 여러 물리적 영향을 바덱 하기 위해
- 물리 현상에 의한 x, y, z 축 회전은 하지 않도록 Constraints 모두 체크해주었다.
pig
👉 실질적인 돼지 모습을 그리는 돼지 3 D 모델 오브젝트.- Animator - 돼지 애니메이션 담당
- 돼지의 애니메이션은 돼지 Mesh 에서 이루어 지므로 이
pig
3 D 모델에 붙어야 한다.
- 돼지의 애니메이션은 돼지 Mesh 에서 이루어 지므로 이
- Animator - 돼지 애니메이션 담당
돼지 애니메이션
돼지 3 D 모델에 내장되어 있던 애니메이션을 프레임 구간으로 잘라내어 애니메이션 State 들을 만듬
- 파라미터로 인한 전이는 Has Exit Time 해제
- Trigger 로 인해 시작됐던 State 가 끝나고 일어나는 전이는 Has Exit Time 체크
🚖 돼지 AI
📜Pig.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Pig : MonoBehaviour
{
[SerializeField] private string animalName; // 동물의 이름
[SerializeField] private int hp; // 동물의 체력
[SerializeField] private float walkSpeed; // 걷기 속력
private Vector3 direction; // 방향
// 상태 변수
private bool isAction; // 행동 중인지 아닌지 판별
private bool isWalking; // 걷는지, 안 걷는지 판별
[SerializeField] private float walkTime; // 걷기 시간
[SerializeField] private float waitTime; // 대기 시간
private float currentTime;
// 필요한 컴포넌트
[SerializeField] private Animator anim;
[SerializeField] private Rigidbody rigidl;
[SerializeField] private BoxCollider boxCol;
void Start()
{
currentTime = waitTime; // 대기 시작
isAction = true; // 대기도 행동
}
void Update()
{
Move();
Rotation();
ElapseTime();
}
private void Move()
{
if (isWalking)
rigidl.MovePosition(transform.position + transform.forward * walkSpeed * Time.deltaTime);
}
private void Rotation()
{
if (isWalking)
{
Vector3 _rotation = Vector3.Lerp(transform.eulerAngles, direction, 0.01f);
rigidl.MoveRotation(Quaternion.Euler(_rotation));
}
}
private void ElapseTime()
{
if (isAction)
{
currentTime -= Time.deltaTime;
if (currentTime <= 0) // 랜덤하게 다음 행동을 개시
ReSet();
}
}
private void ReSet() // 다음 행동 준비
{
isWalking = false;
isAction = true;
anim.SetBool("Walking", isWalking);
direction.Set(0f, Random.Range(0f, 360f), 0f);
RandomAction();
}
private void RandomAction()
{
int _random = Random.Range(0, 4); // 대기, 풀뜯기, 두리번, 걷기
if (_random == 0)
Wait();
else if (_random == 1)
Eat();
else if (_random == 2)
Peek();
else if (_random == 3)
TryWalk();
}
private void Wait() // 대기
{
currentTime = waitTime;
Debug.Log("대기");
}
private void Eat() // 풀 뜯기
{
currentTime = waitTime;
anim.SetTrigger("Eat");
Debug.Log("풀 뜯기");
}
private void Peek() // 두리번
{
currentTime = waitTime;
anim.SetTrigger("Peek");
Debug.Log("두리번");
}
private void TryWalk() // 걷기
{
currentTime = walkTime;
isWalking = true;
anim.SetBool("Walking", isWalking);
Debug.Log("걷기");
}
}
돼지는 4 가지 행동(대기, 풀뜯기, 두리번, 걷기)을 랜덤하게 한다. 걷기는
walkTime
동안 실행되며, 그 외의 대기, 풀뜯기, 두리번은waitTime
동안 행동이 실행 된다. 행동이 끝나면 다른 행동을 결정하고 실행한다.
- 4 가지 상태 개시
- Wait() 👉 대기
waitTime
동안 실행되므로currentTime
을waitTime
로 초기화- 디폴트 상태인 Idle 애니메이션 재생 됨
- Eat() 👉 풀 뜯기
waitTime
동안 실행되므로currentTime
을waitTime
로 초기화- 먹기 애니메이션 재생
- Peek() 👉 두리번
waitTime
동안 실행되므로currentTime
을waitTime
로 초기화- 두리번 거리는 애니메이션 재생
- TryWalk() 👉 걷기
walkTime
동안 실행되므로currentTime
을walkTime
로 초기화- 걷는 애니메이션 재생
- Wait() 👉 대기
- 돼지가 4 가지 행동 중 하나를 현재 행동하는 중이라면
isAction
는 True다. - ElapseTime() 👉 행동 시간 카운트 다운
- 돼지가 4 가지 행동 중 하나를 현재 행동하는 중이라면 매 프레임마다
currentTime
을 1 초에 1 씩 감소시킨다. 이 시간 동안 행동을 한다.- 1 프레임당
Time.deltaTime
감소
- 1 프레임당
currentTime
가 0 에 도달했다면 다음 행동을 결정하고 실행해야 한다- ReSet()
- 돼지가 4 가지 행동 중 하나를 현재 행동하는 중이라면 매 프레임마다
- ReSet() 👉 다음 행동 준비
- 초기화
- 정지 애니메이션으로 돌아감
isAction
True
- 랜덤하게 방향 설정
direction
은 돼지가 향할 방향이다. y 축 360 도 회전값에서 랜덤하게 선택한다.
- 랜덤하게 다음 행동 설정
- RandomAction()
- 초기화
- RandomAction() 👉 랜덤하게 다음 행동 결정
- 0 ~ 3 중 랜덤하게 뽑아서 4 가지 행동 개시
- 돼지가 걷기 상태라면
- 매 프레임마다 돼지 이동시킴
- 현재 위치로부터 돼지를 기준으로 한 앞 방향으로 1 초에
walkSpeed
크기 속도로.
- 현재 위치로부터 돼지를 기준으로 한 앞 방향으로 1 초에
- 매 프레임마다 돼지 부드럽게 회전시킴
- ReSet() 에서 설정했던
direction
방향으로 돼지를 회전 시킨다. - 현재 회전 값에서
direction
로 회전할 때까지 부드럽게 Lerp
- ReSet() 에서 설정했던
- 매 프레임마다 돼지 이동시킴
- 돼지는 5 초동안 걷고 난 후 다음 행동을 한다.
- 돼지는 4 초동안 대기, 풀뜯기, 두리번 행동을 하고 난 후 다음 행동을 한다.
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기