LoginSignup
1
0

UE5 GameplayEffectComponentについてのメモ

Last updated at Posted at 2024-04-12

概要

UnrealEngine5 のゲームプレイエフェクトコンポーネントについてのメモ書き。
UE5.3からゲームプレイエフェクトの機能がコンポーネントごとに切り分けられています。

更新履歴

日付 内容
2024/04/12 初版

参考

以下の記事を参考にいたしました、ありがとうございます。
UE公式:UGameplayEffect
UE公式:UGameplayEffectComponent
UE公式:ゲームプレイエフェクト
GameplayEffect - その3 Expiration と Tags 編
GameplayEffect - その4 Immunity と Granted Abilities 編
UE公式:FGameplayEffectQuery
UE公式:FTagcontainerAggretator
UE公式:FGameplayTagRequirements
UE公式:FInheritedTagContainer

関連過去記事

UE4 GameplayAbility Pluginについてのメモ
UE4 GameplayTagについてのメモ

環境

Windows10
Visual Studio 2022
UnrealEngine 5.3.2

関連ソース

"Engine\Plugins\Runtime\GameplayAbilities\Source\GameplayAbilities\Public\GameplayEffect.h"
"Engine\Plugins\Runtime\GameplayAbilities\Source\GameplayAbilities\Public\GameplayEffectComponents"

GameplayEffectComponent について

5.3よりゲームプレイエフェクトの機能はコンポーネント化されました。
5.2までは以下のように使用するしないに関わらずパラメータが全て表示されていたため、機能別にコンポーネント化して整理したようです。

5.2でのゲームプレイエフェクト

GameplayEffect52.png

利用可能なゲームプレイエフェクトコンポーネント

ゲームプレイエフェクトコンポーネント 説明
UAbilitiesGameplayEffectComponent アクティブ中にゲームプレイエフェクトのターゲットに追加のゲームプレイアビリティを付与します。
UAdditionalEffectsGameplayEffectComponent 特定の条件に基づいてアクティベートを試みる追加のゲームプレイエフェクトを設定できます。
UAssetTagsGameplayEffectComponent ゲームプレイエフェクトアセットが所有するタグ。これらはアクタに転送「されません」。
UBlockAbilityTagsGameplayEffectComponent オーナーのゲームプレイエフェクトのターゲットアクタに対するゲームプレイタグに基づいて、ゲームプレイアビリティのアクティベーションをブロックすることができます。
UChanceToApplyGameplayEffectComponent ゲームプレイエフェクトが適用される確率を設定できます。
UCustomCanApplyGameplayEffectComponent CustomApplicationRequirement クラスを使用して、このゲームプレイエフェクトの適用/非適用を設定することができます。
UGameplayEffectUIData_TextOnly テキストのみを含む UIデータ。これは主に、UGameplayEffectUIData のサブクラスの例として使用されます。
UImmunityGameplayEffectComponent 耐性によって他の GameplayEffectSpec の適用をブロックします。
URemoveOtherGameplayEffectComponent 特定の条件に基づいて他のゲームプレイエフェクトを削除することができます。
UTargetTagRequirementsGameplayEffectComponent この GE を適用したり、実行を継続したりする必要がある場合にターゲット (ゲームプレイエフェクトのオーナー) に必要なタグ要件を指定します。
UTargetTagsGameplayEffectComponent ゲームプレイエフェクトのターゲット (「オーナー」と言う場合もあります) にタグを付与します。

UAbilitiesGameplayEffectComponent

追加のゲームプレイアビリティを付与します。

設定パラメータ 説明
Ability 発動させるゲームプレイアビリティ
Level アビリティレベル
Removal Policy 指定アビリティを終了させる条件を指定

AbilitiesGEComponent.png

動作をすると UGameplayAbility::OnAvatarSet が呼ばれるのでここでアビリティをパッシブ発動をするようにオーバーライドをしてのコード追加が必要です。
以下C++コード例。

.h
UCLASS()
class SAMPLE00_API UPGA_Test : public UPlayerGameplayAbility
{
	GENERATED_BODY()
// ..省略..

