728x90
MonsterController
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting.Antlr3.Runtime.Misc;
using UnityEngine;
using UnityEngine.AI;
public class MonsterController : MonoBehaviour
{
//상태 정의
public enum eState
{
IDLE,
TRACE,
ATTACK,
DIE
}
//몬스터의 현재 상태 저장하는 변수
public eState state;
//공격사거리 변수 정의
[SerializeField]
private float attackRange = 2.0f;
//추적사거리 변수 정의
[SerializeField]
private float traceRange = 10.0f;
//죽었는지 안 죽었는지 저장하는 변수
private bool isDie = false;
private NavMeshAgent agent;
private Transform playerTrans;
private Animator anim;
void Start()
{
//agent 컴포넌트 가져오기
this.agent = this.GetComponent<NavMeshAgent>();
//타겟의 위치
//GameObject playerGo = GameObject.FindWithTag("Player");
//Transform playerTrans = playerGo.GetComponent<Transform>();
//Vector3.playerPosition = playerTrans.position;
this.playerTrans = GameObject.FindWithTag("Player").GetComponent<Transform>();
//this.playerTrans = GameObject.FindWithTag("Player").transform;
//애니메이션 컴포넌트
this.anim = this.GetComponent<Animator>();
//플레이어 위치로 이동하기
this.agent.destination = this.playerTrans.position;
//코루틴 호출
//상태체크
this.StartCoroutine(CheckMonsterState());
//행동수행
this.StartCoroutine(MonsterAction());
}
IEnumerator CheckMonsterState()
{
while (true)
{
yield return new WaitForSeconds(0.3f);
//플레이어와 거리 계산
var dis = Vector3.Distance(this.transform.position, this.playerTrans.position);
//공격사거리에 들어왔는지
if(dis <= this.attackRange)
{
//상태변화
this.state = eState.ATTACK;
}
//아니면 추적사거리에 들어왔는지
else if(dis <= this.traceRange)
{
//상태변화
this.state = eState.TRACE;
}
//공격사거리, 추적사거리도 아니면
else
{
//상태변화
this.state = eState.IDLE;
}
}
}
//행동수행 메서드
IEnumerator MonsterAction()
{
//몬스터가 죽지 않았다면
while (this.isDie == false) //!this.isDie
{
switch (this.state)
{
case eState.IDLE:
//추적 중지
this.agent.isStopped = true;
//애니메이션 실행
this.anim.SetBool("Is Trace", false);
break;
case eState.ATTACK:
//추적 중지
this.agent.isStopped = true;
//애니메이션 실행
this.anim.SetBool("Is Attack", true);
break;
case eState.TRACE:
//플레이어 좌표로 이동
this.agent.SetDestination(this.playerTrans.position);
//추적 실행
this.agent.isStopped = false;
//애니메이션 실행
this.anim.SetBool("Is Trace", true);
this.anim.SetBool("Is Attack", false);
break;
case eState.DIE:
break;
}
yield return new WaitForSeconds(0.3f);
}
}
//몬스터의 상태에 따라 동작 수행
private void OnDrawGizmos()
{
//추적사거리 표시
if(state == eState.TRACE)
{
Gizmos.color = Color.blue;
GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, this.traceRange);
}
//공격사거리 표시
if(state == eState.ATTACK)
{
Gizmos.color = Color.red;
GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, this.attackRange);
}
}
}
원래 이렇게 쓰지만 MonsterAction 부분이 너무 길어짐
그래서 밑에 상태에 따라 따로 메서드들을 만들어주자~
//행동수행 메서드
IEnumerator MonsterAction()
{
//몬스터가 죽지 않았다면
while (this.isDie == false) //!this.isDie
{
switch (this.state)
{
case eState.IDLE:
this.Idle();
break;
case eState.ATTACK:
this.Attack();
break;
case eState.TRACE:
this.Trace();
break;
case eState.DIE:
break;
}
yield return new WaitForSeconds(0.3f);
}
}
//Idle 상태일때 메서드
void Idle()
{
//추적 중지
this.agent.isStopped = true;
//애니메이션 실행
this.anim.SetBool("Is Trace", false);
}
//Trace 상태일때 메서드
void Trace()
{
//플레이어 좌표로 이동
this.agent.SetDestination(this.playerTrans.position);
//추적 실행
this.agent.isStopped = false;
//애니메이션 실행
this.anim.SetBool("Is Trace", true);
this.anim.SetBool("Is Attack", false);
}
//Attack 상태일때 메서드
void Attack()
{
//추적 중지
this.agent.isStopped = true;
//애니메이션 실행
this.anim.SetBool("Is Attack", true);
}
이렇게!
'KDT > 유니티 심화' 카테고리의 다른 글
23/08/27 [주말과제] HeroShooter Stage1 미완 (0) | 2023.08.27 |
---|---|
23/08/24 HeroShooter 사정거리 안에 몬스터 감지 (0) | 2023.08.24 |
23/08/23 HeroShooter 포탈 닿으면 FadeOut (0) | 2023.08.23 |
23/08/22 HeroShooter 이동하기 (0) | 2023.08.22 |
23/08/21 Player 목표지점까지 이동 후 회전 (Lerp,Quaternion) (0) | 2023.08.21 |