One_KWS

게임 개발 일지 #5 - 몬스터 공격, 이동 본문

게임 개발

게임 개발 일지 #5 - 몬스터 공격, 이동

One-Kim 2023. 1. 26. 00:08

Enemy

몬스터의 클래스 구조도 플레이어와 비슷하다. 각 행동들은 IBehaviour 인터페이스를 구현하고 있고 EnemyController에서 행동들을 제어한다.

 

EnemyController 

PlayerController와 마찬가지로 몬스터의 공격과 이동을 제어한다. 몬스터는 일정 범위 내에 플레이어가 들어오면 공격을 해야 하기 때문에 Physics.SphereCastAll를 이용하여 범위 내에 플레이어가 들어오는지 체크하도록 했다. 

[SerializeField] private float sightRange;

...

private Transform FindTarget() {
    var hits = Physics.SphereCastAll(transform.position, sightRange, Vector3.up, 0);
    foreach (var hit in hits) {
        if (hit.transform.CompareTag("Player")) {
            return hit.transform;
        }
    }

    return null;
}
 

공격 및 이동

 target이 null이 아닐 경우 공격이나 이동을 하도록 했고 몬스터의 공격 중일 경우에는 이동하지 않도록 구현했다. target이 null일 경우 몬스터의 근처에 플레이어가 없는 것으로 판단하고 행동을 리셋하도록 했다. 

 private void Update() { 	
    ...
   
    target = FindTarget();

    if (target == null) {
        ResetBehaviour();
        return;
    }

    Attack();
    Move();
}

private void Attack() {
    enemyCombat.Execute(target.position);
}

private void Move() {
    if (enemyCombat.IsOngoing) {
        enemyMovement.Cancel();
        return;
    }

    enemyMovement.Execute(target.position);
}

 

IBehaviour 

몬스터의 공격과 이동을 구현하다보니 Target의 position을 공격과 이동의 Execute 함수의 매개변수로 넘겨줘야 했다. 그래서 일단은 IBehaviour의 Execute 함수가 Vector3 매개변수를 받도록 수정했고 플레이어의 코드도 같이 수정했다. 

public interface IBehaviour {
    public bool IsOngoing { get; }
    public void Execute(Vector3 direction);
    public void Cancel();
}

 

공격

공격시 공격 범위 내에 있는지 확인하기 위해 Vector3.Distance를 이용하여 Target과 몬스터 사이의 거리를 구하고 거리가 공격 범위보다 클 경우에는 리턴하도록 했다. 

public void Execute(Vector3 direction) {
    ...
    
    var distance = Vector3.Distance(direction, transform.position);
    if (distance > attackRange) {
        return;
    }
    
    transform.LookAt(direction);
    animator.SetTrigger("attack");
}

 

이동

이동의 경우 플레이어와 같게 구현했다. Vector3 매개변수를 받아 해당 방향으로 이동하도록 했다.

public void Execute(Vector3 direction) {
    transform.LookAt(direction);
    
    animator.SetBool("move", true);
    characterController.Move(transform.forward * (velocity * Time.deltaTime));
}

 

몬스터 이동&공격