いつもお世話になっております。
本日はGameplayAbilitySystemのUGameplayEffectクラスのプロパティStackingTypeについて質問をさせて下さい。
UE5.7から UGameplayEffectクラスのStackingTypeは直接のアクセスが非推奨になっております。
それに伴い、Get/Set関数とも用意されておりますが、Set関数のほうはエディタのみとなっております。
UE_DEPRECATED(5.7, "Stacking Type will be made private, Please use GetStackingType.")
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Stacking)
EGameplayEffectStackingType StackingType;
/** return the stacking type defined from the data asset */
EGameplayEffectStackingType GetStackingType() const;
#if WITH_EDITOR
/** Set stacking type */
void SetStackingType(EGameplayEffectStackingType InType);
#endif
スタック設定があるゲームプレイエフェクトをアセットを作らず直接コードで生成した場合、SetStackingType() がエディタのみのため問題があります。
UCLASS()
class SAMPLE_API UGameplayEffect_Test : public UGameplayEffect
{
GENERATED_BODY()
public:
UGameplayEffect_Test(){
DurationPolicy = EGameplayEffectDurationType::Infinite;
// スタック設定
StackingType = EGameplayEffectStackingType::AggregateByTarget; // SetStackingType(EGameplayEffectStackingType::AggregateByTarget);
StackLimitCount = 2; // 最大スタック数
// ターゲットタグコンポーネントを追加
UTargetTagsGameplayEffectComponent* _Component = CreateDefaultSubobject<UTargetTagsGameplayEffectComponent>(TEXT("GEComponent0"));
// タグ付与
FInheritedTagContainer _Tags;
_Tags.AddTag(FGameplayTag::RequestGameplayTag("GameplayEffect.Test"));
_Component->SetAndApplyTargetTagChanges(_Tags);
GEComponents.Add(_Component);
}
};
アトリビュートを変更する/GameplayTagを付与する程度のGameplayEffectは直接コードで作成していましたが、そもそもこのような作り方自体が非推奨なのでしょうか?
また、ゲット関数のほうも UE_API がないため別モジュールからアクセスできないようです。
よろしくお願いいたします。
[Attachment Removed]
お世話になっております。
UGameplayEffectのコメントや公式ドキュメントにも書かれておりますように、
/**
* UGameplayEffect
* The GameplayEffect definition. This is the data asset defined in the editor that drives everything.
* This is only blueprintable to allow for templating gameplay effects. Gameplay effects should NOT contain blueprint graphs.
*/
UCLASS(Blueprintable, PrioritizeCategories="Status Duration GameplayEffect GameplayCues Stacking", meta = (ShortTooltip = "A GameplayEffect modifies attributes and tags."), MinimalAPI)
class UGameplayEffect : public UObject, public IGameplayTagAssetInterface
GameplayEffectはエディタ上で定義される「アセット」で、ランタイム時の変更を想定しておりません。この関係で Setter の使用がエディタに限定されております。一方、Getter の UE_API の欠落は、 CL48307033で追加されましたので、こちらをバックポートしていただく(単にUE_APIを追記する)ことで別モジュールからアクセスが可能となります。
> アトリビュートを変更する/GameplayTagを付与する程度のGameplayEffectは直接コードで作成していましたが、そもそもこのような作り方自体が非推奨なのでしょうか?
ランタイムでのGameplayEffectの作成は「ハック」的扱い(“There are small exceptions to this where hacks are done to _create_ a GE at runtime”)とされており、推奨か非推奨かで申し上げますと、非推奨であると考えます。ただし、ご提示いただいたコード(UGameplayEffect_Testのケース)であれば、CDO初期化ですので、リスクは低いといえます。 こうした前提をご理解の上、 PRAGMA_DISABLE_DEPRECATION_WARNINGS で挟んで警告を抑制すれば、UE5.6以前の作り方を続けていただくことは可能かと存じます。
以上、よろしくお願いいたします。
[Attachment Removed]
ご返答ありがとうございます。
StackingTypeの件について了解いたしました。
現在GameplayEffectのC++での作成での値の設定はコンストラクタ時の初期化限定で使用しております。
アトリビュートの数が多い場合、値の変更だけのGameplayEffectアセットだけでもかなりの数になってしまうため単純なものはC++で作成しており、実行時にコンポーネント構成などを変えることはないためリスクはほぼないと判断しております。
>ただし、ご提示いただいたコード(UGameplayEffect_Testのケース)であれば、CDO初期化ですので、リスクは低いといえます。
>こうした前提をご理解の上、 PRAGMA_DISABLE_DEPRECATION_WARNINGS で挟んで警告を抑制すれば、UE5.6以前の作り方を続けていただくことは可能かと存じます。
>
ゲット関数のほうは他モジュールからのアクセスの問題が解消すればいいためこちらを使用いたします。
セット関数のほうはエディタ限定になっているためこれはつくりを改めることにいたします。
また何か質問がありましたらお聞きしたいと思います。
ありがとうございました。
[Attachment Removed]
回答のご確認をありがとうございます。
それでは本件は対応済みとしてCloseさせていただきます。
またご不明点など出てきましたら、お気軽にEPSでお問い合わせください。
以上、よろしくお願いいたします。
[Attachment Removed]