 	// アバター設定or切り替え時の処理
	virtual void OnAvatarSet(const FGameplayAbilityActorInfo* _ActorInfo, const FGameplayAbilitySpec& _Spec) override;
};
.cpp
void UPGA_Test::OnAvatarSet(
	const FGameplayAbilityActorInfo* _ActorInfo,
	const FGameplayAbilitySpec& _Spec
	)
{
	Super::OnAvatarSet(_ActorInfo, _Spec);

	// GEからのパッシブ発動
	if (_Spec.GameplayEffectHandle.WasSuccessfullyApplied()) {
		_ActorInfo->AbilitySystemComponent->TryActivateAbility(_Spec.Handle, false);
	}
}

UAdditionalEffectsGameplayEffectComponent

特定条件にて追加でゲームプレイエフェクトを付与します。

設定パラメータ 説明
On Application Gameplay Effects 適用時に追加で適用される他のGE
On Complete Always 終了方法に関係なく完了したときに適用されるGE
On Complete Normal 持続時間によって自然に切れたときに適用されるGE
On Complete Permatruely 途中で期限切れになった場合に適用するGE (強制削除、タグのクリアなど)

AdditionalEffectGEComponent.png

UAssetTagsGameplayEffectComponent

ゲームプレイエフェクトが所有するゲームプレイタグを指定します。

設定パラメータ 説明
CombinedTags 追加するタグから削除するタグを除いたタグ(編集不可)
Added 追加するタグ
Removed 削除するタグ

AssetTagsGEComponent.png

ゲームプレイ適用時コールバックなどで取り出して別途処理するようなケースで使います。
以下コード例。

// ゲームプレイエフェクト適用時コールバック
void AAppCharacterBase::OnActiveGameplayEffectAddedCallback(
	UAbilitySystemComponent* _TargetASC,
	const FGameplayEffectSpec& _SpecApplied,
	FActiveGameplayEffectHandle _ActiveHandle
)
{
	// アセットタグ
	FGameplayTagContainer _SpecAssetTags;
	_SpecApplied.GetAllAssetTags(_SpecAssetTags);
 	// タグの表示
	UE_LOG(LogTemp, Log, TEXT("%s"), *_SpecAssetTags.ToString());
}

UBlockAbilityTagsGameplayEffectComponent

アビリティのブロックタグの追加/削除ができます。

設定パラメータ 説明
CombinedTags 追加するタグから削除するタグを除いたタグ(編集不可)
Added 追加するアビリティブロックタグ
Removed 削除するアビリティブロックタグ

BlockAbilityTagGEComponent.png

ゲームプレイアビリティが持つ BlockAbilitiesWithTag とは別にゲームプレイエフェクトの適用中にブロックしたいアビリティをタグで設定できます。

UChanceToApplyGameplayEffectComponent

ゲームプレイエフェクトの適用確率[0.0 - 1.0]を設定できます。

ChanceToApplyGEComponent.png

UCustomCanApplyGameplayEffectComponent

ゲームプレイエフェクトの適用/非適用を CustomApplicationRequirementクラスを使っての設定ができます。

CustomCanApplyGEComponent.png

単純な適用確率ではなく、ゲーム内キャラクター等のパラメータなどから適用の可否が決まるようなケースで使用できます。
以下カスタムクラスのコード例。

GameplayCAR_Example.h
#pragma once

#include "CoreMinimal.h"
#include "GameplayEffectCustomApplicationRequirement.h"
#include "GameplayCAR_Example.generated.h"

UCLASS()
class SAMPLE00_API UGameplayCAR_Example : public UGameplayEffectCustomApplicationRequirement
{
	GENERATED_BODY()
	
public:
	// ゲームプレイエフェクトを適用するかどうかを返す
	bool CanApplyGameplayEffect_Implementation(const UGameplayEffect* _GameplayEffect, const FGameplayEffectSpec& _Spec, UAbilitySystemComponent* _ASC) const override;
};
GameplayCAR_Example.cpp
// ゲームプレイエフェクトを適用するかどうかを返す
bool UGameplayCAR_Example::CanApplyGameplayEffect_Implementation(const UGameplayEffect* _GameplayEffect, const FGameplayEffectSpec& _Spec, UAbilitySystemComponent* _ASC) const
{
	const auto _EffectCauser = _Spec.GetContext().GetEffectCauser();

	// キャラクターを取得
	auto _Character = Cast<ACharacter>(_EffectCauser);
	// 何らかのパラメータから適用するかを決定する
	auto _Value = _Character->GetValue();
	if( _Value < 0.0f){
		return(true);
	}
	 else{
		float _Prob = Value; 
		if( (_Prob > 1.f - SMALL_NUMBER) || (FMath::FRand() < _Prob) ){
			return(true);
		}
		else{
			return(false);
		}
	}
}

