게임 개발 공부/Unity

적 케릭터 닷지 회피 구현(Enemy Dodge System)

CalebHong 2022. 1. 20. 14:40

게임을 개발하던 중에 젤다의 전설 야생의 숨결에서

 

보코블린(적 케릭터)가 공격을 회피(닷지) 하는 것이 생각나서 구현해보았다.

 

 

[SerializeField]
private float dodgeChance = 0.3f; // 닷지 확률(0 ~ 1f 사이 값)
[SerializeField]
private float dodgeAngle = 30; // 반각 30도, 총 60도 각도
[SerializeField]
private float dodgeDistance = 5f; // 닷지할 포인트 거리
[SerializeField]
private float counterattackChance = 0.3f; // 닷지 후 반격 찬스

// 플레이어가 공격했을 때 Action을 작동
private void Awake()
{
	PlayerController.Instance.OnPlayerAttack -= DodgeAttack;
}

public void DodgeAttack()
{
    if (!isDodge)
    {
    	// 적의 상태가 공격중일 때
        if (enemyState == EnemyState.Attack && UnityEngine.Random.value < dodgeChance) 
        {
            // NavAgent를 사용하기 때문에 닷지 할 포인트에서 가까운 NavMesh를 파악 후 위치로 닷지
            if (NavMesh.SamplePosition(GetDodgePoint(dodgeAngle), out navHit, dodgeChance, NavMesh.AllAreas))
            {
                isDodge = true;
                navAgent.isStopped = true; // 닷지 중에 NavAgent의 이동과 회전을 멈춘다
                anim.SetTrigger(m_AnimPara_Dodge); // Animation 작동
                thisTransform.DOMove(navHit.position, 1f) // DOTween을 이용하여 닷지 포인트로 이동
                    .SetEase(Ease.OutCubic)
                    .OnComplete(() =>
                    {
                        // 닷지 후 반격
                        if (UnityEngine.Random.value < counterattackChance)
                        {
                            anim.SetTrigger(m_AnimPara_Counterattack);
                        }
                    });
            }
        }
    }
    else
    {
        isDodge = false;
        navAgent.Warp(thisTransform.position); // Transform만 옮겨졌기 때문에 NavAgent도 이동시켜준다.
        navAgent.isStopped = false; // NavAgent 재작동 시작
    }
}

// GET DODGE POINT
private Vector3 GetDodgePoint(float angle)
{
    float randomVal = UnityEngine.Random.Range(-1f, 1f); // 반원에서 방향을 랜덤 값으로 정함
    angle = randomVal * angle; // 0 ~ angle 사이의 각을 구함

    return thisTransform.position + (thisTransform.rotation * Quaternion.Euler(0, angle, 0)) * (Vector3.forward * -dodgeDistance);
}

private void OnDisable()
{
    PlayerController.Instance.OnPlayerAttack -= DodgeAttack;
}

 

개발을 2-3년 했지만 아직 요고 하나 만드는데 굉장히 힘들고 오래 걸렸다.. ㅠㅠ 

 

그러나 다 만들어서 작동하는 것을 보면 너무 뿌듯해진다 ;D

 

닷지 플레이 영상