2 분 소요

공격받으면 Player를 쫓아가기

void OnMouseDown()
    {
        Debug.Log("hit");
        GameObject player = GameObject.FindGameObjectWithTag("Player");
        _isBattle= true;
        ChangedAction(eActionState.RUN);
        _navAgent.destination = player.transform.position;
    }

                _navAgent.stoppingDistance = 0;
                _navAgent.stoppingDistance = 4;  //run일떄는 4만큼떨어지기

            case eActionState.RUN:
                if (Vector3.Distance(_navAgent.destination, transform.position) <= 0.1f)
                {
                    _isBattle= false;           //Player에게 가서 도착하면 다시 제자리로
                    _isSelectAi = false;
                }
                break; 

플레이어에게 다가가서 공격하기

            case eActionState.RUN:
                if (Vector3.Distance(_posTarget, transform.position) <= 3.1f)
                {
                    ChangedAction(eActionState.ATTACK);
                }
                else
                {
                    ChangedAction(eActionState.RUN);
                }
                break;
            case eActionState.ATTACK:
                    //_isBattle = false;
                    //_isSelectAi = false;
                break;


void OnMouseDown()
    {
        Debug.Log("hit");
        GameObject player = GameObject.FindGameObjectWithTag("Player");
        ChangedAction(eActionState.RUN);
        _isBattle= true;
        _posTarget= player.transform.position;
        _navAgent.destination = _posTarget;
    }

최종

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


public class ZombieController : MonoBehaviour
{
    public enum eActionState
    {
        IDLE              =0,
        WALK,
        RUN,
        ATTACK,
        HIT,
    }

    public enum eCharacter
    {
        Fierce = 0,
        lazy
    }

    [SerializeField] float _limitX = 5;
    [SerializeField] float _limitZ = 5;
    [SerializeField] float _moveSpeed;   //뛰는 스피드
    [SerializeField] float _walkSpeed;  //걷는 스피드
    [SerializeField] BoxCollider _damageZone;
    
    public eCharacter _eCh;
    public float _minTime = 2;
    public float _maxTime = 7;

    eActionState _stateAction;
    Animator _ctrlAni;
    Vector3 _posTarget;
    float _Speed;       //최종 스피드
    bool _isDeath;   //플래그 (키고 끄고 할수있는 작용 
    bool _isAttack;
    NavMeshAgent _navAgent;
    Vector3 _startPos;          //cube상에서의 중심 위치 = center
    float _timeWait;
    bool _isSelectAi;
    int _characterStd;
    bool _isBattle;

    private void Awake()
    {
        _isDeath = false;   //초기화
        _isAttack = false;  //초기화
        _ctrlAni = GetComponent<Animator>();
        _navAgent = GetComponent<NavMeshAgent>();   // 좀비에 있는 navmeshagent를 가져옴
        _startPos = _posTarget = transform.position;
        _timeWait = 0;
        _isSelectAi = false;
        _characterStd= 0;
        _isBattle = false;
    }
    void Start()
    {
        switch (_eCh)
        {
            case eCharacter.Fierce:
                _characterStd = 25;
                break;
            case eCharacter.lazy:
                _characterStd = 80;
                break;
        }

    }

    private void Update()
    {
        if (_isDeath)
            return;



        switch (_stateAction)
        {
            case eActionState.IDLE:
                _timeWait -= Time.deltaTime;    //시간이 깎여나가야함
                if(_timeWait< 0) //기다리는 시간이 다 지나면
                {
                    //다시 선택
                    _isSelectAi = false;

                }
                break;
            case eActionState.WALK:
                if (Vector3.Distance(_posTarget, transform.position) <= 0.1f)
                {
                    //다시선택
                    _isSelectAi = false;
                }
                break;
            case eActionState.RUN:
                if (Vector3.Distance(_posTarget, transform.position) <= 3.1f)
                {
                    ChangedAction(eActionState.ATTACK);
                }
                else
                {
                    ChangedAction(eActionState.RUN);
                }
                break;
            case eActionState.ATTACK:
                    //_isBattle = false;
                    //_isSelectAi = false;
                break;

        }

        ProceesAI();
    }

    void ProceesAI()
    {
        if (!_isSelectAi&&!_isBattle)
        {
            int r = Random.Range(0, 100);      //(이상,미만: 0, 1만 나옴)

            if (r <_characterStd)
            {   //IDLE
                ChangedAction(eActionState.IDLE);
                _timeWait = Random.Range(_minTime, _maxTime);

            }
            else if(r>_characterStd)
            {   //WALK
                ChangedAction(eActionState.WALK);
                _posTarget = GetRandomPos(_startPos, _limitX, _limitZ);
                _navAgent.destination = _posTarget;
            }

            _isSelectAi = true;
        }
        
    }

    Vector3 GetRandomPos(Vector3 center, float limitX, float limitZ)            //좀비가 움직일 임의의 위치를 반환
    {
         float rX = Random.Range(-limitX, limitX);              //센터를 중심으로 -5, +5 사이에서 x좌표 랜덤값 (이상,이하)
         float rZ = Random.Range(-limitZ, limitZ);              //센터를 중심으로 -5, +5 사이에서 z좌표 랜덤값

        Vector3 rv = new Vector3(rX,0,rZ);
        return center+ rv;      //center가 있어야 cube에서의 중심점에서 x,z에 따라 움직임
    }

    void ChangedAction(eActionState state)
    {

        switch (state)                                  //애니메이션이 바뀌는 곳에서 속도를 변경 해주는게 직관적임
        {
            case eActionState.WALK:         //walk일때 최종스피드에다가 워크스피드를 넣어줌
                if (_stateAction != eActionState.ATTACK)
                {
                    _navAgent.speed = _walkSpeed;
                    _navAgent.stoppingDistance = 0;
                    _ctrlAni.SetInteger("AniState", (int)_stateAction);
                    _stateAction = state;
                }
                break;
            case eActionState.RUN:
                _navAgent.speed = _moveSpeed;
                _ctrlAni.SetInteger("AniState", (int)_stateAction);
                _stateAction = state;
                _navAgent.stoppingDistance = 3;
                break;
            case eActionState.ATTACK:       //모든것이 변하는 곳에 공격할때는 isAttack을 킴
                if (_stateAction == eActionState.RUN)
                {
                    _isAttack = true;
                    _ctrlAni.SetInteger("AniState", (int)_stateAction);
                    _stateAction = state;

                }
                break;
            case eActionState.HIT:      //맞으면 isDeath를 킴
                _isDeath = true;
                _ctrlAni.SetInteger("AniState", (int)_stateAction);
                _stateAction = state;
                break;
            case eActionState.IDLE:
                _ctrlAni.SetInteger("AniState", (int)_stateAction);
                _stateAction = state;
                break;

        }

        _stateAction = state;
        _ctrlAni.SetInteger("AniState", (int)_stateAction);
    }

    void DamageOn()
    {
        _damageZone.enabled = true;
    }

    void DamageOff()
    {
        _damageZone.enabled = false;
    }

    void OnMouseDown()
    {
        Debug.Log("hit");
        GameObject player = GameObject.FindGameObjectWithTag("Player");
        ChangedAction(eActionState.RUN);
        _isBattle= true;
        _posTarget= player.transform.position;
        _navAgent.destination = _posTarget;
    }
}

댓글남기기