Unreal GAS (7) - AttributeSet 접근

wnsduf0000·2025년 12월 1일

Unreal_GAS

목록 보기
7/34
  • Component Overlap Delegate
    • 컴포넌트의 OnComponentBeginOverlap, OnComponentEndOverlap 이벤트에 바인딩해주기 위한 함수를 각각 선언 및 구현해주어야 한다.
      UFUNCTION()
      virtual void OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
      
      UFUNCTION()
      virtual void EndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
      
    • 함수의 매개변수는 바인딩 할 델리게이트를 찾아보면 알 수 있다.
      void AAuraEffectActor::BeginPlay()
      {
      	Super::BeginPlay();
      	
      	OverlapSphere->OnComponentBeginOverlap.AddDynamic(this, &AAuraEffectActor::OnOverlap);
      	OverlapSphere->OnComponentEndOverlap.AddDynamic(this, &AAuraEffectActor::EndOverlap);
      }
    • 예를 들어, OnComponentBeginOverlap의 경우,
      /** 
       *	Event called when something starts to overlaps this component, for example a player walking into a trigger.
       *	For events when objects have a blocking collision, for example a player hitting a wall, see 'Hit' events.
       *
       *	@note Both this component and the other one must have GetGenerateOverlapEvents() set to true to generate overlap events.
       *	@note When receiving an overlap from another object's movement, the directions of 'Hit.Normal' and 'Hit.ImpactNormal'
       *	will be adjusted to indicate force from the other object against this object.
       */
      		UPROPERTY(BlueprintAssignable, Category="Collision")
      		FComponentBeginOverlapSignature OnComponentBeginOverlap;
      
    • 이렇게 친절한 주석과 함께 작성된 것을 확인할 수 있다.
      이 때, FComponentBeginOverlapSignature를 확인해보면,
      ```cpp
      /** Delegate for notification of start of overlap with a specific component */
      DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SixParams( FComponentBeginOverlapSignature, UPrimitiveComponent, OnComponentBeginOverlap, UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex, bool, bFromSweep, const FHitResult &, SweepResult);
      
      // SPARSE는 자주 사용하지 않는 델리게이트의 메모리 최적화를 위해서 사용되는데,
      // 대신, 기본 델리게이트에 비해 속도가 느린 편이라 한다.
      ```
    • PrimitiveComponent.h에 작성된 델리게이트임을 확인할 수 있다.
      이 때, 매크로의 매개변수들이 상당히 많은 편인데, 매개변수 중 ‘델리게이트 이름’이 나오면,
      그 이후부터는 ‘첫 번째 매개변수의 타입’, ‘첫 번째 매개변수의 이름’, ‘두 번째 매개변수의 타입’, ‘두 번째 매개변수의 이름’ … 과 같은 형태이다.
      이를 통해 매개변수들만 복사해서 바인딩 할 함수를 작성하면 된다.
      > 블루프린트에서 OnComponentBeginOverlap, OnComponentEndOverlap 등의 오버랩 이벤트를 사용하는 경우, 컴포넌트에서 간단하게 이벤트를 생성할 수 있었다.
      > 
      > 
      > 하지만 C++ 클래스에서는 해당 델리게이트에 직접 구현한 함수를 바인딩해주어야 한다.
      > 단순히 BP의 이벤트 그래프에서 바로 함수(이벤트)를 구현하느냐,
      > 혹은 코드로 함수를 작성한 후 이어주는 작업을 따로 거치느냐의 사소한 차이이지만 이런 부분이 블루프린트의 생산성을 높여주는 것이 아닌가 싶다.
      > 
      > 불가피한 경우가 아니라면 최대한 블루프린트를 활용하는 것이 좋을 듯 하다.
      > (C++로 구현 후 블루프린트에서 호출하는 방법도 있기 때문)
      > 
  • Access Attribute Set
    • 기본적으로, AttributeSet에서 ATTRIBUTE_ACCESSORS 매크로를 통해 접근자를 구현해도,
      Get()을 통해 값을 확인하는 것은 가능하나, Set()을 통해 덮어씌우는 것은 불가능하다.
      ```cpp
      void AAuraEffectActor::OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
      {
      	if (IAbilitySystemInterface* ASCInterface = Cast<IAbilitySystemInterface>(OtherActor))
      	{
      		const UAuraAttributeSet* AuraAttributeSet = Cast<UAuraAttributeSet>(ASCInterface->GetAbilitySystemComponent()->GetAttributeSet(UAuraAttributeSet::StaticClass()));
      		// AuraAttributeSet->SetHealth(AuraAttributeSet->GetHealth() + 25.f);
      	}
      }
      ```
      • 위와 같이, 인터페이스를 통해 AttributeSet를 얻어와서 SetHealth()를 호출해도,
        AuraAttributeSet은 const이기 때문에 그 내부의 값을 덮어씌울 수 없다.
        const_cast를 통해 const를 해제해버리는 방법도 있기는 하지만, 이는 좋은 방법이 아니다.
      • GameplayEffect를 통해 AttributeSet를 변경하게 하는 것이 가장 이상적인 방법이다.
profile
저는 게임 개발자로 일하고 싶어요

0개의 댓글