스토리지

[4.15] 2 - 캐릭터 자동인식 및 추적 본문

Unity/유니티 기본

[4.15] 2 - 캐릭터 자동인식 및 추적

ljw4104 2021. 4. 15. 17:56

몬스터에 닿인 시점부터 1초에 체력이 10씩 떨어진다.

  1. 몬스터가 해당범위내에 들어온 플레이어를 인식
  2. 플레이어 정보 저장 및 좌표로 추척시작 (NavMeshAgent 컴포넌트를 사용)
  3. 일정 범위내에 도달했을시에 추적종료

#몬스터의 인식범위

몬스터의 인식범위를 알 수 있다. / Nav Mesh Agent Component

 

 

Enemy.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class Enemy : Entity
{
    private bool isMeetPlayer;
    private bool foundPlayer;
    private int damage;
    private float radius = 16;
    private NavMeshAgent nav;
    private PlayerController player;
    private Animator animator;
    // Start is called before the first frame update
    void Start()
    {
        this.damage = 10;
        this.nav = GetComponent<NavMeshAgent>();
        this.animator = GetComponent<Animator>();
        this.player = null;

        StartCoroutine(this.DectedTarget());
    }

    // Update is called once per frame
    private void Update()
    {
        //캐릭터의 좌표는 몬스터가 추적중인 와중에도 계속 변경될 수 있기때문에 계속 추적하여야 한다.
        if (player != null && !this.isDead)
        {
            this.nav.SetDestination(this.player.transform.position);
            //일정 범위내에 들어왔을시에 추적종료
            if (Vector3.Distance(player.transform.position, this.transform.position) < 0.7f)
            {
                this.nav.isStopped = true;
                this.animator.SetBool("Move", false);
            }
            else
            {
                this.nav.isStopped = false;
                this.animator.SetBool("Move", true);
            }
        }

        Debug.Log(this.isMeetPlayer);
    }

    //플레이어를 찾는다.
    private IEnumerator DectedTarget()
    {
        while (!foundPlayer)
        {
            var colliders = Physics.OverlapSphere(this.transform.position, this.radius);
            for (int i = 0; i < colliders.Length; i++)
            {
                if (colliders[i].gameObject.CompareTag("Player"))
                {
                    this.player = colliders[i].gameObject.GetComponent<PlayerController>();
                    this.nav.isStopped = false;
                    this.nav.SetDestination(this.player.transform.position);
                    this.foundPlayer = !this.foundPlayer;
                    this.animator.SetBool("Move", true);
                    break;
                }
            }
            yield return new WaitForSeconds(1f);
        }
    }

    //Scene창에서만 볼수있는 몬스터의 인식범위를 나타낸다.
    private void OnDrawGizmos()
    {
        Gizmos.color = Color.yellow;
        Gizmos.DrawWireSphere(this.transform.position, this.radius);
    }

    //캐릭터가 몬스터와 겹치기 시작했을 때를 체크
    private void OnTriggerStay(Collider other)
    {
        if (other.CompareTag("Player") && !this.isMeetPlayer)
        {
            isMeetPlayer = true;
            StartCoroutine(this.AttackPlayer());
        }
    }

    //캐릭터가 몬스터를 벗어났을 때를 체크
    private void OnTriggerExit(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            isMeetPlayer = false;
        }
    }

    //캐릭터에게 데미지를 겹쳐있는동안 일정주기로 준다.
    private IEnumerator AttackPlayer()
    {
        while (!this.player.isDead && this.isMeetPlayer)
        {
            this.player.Damage(this.damage);
            yield return new WaitForSeconds(1f);
        }
    }
}

'Unity > 유니티 기본' 카테고리의 다른 글

[4.16] 씬 전환  (0) 2021.04.16
[4.16] Post-Processing  (0) 2021.04.16
[4.15] 1 - Cinemachine 설정  (0) 2021.04.15
[4.15] 엄청 자주하는 실수  (0) 2021.04.15
[4.15] Inverse Kinematics (IK) - 역운동학  (0) 2021.04.15
Comments