유니티 몬스터 AI - yuniti monseuteo AI

오늘은 몬스터 ai 를 구현해보려한다.

 IEnumerator Roaming()
    {
        

        pos = new Vector3(); //목적지 생성
        pos.x = Random.Range(-3f, 3f); //목적지 x 값은 -3~3 사이 랜덤값
        pos.z = Random.Range(-3f, 3f); // 목적지 z 값은 -3~3 사이 랜덤값
       

        myanim.SetBool("IsWalking", true); // 처음에 움직이니까 트루 
        while (true) 
        {
           
            var dir = (pos - this.transform.position).normalized; // pos 포지션 - 몬스터포지션 normalized 한후 
            this.transform.LookAt(pos); // 몬스터가 이동할때 이동하는곳 바라보게하기위해 
            this.transform.position += dir * speed * Time.deltaTime; // 현재포지션에 normalize * 설정한 speed * Time.deltaTime 더해주기 

            float distance = Vector3.Distance(transform.position, pos); // 몬스터와 목적지 사이 거리 구하기 
            if (distance <=0.1f) // 0.1 이하라면 
            {
                myanim.SetBool("IsWalking", false); // 걷는 모션 false 후 Idle 들어갈예정 
                yield return new WaitForSeconds(Random.Range(1f, 3f)); // 랜덤으로 1~3 초기다린후 
                myanim.SetBool("IsWalking", true); // 다시 걷게하고 
                pos.x = Random.Range(-3f, 3f);// 위치설정
                pos.z = Random.Range(-3f, 3f);//위치설정 
               

            }
            
            yield return null;  
        }

       
       
    

    }

코드를 작성해준후 

  void ChangeState(State s) // State 변경 
    {

        if (myState == s) return; // 지금 내 state 가 입력받은 state 와 같다면 return 
        myState = s; // 아니라면 내 state 에 입력받은 s 대입 

        switch(myState)
        {
            case State.CREATE:
                break;
            case State.IDLE:
                ChangeState(State.ROAMING);
                break;
            case State.ROAMING:
                StartCoroutine(Roaming());
                break;
            case State.BATTLE:
                break;
            case State.DIE: // die 상태로돌입하면 
               
                myanim.SetTrigger("Dead"); // Dead 트리거 작동으로 Dead 애니메이션 나오고 
                StartCoroutine(Disapearing()); // Disapearing 코루틴 시작
                CharacterManger characterManger = GameObject.Find("Archer").GetComponent<CharacterManger>();
                characterManger.fixTarget = false;// 만약 맞았는데 현재 hp 가 0보다작거나 같다면 타겟 세팅을 위해 스타트 코루틴 켜줄 bool 조정 
                break;

        }
        
    }

ChangeState 에서 로밍 상태일때 start 코루틴 해준다 .

유니티 몬스터 AI - yuniti monseuteo AI

이런식으로 몬스터가 돌아다니게된다 .

이제 몬스터가 피격시 피격대상을 타겟으로 설정하고 달려오게 만들려고한다 .

그 부분을 구현하다가 저녁약속이 생겨서 오늘은 여기까지만 구현하고 내일 아침일찍부터 구현하려한다. 

유니티 몬스터 AI - yuniti monseuteo AI

기본 몬스터로 사용할 오브젝트를 생성합니다.

유니티 몬스터 AI - yuniti monseuteo AI

리지드바디와 박스콜라이더, 에너미 스크립트를 추가합니다.

        mat = GetComponentInChildren<SkinnedMeshRenderer>().material;

매쉬랜더러가 오브젝트의 하위 오브젝트에 스킨매쉬랜더러로 있기 때문에 Enemy 스크립트에서 수정해줍니다.

유니티 몬스터 AI - yuniti monseuteo AI

몬스터 오브젝트의 태그와 레이어를 Enemy로 수정하고 Nav Mesh Agent 컴포넌트를 추가합니다.

    public Transform target; //추적할 대상의 좌표
    NavMeshAgent nav;
    void Awake()
    {
        nav = GetComponent<NavMeshAgent>();
    }
    void Update()
    {
        nav.SetDestination(target.position);//도착할 목표 위치 지정 함수
    }

Enemy스크립트에 using UnityEngine.AI;를 선언한 뒤 스크립트를 추가해줍니다.

유니티 몬스터 AI - yuniti monseuteo AI

타깃에 플레이어를 드래그&드롭합니다.

유니티 몬스터 AI - yuniti monseuteo AI

추적을 위한 네비매쉬를 생성합니다.

유니티 몬스터 AI - yuniti monseuteo AI

몬스터가 플레이어를 추적하여 다가옵니다.

오류는 기존 피격 테스터에서 생기는 오류입니다.

이제 필요 없으니 지워줍니다.

    void FreezeVelocity()
    {
        rigid.velocity = Vector3.zero;
        rigid.angularVelocity = Vector3.zero;
    }
    void FixedUpdate()
    {
        FreezeVelocity();
    }

물리력이 NavAgent 이동을 방해하지 않도록 로직을 추가합니다.

유니티 몬스터 AI - yuniti monseuteo AI

애니메이션을 세팅해줍니다.

유니티 몬스터 AI - yuniti monseuteo AI

파라메터와 트랜지션을 세팅하여 애니메이터를 완성합니다.

유니티 몬스터 AI - yuniti monseuteo AI
유니티 몬스터 AI - yuniti monseuteo AI

실행해보면 이동과 사망 애니메이션, 추적 모두 정상적으로 이루어집니다.