[ Enemy FSM ] Enemy Attacking

devKyoun·2024년 10월 21일
0

Unity

목록 보기
15/27

소개

이제 Enemy Attacking State를 만드려고 한다!
이번 State는 비교적 간단하다 애니메이터 트랜지션을 잘 이용하면!

Animator

Goblin FSM의 흐름이 Walk는 Roaming(플레이어 발견 전)을 하고 발견 시에는 Run이 가동 된다.
즉 Attacking 상태가 되려면 그전에 무조건 Run이 존재한다
그래서 Run에서 부터 Battle Idle이 가동 되도록 했다

attack1을 하고나서 Exit Time 체크 해제를 해주지 않는다 그래야만 바로 attack2로 안넘어가고 Attack Delay가 생기기 때문


EnemyAttackingState.cs

EnemyTrackingState( 즉, 플레이어 발견 시 뛰어 오고 있는 상태 )에서 전환이 되는데

if (enemyManager.EnemyNavAgent.remainingDistance < enemyManager.NoneTrackingDistance)
{
    setPath = true;
    enemyManager.EnemyNavAgent.isStopped = false;


    if(Vector3.Distance(enemyManager.transform.position, enemyManager.PlayerTransform.position) <= enemyManager.AttackRange)
    {
        enemyAI.ChangeState(EnemyState.Attacking);
        return;
    }


}

공격 가능한 범위에 들어오면 바로 전환 해준다

public class EnemyAttackingState : BaseState
{
    private EnemyAI enemyAI;
    private EnemyManager enemyManager;

    private float attackCounter;
    public EnemyAttackingState(EnemyAI _enemyAI, EnemyManager _enemyManager)
    {
        enemyAI = _enemyAI;
        enemyManager = _enemyManager;
    }

    public override void StateEnter()
    {
        enemyManager.Animator.SetBool(enemyManager.AnimIDIsAttacking, true);
    }

    public override void StateExit()
    {
        enemyManager.Animator.SetBool(enemyManager.AnimIDIsAttacking, false);
        enemyManager.Animator.ResetTrigger(enemyManager.AnimIDAttack);
        attackCounter = 0;
    }

    public override void StateUpdate()
    {
        attackCounter += Time.deltaTime;

        if (Vector3.Distance(enemyManager.transform.position, enemyManager.PlayerTransform.position) > enemyManager.AttackRange)
        {
            if(attackCounter > enemyManager.AttackToTrackingDelay)
                enemyAI.ChangeState(EnemyState.Tracking);
            return;
        }
        
        if(attackCounter > enemyManager.AttackDelay)
        {
            Debug.Log("Attack");
            enemyManager.Animator.SetTrigger(enemyManager.AnimIDAttack);
            attackCounter = 0;
        }

        
    }
}

Enter시에 IsAttacking 을 True로 해줘서 Battle Idle 상태로 해준다
Exit 할때는 ResetTrigger 까먹으면 안됨! ( 버그 방지 )

stateUpdate에서 AttackRange를 벗어났을때 공격 도중이면은 일정 시간 뒤에 전환 하도록 바꿔줬다.

해당 attackCounter 조건문이 없으면은 공격하다말고 바로 전환이 돼서 게임 플레이 난이도가 너무 상승해버리고 게임성이 떨어지기 때문

if(attackCounter > enemyManager.AttackDelay)
{
    Debug.Log("Attack");
    enemyManager.Animator.SetTrigger(enemyManager.AnimIDAttack);
    attackCounter = 0;
}

그리고 이 부분은 사실 애니메이터 트랜지션을 이용해서 SetTrigger만 해놔도 되는 상황인데 차후에 애니메이터가 변경 되거나 디테일한 공격을 구사했을때를 위해 구현해놨다

profile
Game Developer

0개의 댓글