UGameplayEffectUIData_TextOnly

テキストのみ。特に何もしません。

GamepleyEffectUIDataTextOnly.png

UImmunityGameplayEffectComponent

条件に基づいて他のゲームプレイエフェクトの適用を妨げます。

設定パラメータ 説明
Owning Tag Query ここに設定されたアセットタグ/付与されたタグと一致していた場合適用されない
Effect Tag Query ここに設定されたアセットタグと一致していた場合適用されない
SourceSpec Tag Query GamepleyEffectSepc作成時にキャプチャされたSpecタグと一致していた場合適用されない
SourceAggregate Tag Query GamepleyEffectSepc作成時にキャプチャされたAggregatedタグと一致した場合適用されない
Modifying Attribute ここに設定されたアトリビュートを変更するGEは適用されない
Effect Souce ここに設定されたオブジェクトが発生源のGEは適用されない
Effect Definition ここに設定されたGEは適用されない

ImmunityGEComponent.png

URemoveOtherGameplayEffectComponent

他のゲームプレイエフェクトを削除します。

RemoveOtherGEComponent.png

UTargetTagRequirementsGameplayEffectComponent

ゲームプレイエフェクトの適用に必要なタグを指定します。

設定パラメータ 説明
ApplicationTagRequirements このGameplayEffectを対象に適用するためのタグの条件。これは適用時に合否が決まる。失敗した場合、このGEは適用されない。
OngoingTagRequirements GameplayEffectが適用中に、これらのタグ要件をGameplayEffectが「オン」か「オフ」かを判断するために使用します。GE自体は解除されず、一時的なオン/オフのみ。
RemovalTagRequirements タグの条件を満たすとこのGameplayEffectが解除される。

TargetTagRequirementsGEComponent.png

UTargetTagsGameplayEffectComponent

ターゲットにタグを付与します。

設定パラメータ 説明
Combined Tags 継承したタグと追加したタグから削除したタグを除いたタグ
Added 親のタグに加えて持つタグ
Removed 親が持っていた場合は削除する必要があるタグ

TargetTagsGEComponent.png

設定した付与タグは FGameplayEffectSpec::GetAllGrantedTags で取得できるので、ゲームプレイエフェクト適用カスタムクラスUGameplayEffectCustomApplicationRequirementなどから取得して判定に使うことができます。

GameplayEffectSpecから取得
const FGameplayEffectSpec& _Spec;

FGameplayTagContainer _Tags;
_Spec.GetAllGrantedTags(_Tags);

UE_LOG(LogTemp, Log, TEXT("%s"), *_Tags.ToString());

また付与されたタグは AbilitySystemComponent::GetOwnedGameplayTags で取得することもできます。
以下コード例。

所有しているゲームプレイタグの表示
	// キャラクターのアビリティコンポーネント
	auto _TargetASC = _TargetCharacter->GetAbilitySystemComponent();

	FGameplayTagContainer _Tags;
	_TargetASC->GetOwnedGameplayTags(_Tags);
 	
	// ゲームプレイタグの表示
	UE_LOG(LogTemp, Log, TEXT("%s"), *_Tags.ToString());

GameplayEffectComponentを作成について

UGameplayEffectComponent を継承してクラスを作成することで追加可能です。
必要なメソッドを継承して処理を書く必要があります。
以下テンプレートコード例。

TestGameplayEffectComponent.h
#pragma once

#include "GameplayEffectComponent.h"
#include "GameplayEffectTypes.h"
#include "TestGameplayEffectComponent.generated.h"


UCLASS()
class SAMPLE00_API UTestGameplayEffect : public UGameplayEffectComponent
{
	GENERATED_BODY()
	
public:
	// 適用可能かどうかを返す
	virtual bool CanGameplayEffectApply(const FActiveGameplayEffectsContainer& _ActiveGEContainer, const FGameplayEffectSpec& _GESpec) const override;

	// ゲームプレイエフェクトがコンテナに追加されるとき(期間)に呼ばれる処理
	virtual bool OnActiveGameplayEffectAdded(FActiveGameplayEffectsContainer& _ActiveGEContainer, FActiveGameplayEffect& _ActiveGE) const override;

