강의를 따라하며 Behavior Tree를 만들다가 AI가 나를 공격하지 않는 문제가 생겨 살펴보았다.
BTS_IsCloseToPlayer 서비스에서 플레이어와의 거리가 125 이하가 되면 canAttackPlayer가 true로 갱신된다.
아래 트리를 보면 canAttackPlayer의 값이 true임에도 Is Set 흐름으로 이동하지 않고 stuck된 것을 볼 수 있다.
AI는 아무 것도 하지 않고 내 앞에 서 있는 상태이다.
내가 아직 Decorator에 대한 이해가 부족한 탓이라고 생각해 유튜브와 공식 문서, 블로그 등을 찾아보았다.
그러면서 Decorator의 Notify Observer, Observer aborts에 대해 알게 되었다.
Decorator는 매 번 혹은 매 프레임마다 값에 따른 조건을 검사하는 것이 아니라 조건을 미리 예측해 분기를 결정한다.
그렇기 때문에 Observer가 값의 변경을 감시하고 있다가 분기 예측 결과나 값이 변경되면 Notify를 발생시키고 특정 노드들을 Abort 시키는 방식으로 작동한다.
값이 변경되었음에도 해당 흐름으로 진행되지 않는 문제를 겪은 사람이 나 말고도 있었다.
Discussion에 따르면 이전 버전에서도 이런 문제가 있었고 값이 변경되어도 Decorator가 정상적으로 분기 예측 결과를 갱신하지 못 해 발생하는 문제 같다.
<성공 1> Is Not Set 조건의 Observer aborts를 Both -> None으로 변경하면 canAttackPlayer 값에 따라 정상적으로 실행 흐름이 진행된다.
- Abort가 Decorator의 갱신에 관련 있는 것인가..?
canAttakcPlayer가 참이 됨에 따라 AI가 나를 공격한다.
삽질하며 시도해 다른 방법들이다.
<성공 2> Oberver aborts는 그대로 Both로 두고 좌우 노드 순서를 바꾼다.
- 언리얼 카페에 물어봤지만 답해주는 분이 없었다..
<성공 3> canAttackPlayer의 값을 서비스가 아닌 태스크에서 처리한다.
- 블랙보드 키 갱신은 보통 서비스에서 한다고 알고 있는데 서비스에서 설정할 때 Notify에 문제가 있는 것인가..?
<성공 4> canAttackPlater의 값을 외부에서 키 입력으로 수동으로 바꾼다.
- 이때는 거리와 상관 없이 값이 바뀌자마자 AI가 나를 공격한다.
서비스에서 블랙보드 키의 값을 설정할 때 Decorator 갱신에 문제가 있는 게 아닐까하는 추측으로 시도해 본 방법이다.
<실패> 서비스를 실행하되 값 설정은 외부에서 한다.
- 될 줄 알았는데 안 되더라..
여러 방법들을 시도해보며 해결책은 찾았지만 정확한 원인은 알지 못해 찜찜하다..
어제 오후부터 오늘 아침까지 이 문제의 원인을 찾으려고 삽질했는데 빨리 다른 챕터도 공부해야하므로 이쯤 하고 글로 남긴다.
나중에 고수를 만나면 꼭 다시 물어봐야겠다.
'문제 해결' 카테고리의 다른 글
Anim Instance의 델리게이트가 발동되지 않는 문제 (해결 과정) (0) | 2023.07.18 |
---|---|
UWidgetComponent의 위젯 생성 시점 (0) | 2023.03.16 |
알고리즘 시간 초과 해결 (0) | 2023.02.18 |
문제의 축소 (0) | 2023.02.03 |