#pragma once
#include "ActionRPG.h"
#include "Abilities/GameplayAbility.h"
#include "Abilities/RPGAbilityTypes.h"
#include "RPGGameplayAbility.generated.h"
/**
* Subclass of ability blueprint type with game-specific data
* This class uses GameplayEffectContainers to allow easier execution of gameplay effects based on a triggering tag
* Most games will need to implement a subclass to support their game-specific code
*/
UCLASS()
class ACTIONRPG_API URPGGameplayAbility : public UGameplayAbility
{
GENERATED_BODY()
public:
// Constructor and overrides
URPGGameplayAbility();
/**
* Map of gameplay tags to gameplay effect containers
* 游戏标签到游戏效果容器的map
*/
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = GameplayEffects)
TMap<FGameplayTag, FRPGGameplayEffectContainer> EffectContainerMap;
/**
* @brief Make gameplay effect container spec to be applied later, using the passed in container
* 根据给定的GE容器创建GE容器的规范
* @param Container 给定的容器,包含一组GE
* @param EventData 传递的游戏事件的数据
*/
UFUNCTION(BlueprintCallable, Category = Ability, meta=(AutoCreateRefTerm = "EventData"))
virtual FRPGGameplayEffectContainerSpec MakeEffectContainerSpecFromContainer(const FRPGGameplayEffectContainer& Container, const FGameplayEventData& EventData, int32 OverrideGameplayLevel = -1);
/**
* @brief Search for and make a gameplay effect container spec to be applied later, from the EffectContainerMap
* 从EffectContainerMap中搜索并制作稍后应用的游戏效果容器规范
*/
UFUNCTION(BlueprintCallable, Category = Ability, meta = (AutoCreateRefTerm = "EventData"))
virtual FRPGGameplayEffectContainerSpec MakeEffectContainerSpec(FGameplayTag ContainerTag, const FGameplayEventData& EventData, int32 OverrideGameplayLevel = -1);
/**
* @brief Applies a gameplay effect container spec that was previously created
* 应用先前创建的游戏效果容器规范
*/
UFUNCTION(BlueprintCallable, Category = Ability)
virtual TArray<FActiveGameplayEffectHandle> ApplyEffectContainerSpec(const FRPGGameplayEffectContainerSpec& ContainerSpec);
/**
* @brief Applies a gameplay effect container, by creating and then applying the spec
* 通过创建并应用规范,应用游戏效果容器
*/
UFUNCTION(BlueprintCallable, Category = Ability, meta = (AutoCreateRefTerm = "EventData"))
virtual TArray<FActiveGameplayEffectHandle> ApplyEffectContainer(FGameplayTag ContainerTag, const FGameplayEventData& EventData, int32 OverrideGameplayLevel = -1);
};
#include "Abilities/RPGGameplayAbility.h"
#include "Abilities/RPGAbilitySystemComponent.h"
#include "Abilities/RPGTargetType.h"
#include "RPGCharacterBase.h"
URPGGameplayAbility::URPGGameplayAbility() {}
FRPGGameplayEffectContainerSpec URPGGameplayAbility::MakeEffectContainerSpecFromContainer(const FRPGGameplayEffectContainer& Container,
const FGameplayEventData& EventData,
int32 OverrideGameplayLevel) {
// First figure out our actor info
FRPGGameplayEffectContainerSpec ReturnSpec;
AActor* OwningActor = GetOwningActorFromActorInfo();
ARPGCharacterBase* OwningCharacter = Cast<ARPGCharacterBase>(OwningActor);
URPGAbilitySystemComponent* OwningASC = URPGAbilitySystemComponent::GetAbilitySystemComponentFromActor(OwningActor);
if (OwningASC) {
// If we have a target type, run the targeting logic. This is optional, targets can be added later
// // 如果我们有一个目标类型,那么运行目标逻辑。这是可选的,以后可以添加目标
if (Container.TargetType.Get()) {
TArray<FHitResult> HitResults;
TArray<AActor*> TargetActors;
const URPGTargetType* TargetTypeCDO = Container.TargetType.GetDefaultObject();
AActor* AvatarActor = GetAvatarActorFromActorInfo();
TargetTypeCDO->GetTargets(OwningCharacter, AvatarActor, EventData, HitResults, TargetActors);
ReturnSpec.AddTargets(HitResults, TargetActors);
}
// If we don't have an override level, use the default on the ability itself
// 如果我们没有覆盖级别,请对功能本身使用默认级别
if (OverrideGameplayLevel == INDEX_NONE) {
OverrideGameplayLevel = OverrideGameplayLevel = this->GetAbilityLevel(); //OwningASC->GetDefaultAbilityLevel();
}
// Build GameplayEffectSpecs for each applied effect
// 为每个应用的效果构建GESpecs
for (const TSubclassOf<UGameplayEffect>& EffectClass : Container.TargetGameplayEffectClasses)
{
ReturnSpec.TargetGameplayEffectSpecs.Add(MakeOutgoingGameplayEffectSpec(EffectClass, OverrideGameplayLevel));
}
}
return ReturnSpec;
}
FRPGGameplayEffectContainerSpec URPGGameplayAbility::MakeEffectContainerSpec(FGameplayTag ContainerTag,
const FGameplayEventData& EventData,
int32 OverrideGameplayLevel) {
FRPGGameplayEffectContainer* FoundContainer = EffectContainerMap.Find(ContainerTag);
if (FoundContainer)
{
return MakeEffectContainerSpecFromContainer(*FoundContainer, EventData, OverrideGameplayLevel);
}
return FRPGGameplayEffectContainerSpec();
}
TArray<FActiveGameplayEffectHandle> URPGGameplayAbility::ApplyEffectContainerSpec(const FRPGGameplayEffectContainerSpec& ContainerSpec) {
TArray<FActiveGameplayEffectHandle> AllEffects;
// Iterate list of effect specs and apply them to their target data
// 迭代效果规格列表,并将其应用于目标数据
for (const FGameplayEffectSpecHandle& SpecHandle : ContainerSpec.TargetGameplayEffectSpecs) {
AllEffects.Append(K2_ApplyGameplayEffectSpecToTarget(SpecHandle, ContainerSpec.TargetData));
}
return AllEffects;
}
TArray<FActiveGameplayEffectHandle> URPGGameplayAbility::ApplyEffectContainer(FGameplayTag ContainerTag,
const FGameplayEventData& EventData,
int32 OverrideGameplayLevel) {
FRPGGameplayEffectContainerSpec Spec = MakeEffectContainerSpec(ContainerTag, EventData, OverrideGameplayLevel);
return ApplyEffectContainerSpec(Spec);
}
标签:include,const,OverrideGameplayLevel,RPGGameAbility,ActionRPG,EventData,FRPGGamep From: https://www.cnblogs.com/ikun-proto/p/17417237.html