RIT-B07 | RiteSeekers — Equipment 변경이 Ability State까지 이어지는지 확인한 과정
B05에서 Item과 Equipment를 따라가면서 장비가 바뀐다는 것이 단순히 Weapon Mesh를 교체하는 것보다 훨씬 많은 상태를 거친다는 걸 확인했습니다.
그 뒤로 장비 관련 문제를 볼 때 한 가지가 계속 신경 쓰였습니다.
화면에서는 새 Weapon을 들고 있는데, 실제로 그 Weapon의 Ability까지 바뀐 상태인지 알 수 없다는 점이었습니다.
예를 들어 이런 상태입니다.
Text
Equipment Slot
→ 새 Weapon
Weapon Mesh
→ 새 Weapon
하지만
ASC
→ 이전 Weapon Ability가 남아 있음또는 반대로 이전 Ability는 빠졌는데 새 Weapon의 Ability가 들어오지 않을 수도 있습니다.
그래서 장비 교체를 확인할 때는 화면에 보이는 Weapon만 보지 않고, 실제로 어떤
EquipmentSlotType과ItemInstance가 선택됐는지 확인한 뒤 ASC의AbilitySpec까지 같이 보기 시작했습니다.
Text
EquipmentEntry / ItemInstance
→ EquipmentSlotType
→ CurrentEquipState / Active Equip
→ Old AbilitySet Take
→ New AbilitySet Give
→ ASC AbilitySpec
→ Ability Activation이 흐름이 B07에서 확인한 내용입니다.
장비가 바뀌었다는 상태도 여러 단계로 나뉘었다
처음에는 장비가 바뀌었다는 하나의 상태로 생각했습니다.
하지만 Item / Equipment Source를 따라가면서 실제로는 서로 다른 상태가 이어지고 있었습니다.
Text
ItemInstance
→ 실제 Runtime Item
EquipmentEntry
→ 어느 Equipment Slot에 Item이 들어 있는지
EquipmentManager
→ Equipment Slot 상태 관리
EquipManager
→ 현재 실제로 사용할 Equipment 상태 관리
Equipment Actor
→ 손에 보이는 Weapon 표현
ASC AbilitySpec
→ 현재 ASC가 실제로 가진 Ability특히 이름이 비슷한 EquipmentManager와 EquipManager는 처음 볼 때 헷갈렸습니다.
제가 지금 구분해서 보는 기준은 이렇습니다.
Text
EquipmentManager
→ 어느 Slot에 어떤 Item이 들어 있는가
EquipManager
→ 그중 어떤 Equipment를 지금 Gameplay에 반영하고 있는가그래서 Equipment Slot에 Sword가 들어갔다고 해서 그 순간 Active Equipment와 ASC의 Ability까지 Sword 기준으로 바뀌었다고 보지는 않습니다.
Slot과 ItemInstance를 같이 봤다
처음에는 CurrentEquipState가 현재 사용 중인 Weapon 자체를 가리키는 값이라고 생각했습니다.
하지만 Runtime에서 직접 확인해 보니 CurrentEquipState는 Weapon_Primary, Unarmed처럼 현재 어떤 Equip State를 사용하고 있는지를 나타내는 값이었습니다. OneHandSword나 Staff 같은 실제 Item을 구분하는 값은 아니었습니다.
그래서 실제 장착 대상을 확인할 때는 EquipmentSlotType과 ItemInstance를 같이 봤습니다.
Text
CurrentEquipState
→ 어떤 Equip State를 사용하고 있는가
EquipmentSlotType
→ 어느 Equipment Slot을 처리하고 있는가
ItemInstance / ItemTemplateID
→ 실제 어떤 Item이 들어왔는가Staff를 장착한 Runtime에서는 다음 값을 확인했습니다.
Text
EquipmentSlotType = Primary_TwoHand
ItemTemplateID = 1500
📸 Screenshot 1. URSEquipManagerComponent::Equip()에 Primary_TwoHand 슬롯과 Staff의 ItemInstance(ItemTemplateID 1500)가 전달된 Runtime 상태.
Staff는 화면에서는 오른손에 들고 있지만, 현재 RiteSeekers의 Equipment 구조에서는 Primary_TwoHand 슬롯으로 분류하고 있습니다. 실제 손에 어떻게 보이는지와 Equipment Slot의 분류는 같은 개념으로 보지 않는 편이 맞았습니다.
Active Equip이 바뀌면 Ability도 같이 교체돼야 했다
Active Equipment가 변경되면 화면에 보이는 Weapon만 바뀌는 것이 아니라, Ability 쪽에서도 이전 장비의 상태를 정리하고 현재 장비의 상태를 다시 넣는 과정이 필요했습니다.
Text
Old Equipment
→ AbilitySet Take
New Equipment
→ AbilitySet Give실제 FRSEquipEntry::Equip() Source를 다시 확인해 보니, 이 교체 과정은 같은 함수 안에서 순서대로 진행되고 있었습니다.
Text
FRSEquipEntry::Equip
→ BaseAbilitySetHandles.TakeFromAbilitySystem
→ EquippableFragment->BaseAbilitySet
→ GiveToAbilitySystem
→ BaseAbilitySetHandles 갱신
🔡 SourceCode. FRSEquipEntry::Equip()에서 이전 Equipment AbilitySet을 TakeFromAbilitySystem()으로 정리한 뒤, 현재 Item의 BaseAbilitySet을 GiveToAbilitySystem()으로 ASC에 부여하는 부분.
여기서 새 AbilitySet을 부여할 때 현재 ItemInstance도 함께 전달됩니다.
C++
BaseAbilitySet->GiveToAbilitySystem(
ASC,
&BaseAbilitySetHandles,
ItemInstance
);즉 Equipment 교체는 단순히 Weapon Actor를 새로 보여주는 과정으로 끝나지 않습니다. 현재 Item에서 BaseAbilitySet을 가져오고, 이전에 저장해 둔 AbilitySet Handle을 이용해 기존 Ability를 제거한 뒤, 새로운 AbilitySet을 ASC에 다시 부여하는 흐름까지 이어집니다.
B05에서는 이 Give / Take를 Equipment Ability의 Lifetime 관점에서 따라가면서, 장비 변경 전후 ASC의 AbilitySpec이 실제로 교체되는 상태까지 확인했습니다.
B07에서는 같은 ASC 화면을 다시 반복해서 캡처하기보다, 앞에서 확인한 EquipmentSlotType / ItemInstance가 이 AbilitySet 교체 과정까지 어떻게 이어지는지를 연결해서 봤습니다.
Text
EquipmentSlotType / ItemInstance
→ EquippableFragment
→ BaseAbilitySet
→ Previous AbilitySet Take
→ Current AbilitySet Give
→ ASC AbilitySpec이 과정에서 TakeFromAbilitySystem()이 빠진다면 새 Weapon을 장착하더라도 이전 장비의 AbilitySpec이 ASC에 남을 수 있습니다.
반대로 이전 Ability는 정상적으로 제거됐지만 현재 Item의 BaseAbilitySet이 없거나 GiveToAbilitySystem()까지 이어지지 않는다면, ASC에는 새 Weapon에서 기대한 AbilitySpec이 들어오지 않을 수 있습니다.
그래서 Active Equipment가 바뀌었다는 사실과 ASC의 Ability 구성이 바뀌었다는 사실은 따로 확인하는 편이 더 정확했습니다.
Asset에 AbilitySet이 연결돼 있는 것만으로는 부족했다
Equipment Asset에서 BaseAbilitySet이 정상적으로 연결돼 있는 것은 필요한 조건이지만, 그것만으로 Runtime에서 해당 Ability가 실제로 사용 가능한 상태가 됐다고 볼 수는 없었습니다.
Editor에서 확인할 수 있는 것은 여기까지입니다.
Text
Equipment Asset
→ EquippableFragment
→ BaseAbilitySet 설정하지만 Runtime에서는 현재 장착된 ItemInstance에서 실제 EquippableFragment를 찾고, 그 Fragment가 가진 BaseAbilitySet을 ASC에 부여하는 과정까지 이어져야 합니다.
Text
ItemInstance
→ EquippableFragment
→ BaseAbilitySet
→ GiveToAbilitySystem
→ ASC AbilitySpec앞에서 확인한 FRSEquipEntry::Equip()에서도 이 연결이 그대로 나타났습니다.
C++
const URSItemFragment_Equipable* EquippableFragment =
ItemInstance->FindFragmentByClass<URSItemFragment_Equipable>();
if (const ULyraAbilitySet* BaseAbilitySet = EquippableFragment->BaseAbilitySet)
{
BaseAbilitySet->GiveToAbilitySystem(
ASC,
&BaseAbilitySetHandles,
ItemInstance
);
}즉 Asset에 BaseAbilitySet이 지정돼 있어도 현재 ItemInstance가 Equip 흐름에 들어오지 않았거나, EquippableFragment를 찾지 못했거나, GiveToAbilitySystem()까지 이어지지 않았다면 ASC의 Ability 상태는 기대한 결과와 다를 수 있습니다.
반대로 GiveToAbilitySystem() 호출 코드만 존재하는 것도 최종 결과 자체를 의미하지는 않습니다. 실제 Gameplay 관점에서는 그 결과 새 Equipment에 해당하는 AbilitySpec이 ASC에 들어왔는지까지 확인해야 합니다.
B05에서는 이 부분을 ASC의 Runtime AbilitySpec까지 따라가며 확인했습니다. B07에서는 같은 ASC Debugger 화면을 다시 추가하기보다, 앞에서 확보한 Runtime Item 정보와 FRSEquipEntry::Equip() Source를 연결해서 장비 상태가 AbilitySet 교체로 이어지는 경계를 정리했습니다.
그래서 Equipment 관련 문제를 볼 때는 다음 세 상태를 따로 구분해서 봅니다.
Text
BaseAbilitySet이 Asset에 설정돼 있는가
→ 설정 상태
현재 ItemInstance가 Equip 흐름에 들어왔는가
→ Equipment Runtime 상태
새 AbilitySpec이 ASC에 존재하는가
→ Gameplay Ability Runtime 상태이 세 단계가 모두 같은 의미는 아니었습니다. 특히 Editor 설정이 정상이라는 이유만으로 ASC까지 정상이라고 판단하지 않는 것이 중요했습니다.
장비 변경 전후 ASC 상태는 B05에서 확인했다
장비 Ability가 실제로 교체됐는지는 결국 ASC의 AbilitySpec을 확인해야 했습니다.
새 Ability가 들어왔다는 사실만 보면 이전 장비의 Ability가 그대로 남아 있는 문제를 놓칠 수 있기 때문에, 장비 변경 전후에는 두 가지를 같이 봤습니다.
Text
Old Ability
→ 실제로 제거됐는가
New Ability
→ 실제로 추가됐는가이 부분은 B05에서 이미 Runtime Debugger로 확인했습니다.
OneHandSword를 사용하던 상태에서는 해당 장비의 AbilitySpec이 ASC에 존재했고, 장비 교체 과정에서 기존 AbilitySet을 정리한 뒤 Staff의 AbilitySet이 들어오면서 Staff에 해당하는 AbilitySpec이 ASC에 추가되는 것을 확인했습니다.
Staff 쪽에서는 다음 Ability들이 ASC에 들어오는 상태를 확인했습니다.
Text
GA_MeleeCombo_Staff_1
GA_MeleeCombo_Staff_2
GA_Spell_Projectile_SoulBall그래서 B07에서는 같은 ASC Debugger 화면을 다시 캡처하지 않았습니다. 대신 그보다 앞에서 어떤 EquipmentSlotType과 ItemInstance가 선택되고, 그 Item의 BaseAbilitySet이 실제 Take / Give 과정으로 이어지는지를 확인했습니다.
Text
EquipmentSlotType / ItemInstance
→ EquippableFragment
→ BaseAbilitySet
→ Previous AbilitySet Take
→ Current AbilitySet Give
→ ASC AbilitySpec이렇게 보면 장비가 바뀌는 과정에서 어디까지 정상적으로 진행됐는지를 단계별로 나눌 수 있습니다.
예를 들어 현재 Item과 BaseAbilitySet까지 정상적으로 확인됐는데 새 AbilitySpec이 ASC에 없다면, Slot이나 Weapon Mesh를 다시 확인하기보다 AbilitySet Grant 구간을 먼저 볼 수 있습니다.
반대로 새 Weapon의 AbilitySpec까지 ASC에 정상적으로 들어왔다면 Equipment 교체 흐름은 상당 부분 통과한 상태이므로, 그다음부터는 InputTag나 Ability Activation 쪽으로 확인 범위를 옮길 수 있습니다.
결국 장비 변경을 확인할 때는 화면에 새 Weapon이 보이는 것보다, 이전 Ability가 정리되고 현재 장비의 Ability가 ASC에 실제로 들어왔는지를 따로 확인하는 것이 더 중요했습니다.
AbilitySpec까지 바뀌었다면 Input 쪽으로 넘어갔다
새 Equipment의 AbilitySpec이 ASC에 정상적으로 들어와 있다면 장비 교체 흐름은 이미 상당 부분 진행된 상태입니다.
이 시점부터는 Equipment Slot이나 ItemInstance를 계속 따라가기보다, B06에서 확인했던 Input과 Ability Activation 흐름으로 확인 범위를 옮겼습니다.
Text
New AbilitySpec
→ DynamicAbilityTags
→ InputTag
→ ProcessAbilityInput
→ TryActivateAbility여기서 중요한 것은 문제가 발생한 위치에 따라 다시 확인할 Source가 달라진다는 점이었습니다.
예를 들어 새 Weapon의 AbilitySpec 자체가 ASC에 없다면 아직 Input을 볼 단계가 아닙니다.
Text
New AbilitySpec 없음
→ ItemInstance
→ BaseAbilitySet
→ Take / Give
→ ASC Grant 구간 확인반대로 새 Weapon의 AbilitySpec이 ASC에는 존재하지만 기대한 DynamicAbilityTags가 없거나 InputTag와 연결되지 않는다면, Equipment 교체보다 Input 연결 쪽을 확인하는 편이 맞았습니다.
Text
New AbilitySpec 있음
→ DynamicAbilityTags 확인
→ InputTag Matching 확인
→ ProcessAbilityInput 확인
→ TryActivateAbility 확인B06에서는 실제 Runtime에서 InputTag.Attack.MainHand가 GA_MeleeCombo_OneHandSword_1의 DynamicAbilityTags와 일치하고, 같은 AbilitySpec Handle이 ProcessAbilityInput()의 AbilitiesToActivate를 거쳐 TryActivateAbility()까지 전달되는 흐름을 확인했습니다.
그래서 B07에서는 Equipment와 Input을 하나의 긴 문제로 보지 않고 경계를 나눠서 봤습니다.
Text
EquipmentSlotType / ItemInstance
→ BaseAbilitySet
→ ASC AbilitySpec
여기까지 정상
→ Input / Activation 확인이렇게 나누면 Equipment부터 Input까지 관련 Source를 한꺼번에 열어볼 필요가 없었습니다.
ASC에 새 AbilitySpec이 없다면 Equipment / AbilitySet 쪽에 집중하고, AbilitySpec까지 정상이라면 그때부터 InputTag와 Activation 쪽으로 넘어가는 식으로 확인 범위를 줄였습니다.
화면에 새 Weapon이 보여도 ASC는 따로 확인했다
Equipment는 Visual 변화가 분명해서 화면 결과를 먼저 확인하기 쉽습니다.
Weapon Actor가 바뀌고 손에 새 무기가 보이면 장비 교체가 끝난 것처럼 느껴질 수 있습니다.
하지만 이번에 Source와 Runtime 상태를 같이 따라가면서, 화면에 보이는 Weapon과 ASC의 Ability 상태는 따로 확인해야 한다고 봤습니다.
Text
Weapon Actor
→ 새 Weapon 표시
EquipmentSlotType / ItemInstance
→ 새 장비 상태 확인
ASC AbilitySpec
→ 새 장비 Ability가 실제로 들어왔는지 확인예를 들어 화면에서는 새 Weapon이 정상적으로 보이지만 ASC에는 이전 장비의 AbilitySpec이 그대로 남아 있을 수 있습니다.
Text
Weapon Mesh
→ New Weapon
ASC
→ Old AbilitySpec remains이 경우 Visual 교체는 정상이어도 Gameplay Ability 구성은 기대한 상태와 다릅니다.
반대로 ASC에는 새 장비의 AbilitySpec이 정상적으로 들어왔지만 UI의 Skill Icon이나 Weapon 표시가 아직 갱신되지 않았을 수도 있습니다.
Text
ASC
→ New AbilitySpec
UI / Visual
→ Previous State그래서 Weapon Mesh나 UI는 장비 교체 결과를 확인하는 데 유용하지만, 그것만으로 Ability 상태까지 판단하지 않았습니다.
B07에서 확인한 흐름을 기준으로 보면 Visual과 Gameplay State는 다음처럼 따로 이어집니다.
Text
ItemInstance
→ Equipment Actor / Weapon Visual
ItemInstance
→ BaseAbilitySet
→ ASC AbilitySpec둘 다 같은 Item에서 시작할 수 있지만, Runtime에서는 서로 다른 경로를 거치기 때문에 한쪽이 정상이라고 해서 다른 쪽도 자동으로 정상이라고 보지는 않았습니다.
결국 장비 교체를 확인할 때는 화면에 새 Weapon이 보이는지와 ASC의 Ability 구성이 실제로 바뀌었는지를 각각 확인하는 편이 더 정확했습니다.
Runtime 값을 따라가면 확인 범위가 금방 줄었다
Equipment 문제가 생겼을 때 처음부터 Slot, Weapon Actor, AbilitySet, ASC, Input Source를 전부 다시 따라가면 확인 범위가 너무 넓어졌습니다.
그래서 Runtime에서 이미 정상이라고 확인한 상태를 기준으로 다음 구간을 좁혀서 봤습니다.
예를 들어 다음 상태까지 확인됐다고 해보겠습니다.
Text
EquipmentSlotType / ItemInstance
→ 기대한 Weapon 확인
CurrentEquipState
→ 기대한 Equip State 확인
Old AbilitySpec
→ Removed
New AbilitySpec
→ 없음이 상태라면 Equipment Slot이나 Weapon Visual부터 다시 확인할 필요는 없습니다.
실제 Item이 기대한 Slot을 통해 Equip 흐름에 들어왔고, 이전 장비의 Ability도 정리됐기 때문입니다.
이 경우 다시 볼 범위는 자연스럽게 다음 구간으로 줄어듭니다.
Text
ItemInstance
→ EquippableFragment
→ BaseAbilitySet
→ GiveToAbilitySystem
→ ASC AbilitySpec반대로 다음 상태라면 확인 위치가 달라집니다.
Text
EquipmentSlotType / ItemInstance
→ 기대한 Weapon 확인
New AbilitySpec
→ Present
DynamicAbilityTags
→ 기대한 InputTag와 다름새 Equipment의 AbilitySpec까지 ASC에 들어왔다면 Equipment 교체 자체를 계속 따라가기보다 Input 연결 쪽으로 넘어가는 편이 맞았습니다.
Text
ASC AbilitySpec
→ DynamicAbilityTags
→ InputTag Matching
→ ProcessAbilityInput
→ TryActivateAbility결국 제가 확인한 순서는 다음과 같았습니다.
Text
EquipmentSlotType / ItemInstance
→ Equip State
→ AbilitySet Take / Give
→ ASC AbilitySpec
→ Input
→ Activation앞 단계가 정상이라면 그 구간을 다시 뒤지지 않고 다음 단계로 넘어갔습니다.
이 방식으로 보면 장비 교체와 Ability Activation을 하나의 긴 흐름으로 보면서도, 실제 문제가 어느 구간에 있는지 빠르게 범위를 줄일 수 있었습니다.
이 글의 예시는 실제 버그 기록은 아니다
이 글에서 사용한 상황은 Equipment와 ASC State를 어떻게 같이 확인할 수 있는지 설명하기 위해 정리한 예시입니다.
Text
Weapon Visual은 바뀌었는데
Ability가 예상대로 바뀌지 않는다이 상황이 RiteSeekers 개발 중 실제로 그대로 발생했고, 특정 Root Cause를 찾아 수정했다는 의미는 아닙니다.
B07에서 실제로 확인한 것은 다음과 같은 연결입니다.
Text
EquipmentManager
→ EquipmentEntry / ItemInstance / EquipmentSlotType
EquipManager
→ CurrentEquipState / Active Equip
FRSEquipEntry::Equip
→ Previous AbilitySet Take
→ Current BaseAbilitySet Give
ASC
→ AbilitySpec Runtime State또한 Runtime에서는 Staff가 Primary_TwoHand 슬롯의 ItemInstance로 Equip 흐름에 들어오는 상태를 확인했고, Source에서는 같은 Equip 과정 안에서 기존 AbilitySet을 정리한 뒤 현재 Item의 BaseAbilitySet을 ASC에 부여하는 흐름을 확인했습니다.
Text
EquipmentSlotType / ItemInstance
→ EquippableFragment
→ BaseAbilitySet
→ TakeFromAbilitySystem
→ GiveToAbilitySystem
→ ASC AbilitySpec따라서 이 글은 특정 버그 하나를 해결한 기록이라기보다, Equipment 변경이 Gameplay Ability State까지 이어지는 구조를 기준으로 실제 문제가 생겼을 때 어떤 Runtime 값을 순서대로 확인할 수 있는지 정리한 글에 가깝습니다.
실제 발생하지 않은 문제를 해결 사례처럼 보이게 만들기보다, Source와 Runtime에서 직접 확인한 범위까지만 설명하는 편이 더 정확하다고 봤습니다.
Source에서 다시 찾은 위치
Equipment와 ASC State를 같이 볼 때는 관련 Class를 전부 외우기보다, 실제 상태가 이동하는 순서를 기준으로 Source를 다시 찾았습니다.
Text
EquipmentManager
→ EquipmentEntry
→ ItemInstance
→ EquipmentSlotType
EquipManager
→ CurrentEquipState
→ EquipCurrentSlots
→ Equip
FRSEquipEntry::Equip
→ BaseAbilitySetHandles.TakeFromAbilitySystem
→ EquippableFragment->BaseAbilitySet
→ GiveToAbilitySystem(ASC, &BaseAbilitySetHandles, ItemInstance)
ASC
→ AbilitySpec
→ DynamicAbilityTags이번에 Runtime에서 Staff가 어떤 장비 상태로 들어오는지 확인할 때는 URSEquipManagerComponent::Equip()까지 따라가서 EquipmentSlotType과 ItemInstance를 같이 봤습니다.
그 뒤 Ability 쪽에서는 FRSEquipEntry::Equip() 안에서 이전 AbilitySet을 정리하고 현재 Item의 BaseAbilitySet을 ASC에 다시 부여하는 흐름을 확인했습니다.
Input까지 확인할 필요가 있을 때만 B06에서 봤던 다음 흐름으로 더 내려갔습니다.
Text
AbilitySpec
→ DynamicAbilityTags
→ InputTag Matching
→ ProcessAbilityInput
→ TryActivateAbility그래서 실제로 다시 Source를 찾을 때는 전체 Class 이름을 외우기보다 다음 정도의 순서를 기억하는 편이 더 편했습니다.
Text
Equipment Slot / ItemInstance
→ Active Equip
→ Ability Lifetime
→ ASC AbilitySpec
→ Input앞 단계의 Runtime 값이 정상이라면 그 구간을 다시 뒤지지 않고 다음 단계로 넘어갈 수 있었습니다.
프로젝트를 진행하며 달라진 부분
처음에는 Equipment 교체를 확인할 때 가장 먼저 눈에 보이는 결과를 봤습니다.
Text
Weapon Mesh가 바뀌었는가
Equipment UI가 바뀌었는가하지만 Source와 Runtime 상태를 따라가면서, 화면에 보이는 변화만으로는 실제 Gameplay State까지 바뀌었다고 판단하기 어렵다는 걸 알게 됐습니다.
지금은 장비가 바뀔 때 다음 상태를 순서대로 봅니다.
Text
어떤 Item이 어느 EquipmentSlotType에 들어갔는가
→ 현재 어떤 Equip State가 사용되고 있는가
→ 이전 Equipment AbilitySet이 정리됐는가
→ 현재 Item의 BaseAbilitySet이 ASC에 부여됐는가
→ ASC의 AbilitySpec이 실제로 바뀌었는가여기까지 정상이라면 그다음에 Input과 Ability Activation으로 넘어갑니다.
Text
ASC AbilitySpec
→ DynamicAbilityTags
→ InputTag
→ ProcessAbilityInput
→ TryActivateAbility이렇게 나누고 나니 Equipment 교체를 단순히 Weapon 하나를 다른 Weapon으로 바꾸는 기능으로만 보지 않게 됐습니다.
Text
Item / Equipment State
→ Visual State
→ AbilitySet Lifetime
→ ASC Runtime State
→ Input / Activation각 단계가 서로 이어져 있지만 같은 상태는 아니기 때문에, 앞 단계가 정상이라는 이유만으로 뒤 단계까지 정상이라고 판단하지 않는 편이 더 정확했습니다.
특히 이번에 CurrentEquipState를 직접 확인하면서도 하나를 더 구분하게 됐습니다.
CurrentEquipState는 OneHandSword나 Staff 같은 실제 Weapon을 식별하는 값이 아니라 Weapon_Primary, Unarmed처럼 현재 사용하는 Equip State를 나타냈습니다.
실제 장착된 Item을 확인할 때는 EquipmentSlotType, ItemInstance, ItemTemplateID 같은 값을 함께 봐야 했습니다.
결국 Equipment 관련 문제를 볼 때도 화면 결과에서 시작해 Source 전체를 한꺼번에 따라가기보다, 실제 Runtime State가 어디까지 기대한 값으로 이어졌는지를 먼저 확인하는 방식으로 바뀌었습니다.
정리
RiteSeekers에서 Equipment와 Ability 연결을 다시 따라가며 가장 중요하게 본 것은 화면에 보이는 장비 상태와 ASC의 실제 Ability 상태를 같은 것으로 보지 않는 것이었습니다.
장비 교체는 단순히 Weapon Mesh 하나가 바뀌는 과정이 아니었습니다.
Text
EquipmentEntry / ItemInstance
→ EquipmentSlotType
→ CurrentEquipState / Active Equip
→ Previous AbilitySet Take
→ Current AbilitySet Give
→ ASC AbilitySpec
→ Input / Ability Activation각 단계는 서로 이어져 있지만 같은 상태를 의미하지는 않습니다.
CurrentEquipState 역시 OneHandSword나 Staff 같은 실제 Weapon을 직접 식별하는 값이 아니라 Weapon_Primary, Unarmed처럼 현재 사용하는 Equip State를 나타냈습니다.
그래서 실제 장착 대상을 확인할 때는 다음 값을 함께 봤습니다.
Text
EquipmentSlotType
→ 어느 Equipment Slot을 처리하고 있는가
ItemInstance / ItemTemplateID
→ 실제 어떤 Item이 들어왔는가
CurrentEquipState
→ 현재 어떤 Equip State를 사용하고 있는가Staff의 Runtime 상태에서는 Primary_TwoHand 슬롯과 ItemTemplateID 1500을 확인했고, Source에서는 현재 Item의 BaseAbilitySet을 가져오기 전에 이전 AbilitySet을 정리하고 새 AbilitySet을 ASC에 부여하는 흐름을 확인했습니다.
Text
ItemInstance
→ EquippableFragment
→ BaseAbilitySet
BaseAbilitySetHandles.TakeFromAbilitySystem
→ Previous Ability 제거
GiveToAbilitySystem
→ Current AbilitySet 부여
ASC
→ AbilitySpec Runtime State장비 관련 문제가 생겼을 때도 처음부터 Equipment와 Input Source를 전부 열어보지 않습니다.
Text
Equipment Slot / ItemInstance
→ Active Equip
→ AbilitySet Lifetime
→ ASC AbilitySpec
→ Input
→ Activation순서로 Runtime 값이 어디까지 기대한 상태인지 확인합니다.
새 AbilitySpec 자체가 없다면 Equipment / AbilitySet Grant 구간을 보고, AbilitySpec까지 정상이라면 그때부터 DynamicAbilityTags, InputTag, ProcessAbilityInput, TryActivateAbility 쪽으로 넘어갑니다.
예전에는 Weapon Mesh와 UI가 바뀌면 Gameplay 쪽 상태도 자연스럽게 같이 바뀌었을 거라고 생각하기 쉬웠습니다.
지금은 장비가 바뀌었다는 Visual 결과와, 현재 Item이 선택됐다는 Equipment Runtime 상태, 그리고 Ability 구성이 바뀌었다는 ASC Runtime 상태를 각각 나눠 확인하는 편이 더 정확하다고 보고 있습니다.