Enemy Roaming 만들기

devKyoun·2024년 10월 18일
0

Unity

목록 보기
10/27

이제 적을 만들어볼텐데 FSM으로 구현하려고 한다

Enemy Roaming 틀 만들기

그 전에 우선 적은 플레이어를 감지하기 전에 패트롤 형태로 위치를 이동한다
그것을 Roaming이라고 앞으로 말하겠고 이 Roaming을 구현하려고 한다

왜 먼저 이 틀을 짜냐면 각 상태의 기능을 표현하는 Script를 짤때 그대로 가져오기 위함

내가 사용 할 오늘의 모델

EnemyAI.cs를 생성하고 시작 지점 + 랜덤 방향 * 랜덤 거리 를 통해 Roaming의 목표 지점을 만든다


private void Awake()
{
    startingPosition = transform.position;
}

{ ... }

private Vector3 GetRoamingPosition()
{
    Vector3 randomDir = new Vector3(Random.Range(-1f, 1f), 0, Random.Range(-1f, 1f)).normalized;
    return startingPosition + randomDir * Random.Range(minRoamingDistance, maxRoamingDistance);
}

해당 목표 지점은 AI Navigation을 이용해서 이동 시키려고 한다

 private NavMeshAgent enemyNavAgent;

 #region Roaming
 private NavMeshPath path = null;

 private Vector3 startingPosition;
 private Vector3 roamPosition;
 private bool setRoamPos = false;

  [SerializeField]
 private float minRoamingDistance = 10;
 [SerializeField]
 private float maxRoamingDistance = 70;
 #endregion
 private void Awake()
 {
     enemyNavAgent = GetComponent<NavMeshAgent>();

     startingPosition = transform.position;
     roamPosition = GetRoamingPosition();
     setRoamPos = true;
 }

 private void Update()
 {
     if (setRoamPos)
     {
         path = new NavMeshPath();
         enemyNavAgent.CalculatePath(roamPosition, path);
         enemyNavAgent.SetPath(path);
         path = null;

         setRoamPos = false;
     }

     if(enemyNavAgent.remainingDistance <= enemyNavAgent.stoppingDistance)
     {
         setRoamPos = true;
         roamPosition = GetRoamingPosition();
     }

 }

 private Vector3 GetRoamingPosition()
 {
     Vector3 randomDir = new Vector3(Random.Range(-1f, 1f), 0, Random.Range(-1f, 1f)).normalized;
     return startingPosition + randomDir * Random.Range(minRoamingDistance, maxRoamingDistance);
 }

처음 Awake에서 GetRoaming을 받아주면 setRoamPos을 통해 Roaming 목표 지점을 받았다고 true로 변경해준다

그러고 Update에서 setRoamPos이 True인 경우에만 NavMeshAgent를 통해 목표 지점을 설정하고 setRoamPos 을 False로 해준다

remainingDistance 와 stoppingDistance를 이용해서 목표지점에 도달했을때 다시 Awake에서 해줬던 작업을 실행해준다

이제 두 가지 해야 할 일이 있다

  • 도착 지점에서 바로 즉시 Roaming을 하는 경우인데 이를 waitTime을 통해 일정시간 후에 이동하게끔 하는 것
        if(enemyNavAgent.remainingDistance <= enemyNavAgent.stoppingDistance)
        {
            // 도착 했을때, Timer 시작
            waitCounter += Time.deltaTime;

            if (waitCounter >= waitTime)
            {
                setRoamPos = true;
                roamPosition = GetRoamingPosition();
                waitCounter = 0;
            }
        }
  • 이동 애니메이션 추가
       private void Update()
	{
      if (setRoamPos)
      {
          path = new NavMeshPath();
          enemyNavAgent.CalculatePath(roamPosition, path);
          enemyNavAgent.SetPath(path);
          path = null;

          setRoamPos = false;

          animator.SetBool(animIDWalk, true);
      }

      if(enemyNavAgent.remainingDistance <= enemyNavAgent.stoppingDistance)
      {

          // 도착 했을때, Timer 시작
          waitCounter += Time.deltaTime;

          if (waitCounter >= waitTime)
          {
              setRoamPos = true;
              roamPosition = GetRoamingPosition();
              waitCounter = 0;
          }
      }
      else
      {
          animator.SetBool(animIDWalk, true);
      }

	}

해결이 됐다
이 기능은 이제 EnemyRoamingState 로 가동 될 예정이다

profile
Game Developer

0개의 댓글