반응형

몬스터인 적이 플레이어를 공격하고 추적하는 스크립트를 만들겠습니다

 

먼저 EnemyFSM 스크립트를 만들고 Enemy 오브젝트에 붙힘니다.

 

그리고 EnemyFSM 스크립트 작성

 

 

 

 

 

 

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

public class EnemyFSM : MonoBehaviour
{
    public enum State
    {
        Idle,  //정지
        Chase,  //추적
        Attack,  //공격
        Dead,   //사망
        NoState  //아무 일도 없는 상태
    }

    public State currentState = State.Idle;

    EnemyAni myAni;

    Transform player;

    float chaseDistance = 5f; // 플레이어를 향해 몬스터가 추적을 시작할 거리
    float attackDistance = 2.5f; // 플레이어가 안쪽으로 들오오게 되면 공격을 시작
    float reChaseDistance = 3f; // 플레이어가 도망 갈 경우 얼마나 떨어져야 다시 추적

    float rotAnglePerSecond = 360f; // 초당 회전 각도
    float moveSpeed = 1.3f; // 몬스터의 이동 속도

    float attackDelay = 2f;
    float attackTimer = 0f;

    void Start()
    {
        myAni = GetComponent<EnemyAni>();
        ChangeState(State.Idle, EnemyAni.IDLE);

        player = GameObject.FindGameObjectWithTag("Player").transform;
    }

    void UpdateState()
    {
        switch (currentState)
        {
            case State.Idle:
                IdleState();
                break;
            case State.Chase:
                ChaseState();
                break;
            case State.Attack:
                AttackState();
                break;
            case State.Dead:
                DeadState();
                break;
            case State.NoState:
                NoState();
                break;          
        }
    }

    public void ChangeState(State newState, string aniName)
    {
        if (currentState == newState)
        {
            return;
        }

        currentState = newState;
        myAni.ChangeAni(aniName);
    }
    void IdleState()
    {
        if (GetDistanceFromPlayer() < chaseDistance)
        {
            ChangeState(State.Chase, EnemyAni.WALK);
        }
    }

    void ChaseState()
    {
        //몬스터가 공격 가능 거리 안으로 들어가면 공격 상태
        if (GetDistanceFromPlayer() < attackDistance)
        {
            ChangeState(State.Attack, EnemyAni.ATTACK);
        }
        else
        {
            TurnToDestination();
            MoveToDestination();
        }   
    }

    void AttackState()
    {
        if (GetDistanceFromPlayer() > reChaseDistance)
        {
            attackTimer = 0f;
            ChangeState(State.Chase, EnemyAni.WALK);
        }
        else
        {
            if (attackTimer > attackDelay)
            {
                transform.LookAt(player.position);
                myAni.ChangeAni(EnemyAni.ATTACK);

                attackTimer = 0f;
            }

            attackTimer += Time.deltaTime;
        }
    }

    void DeadState()
    {

    }

    void NoState()
    {

    }

    void TurnToDestination()
    {
        Quaternion lookRotation = Quaternion.LookRotation(player.position - transform.position);

        transform.rotation = Quaternion.RotateTowards(transform.rotation, lookRotation, Time.deltaTime * rotAnglePerSecond);
    }

    void MoveToDestination()
    {
        transform.position = Vector3.MoveTowards(transform.position, player.position, moveSpeed * Time.deltaTime);
    }


    //플레이어와 거리을 재는 함수
    float GetDistanceFromPlayer()
    {
        float distance = Vector3.Distance(transform.position, player.position);
        return distance;
    }

    // Update is called once per frame
    void Update()
    {
        UpdateState();
    }
}

 

 

 

 

 

그리고 EnemyAni 스크립트를 만들고 Enemy 오브젝트에 붙힘니다

EnemyAni 스크립트 작성

 

 

 

 

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

public class EnemyAni : MonoBehaviour
{
    public const string IDLE = "idle";
    public const string WALK = "walk";
    public const string ATTACK = "attack1";
    public const string DIE = "death1";

    Animation anim;
    // Start is called before the first frame update
    void Start()
    {
        anim = GetComponentInChildren<Animation>();
    }

    public void ChangeAni(string aniName)
    {
        anim.CrossFade(aniName);
    }
    // Update is called once per frame
    void Update()
    {
        
    }
}

 

 

 

 

게임을 실행시켜서 player가 적에게 다가갔을때 적이 공격하고 Player가 달아 났을 때 적이 추적하는지 확인 합니다

https://youtu.be/w1RNqHVehIc

 

반응형

+ Recent posts