MonsterController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class MonsterController : MonoBehaviour
{
public enum eState
{
Idle, Trace, Attack, Die
}
[SerializeField]
private NavMeshAgent agent;
private Transform playerTrans;
[SerializeField]
private float attackRange = 2f; //공격사거리
[SerializeField]
private float traceRange = 10f; //추적사거리
[SerializeField]
private eState state; //상태 저장 변수
private bool IsDie = false;
private Animator anim;
private readonly int hashTrace = Animator.StringToHash("IsTrace");
private readonly int hashAttack = Animator.StringToHash("IsAttack");
private readonly int hashHit = Animator.StringToHash("Hit");
// Start is called before the first frame update
void Start()
{
//애니메이션 컴포넌트 가져오기
this.anim = this.GetComponent<Animator>();
//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.agent.destination = this.playerTrans.position;
this.StartCoroutine(this.CoCheckMonsterState());
this.StartCoroutine(this.CoMonsterAction());
}
private IEnumerator CoCheckMonsterState()
{
while(true)
{
yield return new WaitForSeconds(0.3f);
//플레이어와 거리계산
float dis = Vector3.Distance(this.transform.position, this.playerTrans.position);
if (dis <= attackRange)
{
//공격사거리에 들어왔는지
this.state = eState.Attack;
}
else if(dis <= this.traceRange)
{
//아니면 추적사거리에 들어왔는지
this.state = eState.Trace;
}
else
{
//공격사걸에도 추적사거리에도 안들어왔는지
this.state = eState.Idle;
}
}
}
private IEnumerator CoMonsterAction()
{
while (!this.IsDie)
{
yield return new WaitForSeconds(0.3f);
switch(this.state)
{
case eState.Idle:
//추적 중지
this.agent.isStopped = true;
this.anim.SetBool(hashTrace, false);
break;
case eState.Trace:
//플레이어 좌표로 이동
this.agent.SetDestination(this.playerTrans.position);
this.agent.isStopped = false;
this.anim.SetBool(hashTrace, true);
this.anim.SetBool(hashAttack, false);
break;
case eState.Attack:
this.anim.SetBool(hashAttack, true);
break;
case eState.Die:
break;
}
}
}
private void OnCollisionEnter(Collision collision)
{
if(collision.collider.CompareTag("Bullet"))
{
//충돌한 총알 삭제
Destroy(collision.gameObject);
//피격 리액션 애니메이션 실행
this.anim.SetTrigger(hashHit);
}
}
private void OnDrawGizmos()
{
if (this.state == eState.Trace)
{
Gizmos.color = Color.blue;
GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, this.attackRange);
}
else if(this.state == eState.Attack)
{
Gizmos.color = Color.red;
GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, this.traceRange);
}
}
}
'유니티 심화' 카테고리의 다른 글
절대강좌 유니티 - 혈흔효과, 몬스터 공격효과, 델리게이트, 죽으면 강남스타일, 본 구조, 충돌감지, 몬스터 사망 (0) | 2023.08.24 |
---|---|
HeroShooter - FadeIn, FloatingJoystick, 닭이미지, 텍스트, Ray (0) | 2023.08.23 |
절대강좌 유니티 - NavMeshSurface (0) | 2023.08.23 |
절대강좌 유니티 - MuzzleFlash (0) | 2023.08.22 |
HeroShooter - 튜토리얼 스테이지 (0) | 2023.08.22 |