	// ゲームプレイエフェクトが実行されるとき(即時or期間の周期ごと)に呼ばれる処理
	virtual void OnGameplayEffectExecuted(FActiveGameplayEffectsContainer& _ActiveGEContainer, FGameplayEffectSpec& _GESpec, FPredictionKey& _PredictionKey) const;

	// ゲームプレイエフェクトが最初に適用されるときに呼ばれる処理
	virtual void OnGameplayEffectApplied(FActiveGameplayEffectsContainer& _ActiveGEContainer, FGameplayEffectSpec& _GESpec, FPredictionKey& _PredictionKey) const;

	// ゲームプレイエフェクトが変更されたときに呼ばれる処理
	virtual void OnGameplayEffectChanged() const;

protected:
	// ゲームプレイエフェクトが削除されるときに呼ばれる処理
	virtual void OnActiveGameplayEffectRemoved(const FGameplayEffectRemovalInfo& _RemovalInfo, FActiveGameplayEffectsContainer* _ActiveGEContainer) const;

};
TestGameplayEffectComponent.cpp
#include "./TestGameplayEffectComponent.h"

// 適用可能かどうかを返す
bool UTestGameplayEffect::CanGameplayEffectApply(const FActiveGameplayEffectsContainer& _ActiveGEContainer, const FGameplayEffectSpec& _GESpec) const
{
	return true;
}

// ゲームプレイエフェクトがコンテナに追加されるとき(期間)に呼ばれる処理
bool UTestGameplayEffect::OnActiveGameplayEffectAdded(FActiveGameplayEffectsContainer& _ActiveGEContainer, FActiveGameplayEffect& _ActiveGE) const
{
	UAbilitySystemComponent* _ASC = _ActiveGEContainer.Owner;
	if (!ensure(_ASC)){
		return false;
	}
	
	// We don't allow prediction of expiration (on removed) effects
	// 有効期限(削除時)の影響を予測することは許可されていません
	if (_ActiveGEContainer.IsNetAuthority()){
		// When this ActiveGE gets removed, so will our events so no need to unbind this.
		// この ActiveGE が削除されると、イベントも削除されるため、これをバインド解除する必要はありません。
		_ActiveGE.EventSet.OnEffectRemoved.AddUObject(this, &UTestGameplayEffect::OnActiveGameplayEffectRemoved, &_ActiveGEContainer);
	}

	
	return true;
}

// ゲームプレイエフェクトが実行されるとき(即時or期間の周期ごと)に呼ばれる処理
void UTestGameplayEffect::OnGameplayEffectExecuted(FActiveGameplayEffectsContainer& _ActiveGEContainer, FGameplayEffectSpec& _GESpec, FPredictionKey& _PredictionKey) const
{
}

// ゲームプレイエフェクトが最初に適用されるときに呼ばれる処理
void UTestGameplayEffect::OnGameplayEffectApplied(FActiveGameplayEffectsContainer& _ActiveGEContainer, FGameplayEffectSpec& _GESpec, FPredictionKey& _PredictionKey) const
{
}

// ゲームプレイエフェクトが変更されたときに呼ばれる処理
void UTestGameplayEffect::OnGameplayEffectChanged() const
{
}

// ゲームプレイエフェクトが削除されるときに呼ばれる処理
void UTestGameplayEffect::OnActiveGameplayEffectRemoved(const FGameplayEffectRemovalInfo& _RemovalInfo, FActiveGameplayEffectsContainer* _ActiveGEContainer) const
{
	FScopedActiveGameplayEffectLock ActiveScopeLock(*_ActiveGEContainer);

	const FActiveGameplayEffect* ActiveGE = _RemovalInfo.ActiveEffect;
	if (!ensure(ActiveGE))
	{
		UE_LOG(LogTemp, Error, TEXT("FGameplayEffectRemovalInfo::ActiveEffect が OnActiveGameplayEffectRemoved に設定されていませんでした"));
		return;
	}

	UAbilitySystemComponent* ASC = _ActiveGEContainer->Owner;
	if (!ensure(IsValid(ASC)))
	{
		UE_LOG(LogTemp, Error, TEXT("ActiveGEContainer が OnActiveGameplayEffectRemoved で無効でした"));
		return;
	}

}

まとめ

ゲームプレイエフェクトを調べているとゲームプレイタグの種類がいろいろあってややこしいですね。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0