ChatGPT에게 이런식으로 CDO 영역에 Actor가 AttributeSet를 생성만 해줬는데 어떻게 ASC가 이를 인식하고 적용한 지 물어봤고 아래는 그에 대한 답변이다
좋은 포인트 짚으셨어요 👍
UAbilitySystemComponent::InitializeComponent 시점에서 AttributeSet들이 자동으로 ASC(AbilitySystemComponent)에 붙는 이유를 단계별로 설명드릴게요.
1. AttributeSet은 UObject
UAttributeSet은 UObject 기반이라서, 보통 UAbilitySystemComponent의 DefaultSubobject 또는 Owner의 Subobject로 만들어집니다.
즉, ASC가 소유한 액터(보통 ACharacter, AActor 등)에 CreateDefaultSubobject<UAttributeSet_XXX>(TEXT("AttributeSetName")) 식으로 멤버 선언해두면, 그 AttributeSet은 액터가 생성될 때 이미 인스턴스화되어 있고, Owner의 ChildObjects에 들어갑니다.
2. ASC의 InitializeComponent 동작
UAbilitySystemComponent::InitializeComponent() 내부에서는 대략 이런 로직을 탑니다:
- GetOwner() → ASC가 붙은 액터를 가져옴
- 액터의 ChildObjects(Subobjects) 를 순회
- 그 중에서 UAttributeSet을 상속한 애들을 모두 찾아서 SpawnedAttributes 배열에 등록
즉, 내가 따로 AddAttributeSet을 호출하지 않아도, 멤버 변수로 선언한 AttributeSet이 이미 Owner의 Subobject 트리에 들어 있어서 ASC가 그것을 스캔하는 구조예요.
3. 왜 ChildObjects에 들어가 있나?
UCLASS 안에서 이렇게 했다고 가정해봅시다:
생성자에서:
- 이렇게 하면 HealthSet은 Owner 액터의 DefaultSubobject가 됩니다.
- 언리얼 엔진은 CreateDefaultSubobject로 만든 것들을 자동으로 ChildObjects에 넣어줍니다.
- 그 상태로 BeginPlay 전에 ASC 초기화가 돌면서 ASC가 “아 이 액터에 AttributeSet 있네?” 하고 등록하는 것.
4. 정리
- ASC::InitializeComponent는 Owner 액터의 Subobject(ChildObjects)를 스캔해서 UAttributeSet들을 SpawnedAttributes에 추가한다.
- 내가 ASC->AddAttributeSet() 같은 걸 호출하지 않아도 되는 이유는, 액터 생성자에서 CreateDefaultSubobject<UAttributeSet>로 만든 AttributeSet들이 자동으로 ChildObjects에 들어가기 때문.
- 그래서 ASC가 알아서 찾아내서 등록해준다.
실제로 찾아보니 UAbilitySystemComponent::InitializeComponent 함수에서 OwnerActor의 자식들을 다 찾아서 UAttributeSet 타입 객체를 전부 등록해주고 있었다
* GetObjectsWithOuter는 1번째 인자(여기선 ASC의 Owner)의 자식들을 TArray에 담아서 가져오는 함수이다
'공부 > UE' 카테고리의 다른 글
[UE] Unreal C++ Coding Convention (0) | 2025.09.22 |
---|---|
[UE] GameplayCue와 GameplayEffect (0) | 2025.09.21 |
[UE] 각종 Ability가 GAS의 ActorInfo에 접근할 수 있는 이유 (0) | 2025.09.20 |
[UE] Notify, AbilityTask, TargetActor를 이용한 공격 판정 (0) | 2025.09.17 |
[UE] TSubclassOf vs TObjectPtr (0) | 2025.06.28 |