게임개발일지/리그오브워치

[리그오브워치개발일지] 10 # Bugfix # 미니언 전투 버그 수정

김진우 개발일지 2023. 10. 26. 04:20

Git

이번 글부터는 기준 브랜치를 따로 만들지 않고 태그를 추가하기로 결정했다.
레포지토리 주소 : https://github.com/kjinwoo12/UE5Game_LeagueOfWatch
기준 태그 : 10_Bugfix_MinionAI

문제 발견

미니언은 적을 만나면 공격한다. 이 기능은 [리그오브워치개발일지] #6 미니언 AI - 자동공격에서 다뤘다. AIC_Minion퍼셉션 업데이트 시 이벤트에서 AddAttackTarget 함수와 RemoveAttackTarget 함수를 사용해 공격 타겟 목록을 관리하고, Tick 이벤트에서 사거리 내에 존재하는지 확인 후 공격하도록 만들었다. 하지만 정상적으로 작동하지 않는 문제를 발견했는데, 만난 적과 전투가 끝나면 다음 적과 전투를 이어서 하는 것이 아니라 무조건 다음 PatrolPoint로 이동하기만 하는 버그다. 원인을 분석하고 미니언이 다음 전투로 넘어갈 수 있도록 고쳐야한다.

미니언 전투 수정

문제 분석을 조금 더 쉽게 진행하기 위해서 레벨을 새로 만들었다. 레벨 TestMinion에서 미니언의 동작을 확인할 것이다.

버그 재연

양 끝에 나타나는 미니언은 서로 다른 팀이다. 적을 감지하지 않을 때에는 상단에 구 모양으로 표시된 PatrolPoint로 이동하고, 적을 감지하면 이동을 멈추고 감지한 적을 공격할 것이다. 하지만 영상에서는 처음 만난 미니언을 공격한 다음에 해당 미니언이 죽으면 다른 미니언을 공격하지 않고 PatrolPoint로 곧바로 이동하는 모습을 확인할 수 있다.

추측

값 감시를 통해 AttackTargets를 확인해본 결과, 함수 AddAttackTarget가 실행되며 입력된 배열 요소는 정상적이지만 RemoveAttackTarget가 호출되는 시점에 문제가 발생하는 것으로 보였다.

공격을 멈춘 상태에서 AttackTargets의 값은 인덱스 0번이 None인 것을 확인했다. 아마 배열 안에 있는 액터가 다른 원인에 의해 제거되었을 때 발생하는 문제거나 또는, 공격중인 대상이 파괴되었을 때 다음 미니언으로 대상을 옮기는 코드가 누락되었을 가능성이 있다. 전자의 경우 블랙보드에 값을 전달할 때 값이 AttackTargets의 요소 중 값이 None인 요소를 제거하면 문제를 해결할 수 있을 것이고 후자의 경우 코드가 누락되었는지 아닌지 확인 후 누락되었다면 추가를, 누락되지 않았다면 코드가 실행되지 않는 이유를 찾아야 한다.

버그 테스트

테스트 1. 함수 RemoveAttackTarget에서 배열 AttackTargetsNone 요소 제거

문제가 사라지지 않았다. 공격을 멈춘 미니언의 AttackTargets 배열을 확인해본 결과 여전히 인덱스 0번이 None인 것을 확인할 수 있었다. 지금까지 미니언이 죽어서 제거되면 AI의 시야에서 미니언이 사라지니 자연스럽게 타깃 퍼셉션 업데이트 이벤트에서 처리될 것으로 생각했다. 하지만 타깃 퍼셉션 업데이트는 생각과 다르게 동작하는 것 같고, Stimulus.SuccessfullySensed 의 값은 시야에서 사라짐을 의미하는 것이 아닌 것 같았다. 좀 더 자세히 이벤트의 동작과 매개변수의 의미를 알아볼 필요가 있다.

 

테스트 2. Tick 이벤트에서 배열 AttackTargetsNone 요소 제거

AIC_MinionUpdateAttackTarget 함수를 추가한다. 이 함수의 역할은 Tick마다 AttackTargets 배열의 요소들 중 None을 제거하고 인덱스 0번에 해당하는 요소를 블랙보드에 AttackTargetActor으로 전달하는 것이다. 이 과정에서 AIPerception - 감지 환경설정시야구성 설정 중 시야 반경은 2200, 시야 상실 반경은 2400, 주변 시야 반각도는 180, 마지막으로 본 위치에서 범위 자동 성공은 2200으로 설정했다.

UpdateAttackTarget 함수는 Tick 이벤트에 추가해준다. OnPossess 이벤트도 GenericTeamId 관련해서 수정된 모습을 볼 수 있는데, GenericTeamIdAIPerception이 팀을 구분해서 시야 감각을 작동할 수 있도록 돕는다. AI 시야 구성에서 귀속 감지에 사용된다. 자세한 정보는 이후에 다루도록 하겠다.

위 과정을 마치고 테스트를 한 결과다.

전투를 한 번만 진행하는 미니언이 눈에 띄게 줄었지만, 미니언이 한 번의 전투를 마친 후에 PatrolPoint로 이동하고 다시 AttackTarget으로 돌아와 다시 전투를 진행하는 모습을 보인다. 배열 안에 None이 생기는 문제는 해결했지만 또 다른 문제점을 찾았다.

또다른 미니언 전투 버그 수정

미니언이 한 번 전투를 끝내면 다음 미니언과 싸우기 전 PatrolPoint를 방문했다가 AttackTarget을 향해 돌아와 전투를 진행하는 버그를 발견했다. 이런 모습을 보이는 원인은 첫 번째 비헤이비어 트리 문제인 경우가 있고, 두 번째는 코드 자체에 버그가 있는 경우다. 먼저 비헤이비어 트리를 확인해보자

비헤이비어 트리 확인

비헤이비어 트리에서 문제를 발견했다. 한 마리를 제외한 모든 미니언이 죽어 더이상 AttackTarget이 존재하지 않는데도 불구하고 살아남은 미니언의 비헤이비어 트리에서 블랙보드 데코레이터인 IsValidAttackTarget가 활성화되어 있는 것이다. 데코레이터를 자세히 살펴보니 조건 블랙보드 키가 AttackTargetActor가 아닌 bool IsValidAttackTarget으로 설정되어 있음을 확인했다. 이 변수의 사용처를 확인해본 결과 필요없는 키로 확인되어 삭제했다.

버그 수정 후 영상

문제가 모두 수정되었음을 확인했다.