Unreal GAS (11) - GameplayEffect 적용 (ApplyGameplayEffectSpecToSelf)

wnsduf0000·2025년 12월 1일

Unreal_GAS

목록 보기
11/34
  • Apply GameplayEffect (ApplyGameplayEffectSpecToSelf)
    • AuraEffectActor를 변경하여, 세부 사항은 블루프린트를 이용하여 구현할 수 있도록 하는 기본 클래스의 역할을 하도록 만드려고 함.

    • 기존의 AttributeSet에 직접 접근하여 const_cast를 통해 변경한 것과 다르게,
      GameplayEffect를 이용하여 Attribute를 변경하도록 만들 것임.

      class UGameplayEffect;
      
      UCLASS()
      class AURA_API AAuraEffectActor : public AActor
      {
      	GENERATED_BODY()
      	
      public:	
      	AAuraEffectActor();
      
      protected:
      	virtual void BeginPlay() override;
      
      	UFUNCTION(BlueprintCallable)
      	void ApplyEffectToTarget(AActor* Target, TSubclassOf<UGameplayEffect> GameplayEffectClass);
      
      	UPROPERTY(EditAnywhere, Category = "Applied Effect")
      	TSubclassOf<UGameplayEffect> InstantGameplayEffectClass;
      };
    • InstantGameplayEffectClass에 GameplayEffect를 생성하여 등록하고,
      ApplyEffectToTarget()을 통해 Target에게 GameplayEffect를 적용할 것임.

      // AAuraEffectActor.cpp
      void AAuraEffectActor::ApplyEffectToTarget(AActor* Target, TSubclassOf<UGameplayEffect> GameplayEffectClass)
      {
      	UAbilitySystemComponent* TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(Target);
      	if (TargetASC == nullptr) return; 
      
      	check(GameplayEffectClass);
      	FGameplayEffectContextHandle EffectContextHandle = TargetASC->MakeEffectContext();
      	EffectContextHandle.AddSourceObject(this);
      	
      	const FGameplayEffectSpecHandle EffectSpecHandle = TargetASC->MakeOutgoingSpec(GameplayEffectClass, 1.f, EffectContextHandle);
      	TargetASC->ApplyGameplayEffectSpecToSelf(*EffectSpecHandle.Data.Get());
      }
    • GameplayEffect를 적용하기 함수는 이미 AbilitySystemComponent에 거의 준비되어 있음.
      여러 가지 방법이 있지만, 우선은 ApplyGameplayEffectSpecToSelf()를 이용하여 GameplayEffect를 Target에게 적용시켜 볼 것임.

    1. UAbilitySystemBlueprintLibrary에서 제공하는 GetAbilitySystemComponent() 함수를 이용하면, 
    해당 인터페이스 캐스팅 및 만약 인터페이스를 상속하지 않을 경우 FindComponentByClass()를 통한 컴포넌트 탐색까지 실시하여
    AbilitySystemComponent를 반환하도록 시도해주는 기능을 편리하게 사용할 수 있음.
    "AbilitySystemBlueprintLibrary.h” 를 include 해주어야 사용할 수 있음.
        - UKismetSystemLibrary, UKismetMathLibrary, UGameplayStatics의 함수를 쓰기 위해 
        Kismet 폴더 내에서 필요한 헤더를 include 하는 것처럼 미리 외워두면 좋음
        - 다만, AbilitySystemComponent 소유 액터들이 모두 반드시 IAbilitySystemInterface를 상속하도록 할 것이 확실한 경우는
        반드시 UAbilitySystemBlueprintLibrary의 함수를 이용할 필요는 없음. 프로젝트 설계 방향에 따라 결정하면 됨.
        
    2. ApplyGameplayEffectSpecToSelf()는 매개변수로 const FGameplayEffectSpec&와 FPredictionKey를 받음.
    (FPredictionKey는 일단 기본값을 그대로 사용함)
    
    3. FGameplayEffectSpec은 AbilitySystemComponent의 MakeOutGoingSpec()을 통해 반환되는 FGameplayEffectSpecHandle을 통해 얻을 수 있음.
        - FGameplayEffectSpecHandle은 FGameplayEffectSpec을 생성하고 사용할 수 있게 해주는 구조체이기 때문에, 
        FGameplayEffectSpec을 멤버변수로 지니고 있음.
        
    4. MakeOutGoingSpec()의 매개변수로는 TSubclassOf<UGameplayEffect>, float level, FGameplayEffectContextHandle이 필요함.
        - UGameplayEffect 클래스는 사용할 GameplayEffect 클래스를 그대로 넣어주면 됨.
        - level의 경우 GameplayEffect들이 다양해짐에 따라 서로 다른 값을 사용하지만, 일단은 임시로 1을 사용하도록 함.
        - 다만, FGameplayEffectContextHandle의 경우는 생성해서 넘겨받아야 함.
        
    5. FGameplayEffectContextHandle 또한 AbilitySystemComponent의 MakeEffectContext()를 통해 생성할 수 있음
    - FGameplayEffectContextHandle은 FGameplayEffectSpecHandle과 비슷한 맥락으로, FGameplayEffectContext를 다루는 구조체이며,
    FGameplayEffectContext는 이 GameplayEffect의 말 그대로의 ‘맥락’에 대한 정보를 담기 위한 구조체라고 보면 됨.
        - 예를 들어, 이 GameplayEffect가 누구에 의해 생성되었으며, 누가 영향을 받는 지 등.
        FEffectContextHandle에 AddSourceObject()로 this를 넘겨주면 됨.
        (AuraEffectActor 자신이 영향을 주는 액터이기 때문)
profile
저는 게임 개발자로 일하고 싶어요

0개의 댓글