씬 전환 간 몬스터 AI 기능 에러

양규빈·2023년 11월 24일

디버깅

목록 보기
4/6

문제 개요

통상적으로 필드의 몬스터는 플레이어의 위치에 따라 생성과 소멸을 반복하는 데 반해, 던전의 몬스터는 개체 생성 후, 소멸하지 않고 자리에서 대기하거나 순찰하며 플레이어를 맞이합니다.

따라서, 기존의 몬스터 생성 방식과 다른 방식으로 몬스터를 생성해야 했습니다.

그렇게 구현한 몬스터 생성 코드에서 핵심은 StaticFixed 변수를 true로 초기화하는 것이었습니다.

몬스터의 소멸은 플레이어를 기준으로 이뤄지며, 이를 제어하는 플래그 변수를 조건으로 추가한다면, 일정 범위 내에 플레이어가 없더라도 몬스터가 소멸하지 않을 수 있는 것입니다.

이렇게 고정된 지점에서 몬스터를 구현하였지만, 문제가 발생했습니다.
바로, 위 사진과 같이 몬스터가 플레이어를 인식하고 공격하는 행위를 하지 않는다는 것이었습니다.

고정 방식 생성이 아닌, 플레이어의 스폰위치 접근에 따른 동적 생성의 경우에도 문제가 발생하는지 확인하기 위해, 오픈 필드의 스폰 방식을 던전에 그대로 구현하였지만, 이 경우에는 문제가 발생하지 않았습니다.

즉, 고정 생성 방식에 문제가 있는 것이었습니다.

던전 구현과 관련된 상세한 내용은 배틀 레드 개발 일지에 작성하고, 해당 문서에는 디버깅 관련된 내용을 위주로 쓰도록 하겠습니다.

문제 해결_1안

가장 먼저, 저는 유니티의 생성 주기를 떠올렸습니다.
게임 필드 씬 → 던전 씬으로 전환 간에, 모노비헤이어의 생성 주기에 문제가 있다고 판단한 것입니다.

몬스터의 이동에는 문제가 없고, 오로지 몬스터의 공격에 문제가 있기 때문에, MonsterAttackManager의 생성/분류를 담당하는 MonsterAtkDivider()함수에 문제가 있을 거라 판단 후, 코드를 수정했습니다.

└ 상단의 CreateMonster 함수는 던저매니저 함수에 구현하였다가, 코드의 추상화를 유지하기 위해서 GameManager() 클래스로 이동했습니다

사진을 보면 알다시피, 몬스터의 생성 역시 Start 단계에서 이뤄지기 때문에, 여기서 AttackManager에 문제가 발생하는 것이라 생각했습니다.

그렇기에, 몬스터의 생성을 Awake 단계로 내리는 수정 조치를 했지만, 여전히 몬스터는 플레이어를 인식하지 못했습니다.

당연한 일이었습니다.

MonsterManager를 ObjectPool패턴을 통해서 ActiveTrue로 전환한 후에 AttackManager를 분류하는 Monster 클래스를 곧바로 할당하기 때문입니다.

(객체 초기화 -> Awake -> 함수 종료 -> Start 단계로 이루어지는 걸 확인했습니다.)

즉, Start단계 전에 몬스터 클래스가 할당되어, 정상적으로 몬스터 어택 매니저를 분류하고 작동시키는 것입니다.

문제 해결_2안

Awake - Start의 생성주기에는 문제가 없는 것을 확인했습니다.
조금 더 확실한 문제 해결을 위해서, 저는 플레이어 객체가 몬스터의 탐지 범위 내에 들어 갔을 때, 어떤 식으로 공격 프로세스가 동작하는지 디버깅을 찍어서 확인해보았습니다.

플레이어가 몬스터를 공격한다면, 강제로 타겟으로 설정되고, 몬스터는 타겟이 추격 범위 내에 있으면 공격 AI를 가동합니다.

즉, 몬스터 공격 후, 타겟으로 설정된 플레이어와 몬스터 사이에 어떤 일이 일어났는지 확인했습니다.

문제는 해당 코드에서 발견할 수 있었습니다.
플레이어 객체와 몬스터 객체의 좌표가 아래로 설정되어 조건문을 돌린 것입니다.

플레이어
62.6 84.7 -246

몬스터
64.4 75.8 -154.7

추적 범위는 15인데 반해, 둘 사이의 거리는 90이 넘는 것으로 값이 찍혔습니다.
따라서, 몬스터는 추격을 멈추고, 공격 페이즈를 곧바로 종료했던 것입니다.

두 좌표값의 불일치 문제를 해결하기 위해서, 먼저 오브젝트들을 같은 부모로 묶어보려했습니다.
(다만, 플레이어 위치를 기반으로 한 동적 생성 시에는, 플레이어와 몬스터의 부모 객체가 다르더라도 문제가 발생하지 않았었습니다. 부모 객체가 다른 것이 원인은 아닌 것으로 추측됩니다.)

이 과정에서, 몬스터의 생성 코드가 동작되는 던전 매니저의 Start or Awake 단계에선, 씬이 로딩중이라는 것을 확인했습니다.

또한, 플레이어 객체가 Update 단계에서, 3프레임 이후에 Instantiate 된다는 것을 확인했습니다.
(플레이어 객체를 옮기기 위해서 태그를 기준으로 객체를 참조하려 했지만, 3번의 Null Reference 에러가 발생했습니다.)

따라서 씬이 완전히 생성된 이후, 즉. 플레이어가 Instantiate 된 이후에, 몬스터를 생성하는 방식으로 바꿨습니다.

위 로직이 바로, 몬스터 스폰 함수 호출 방식을 바꾼 것입니다.
씬 상에서 플레이어 객체의 존재 유무를 확인하고, Update 단계에서 몬스터를 생성하고, 반복을 막기 위해서 제어 변수를 true로 변경한다.

최종적으로는 몬스터 객체가 플레이어를 인식하고 공격 AI를 돌리는 것을 확인할 수 있었습니다.

profile
훌륭한 개발자를 꿈꾸는 중입니다

0개의 댓글