Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

能力系统

  • 插件未开源

作者信息

Copyright FirePlume, All Rights Reserved.

Email: fireplume@126.com
GitHub: FirePlume126
Bilibili: 火羽FP
YouTube: FirePlume126

返回目录

FPAbilitySystem

FPAbilitySystem

能力属性管理框架,此模块基于GAS,输入基于FPInput

  • 此模块的主要类
类名 描述
FPAbilityManagerComponent 能力管理组件,添加给APawn
服务器通过能力属性配置服务器存档初始化属性和能力,本地通过能力属性配置自动绑定按键输入,也可以通过蓝图API手动添加激活能力和绑定输入
FPAttributeSetBase 属性集基类,继承此类创建自己的属性集
FPAbilityBase 能力基类,能力添加到能力模型统一管理
FPAbilityComboBase 运行能力组合的能力基类,继承此类只需要完成基础设置就可以使用能力组合
FPAbilityBTTask_RunAbility 运行能力模型中能力的行为树任务,详见AI激活能力
FPAbilitySTTask_RunAbility 运行能力模型中能力的状态树任务,详见AI激活能力

FPAbilitySystem_Framework

  • FPAbilitySystem项目设置
属性 数据类型 描述
AttributeConfig TSoftObjectPtr<UDataTable> 能力属性配置
AbilityMapTable TSoftObjectPtr<UFPAbilityMapTable> 能力映射表,管理所有能力映射,插件已设置好,不建议修改
CooldownGameplayEffectClass TSoftClassPtr<UGameplayEffect> 冷却GE类,所有能力都使用此GE,插件已设置好,不建议修改
CostGameplayEffectClass TSoftClassPtr<UGameplayEffect> 消耗GE类,所有能力都使用此GE,插件已设置好,不建议修改
DamageGameplayEffectClass TSoftClassPtr<UGameplayEffect> 伤害GE类,所有能力都使用此GE,根据自己的需求更换计算逻辑
FullStateGameplayEffectClass TSoftClassPtr<UGameplayEffect> 状态一直全满GE类,控制台输入"FP_FullState (bool)"启动GE,根据自己的需求添加

FPAbilitySystemSettings

  • 能力属性配置

使用建议能力属性配置数据表格的每一行对应一个骨骼或者角色

1、继承FFPAbilityAttributeConfig创建能力属性配置的数据表格

// 能力属性配置
USTRUCT(BlueprintType)
struct FFPAbilityAttributeConfig : public FTableRowBase
{
	GENERATED_BODY()

public:

	// 默认属性
	UPROPERTY(EditDefaultsOnly)
	TMap<FGameplayAttribute, FGameplayEffectModifierMagnitude> DefaultAttributes;

	// 默认应用的效果
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	TArray<TSubclassOf<UGameplayEffect>> DefaultEffects;

#if WITH_EDITORONLY_DATA

	// 能力模型,仅用于映射UFPAbilityMapTable::AbilityMaps,索引越大优先级越高(能力标签相同时,仅映射优先级最高的能力模型能力)
	UPROPERTY(EditDefaultsOnly, meta = (RequiredAssetDataTags = "RowStructure=/Script/FPAbilitySystem.FPAbilityData"), Category = "Ability")
	TArray<TSoftObjectPtr<UDataTable>> AbilityModels;
#endif

	// 能力的确认取消输入
	UPROPERTY(EditDefaultsOnly, Category = "Ability")
	FFPAbilityInput ConfirmCancelInput;

	// 主动能力,FFPAbilityInput不为空时绑定输入,<能力标签,能力输入>
	UPROPERTY(EditDefaultsOnly, meta = (Categories = "FPAbility.Ability.Active"), Category = "Ability")
	TMap<FGameplayTag, FFPAbilityInput> ActiveAbilities;

	// 被动能力标签容器
	UPROPERTY(EditDefaultsOnly, meta = (Categories = "FPAbility.Ability.Passive"), Category = "Ability")
	FGameplayTagContainer PassiveAbilities;
};

2、给APawn添加UFPAbilityManagerComponent组件,然后通过能力属性配置行命名选择对应的配置,此APawn会根据选择的配置进行初始化

FPAbilitySystem_AbilityManager

3、服务器调用UFPAbilityManagerComponent::InitAbilityManager()初始化组件。
绑定UFPAbilityManagerComponent::OnReceivedDamage可以播放受击的动画和声音,也可以显示伤害数字;
绑定UFPAbilityManagerComponent::OnDied执行死亡逻辑

// 初始化能力管理组件,建议在APawn::PossessedBy()中调用
// @param InAbilitySystemComp 能力管理组件管理的能力系统组件
// @param NewServerData 服务器保存的数据
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "FPAbility")
bool InitAbilityManager(UAbilitySystemComponent* InAbilitySystemComp, const FFPAbilityServerData& NewServerData);

// 重置能力管理组件
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "FPAbility")
void ResetAbilityManager();

// 接收伤害委托,源和目标的服务器和客户端都可接收到委托。攻击拥有"FPAbility.Damage.Type.NotHitReact"标签将不执行此委托,可以播放受击的动画和声音,也可以显示伤害数字
UPROPERTY(BlueprintAssignable, Category = "FPAbility")
FFPAbilityReceivedDamageDelegate OnReceivedDamage;

// 死亡委托,绑定委托后执行死亡动画或者布娃娃,如果使用FPOnlineSystem调用UFPOnlineFunctionLibrary::PawnDied()重生
UPROPERTY(BlueprintAssignable, BlueprintAuthorityOnly, Category = "FPAbility")
FFPAbilityDiedDelegate OnDied;
// 能力服务器数据
USTRUCT(BlueprintType)
struct FFPAbilityServerData
{
	GENERATED_BODY()

public:

	// 属性
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	TMap<FGameplayAttribute, float> Attributes;

	// 是否有效
	FORCEINLINE bool IsValid() const
	{
		return !Attributes.IsEmpty();
	}
};

// 接收伤害数据
USTRUCT(BlueprintType)
struct FFPAbilityReceivedDamageData
{
	GENERATED_BODY()

public:

	// 伤害来源AvatarActor
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	TObjectPtr<AActor> SourceAvatarActor;

	// 伤害目标AvatarActor
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	TObjectPtr<AActor> TargetAvatarActor;

	// 命中结果
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	FHitResult HitResult;

	// 伤害数值
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (ClampMin = 0))
	float DamageValue = 0.0f;

	// 伤害类型标签
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (Categories = "FPAbility.Damage.Type"))
	FGameplayTagContainer DamageTypeTags;
};

4、客户端调用UFPAbilityManagerComponent::InitAbilityInput(),通过读取能力属性配置ConfirmCancelInputActiveAbilities自动绑定能力输入,死亡时移除所有能力输入, 也可以通过函数UFPAbilityManagerComponent的函数手动绑定输入

// UFPAbilityManagerComponent的函数↓↓↓

// 初始化能力输入,通过AttributeConfigPtr绑定输入,建议在APawn::SetupPlayerInputComponent中调用
UFUNCTION(BlueprintCallable, Category = "FPAbility")
void InitAbilityInput();

// 移除所有能力输入
UFUNCTION(BlueprintCallable, Category = "FPAbility")
void RemoveAllAbilityInput();

// 绑定能力输入(仅支持本地调用),按键被使用时会自动解绑之前的能力
bool BindAbilityInput(const FGameplayTag& InAbilityTag, const FFPAbilityInput& InAbilityInput);

// 解除此按键绑定的能力(仅支持本地调用)
UFUNCTION(BlueprintCallable, Category = "FPAbility")
void RemoveAbilityInput(const FFPAbilityInput& InAbilityInput);
// 能力输入
USTRUCT(BlueprintType)
struct FFPAbilityInput
{
	GENERATED_BODY()

public:

	// 激活能力输入标签
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (Categories = "FPInput.Ability"))
	FGameplayTag ActivateInputTag;

	// 激活能力触发事件
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	ETriggerEvent ActivateTriggerEvent = ETriggerEvent::Started;

	// 取消能力输入标签
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (Categories = "FPInput.Ability"))
	FGameplayTag CancelInputTag;

	// 取消能力触发事件
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	ETriggerEvent CancelTriggerEvent = ETriggerEvent::Started;

	// 是否有效
	FORCEINLINE bool IsValid() const
	{
		return ActivateInputTag.IsValid() || CancelInputTag.IsValid();
	}
};

5、服务器读取能力属性配置DefaultAttributesDefaultEffects初始化属性。死亡会添加死亡标签用来判断是否为复活,复活仅恢复属性(需重写FPAttributeSetBase::RestoreFullAttribute()),不重复初始化

6、添加能力模型数组,管理此角色的所有能力,数组索引越大映射能力映射表的优先级越高(能力标签相同时,仅映射优先级最高的能力模型能力)

7、服务器读取能力属性配置ActiveAbilitiesPassiveAbility能力标签能力标签读取能力映射表初始化能力,在死亡时会移除添加的能力

  • 能力模型

能力模型用于管理配置能力,修改数据表格时会同步修改编译蓝图,数据表格保存时也会同步保存蓝图,同时也会更新保存能力映射表,从而影响C++能力构造。
将能力模型添加给能力属性配置,通过能力属性配置数据表格的Key能力标签通过能力映射表查询能力

1、继承FFPAbilityData创建能力模型的数据表格

// 能力数据,继承此结构体创建能力模型
USTRUCT(BlueprintType)
struct FFPAbilityData : public FTableRowBase
{
	GENERATED_BODY()

public:

	// 能力标签
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (Categories = "FPAbility.Ability"))
	FGameplayTag Tag = FGameplayTag::EmptyTag;

	// 能力类
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	TSoftClassPtr<UFPAbilityBase> Class = nullptr;

	// 标签
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	FFPAbilityTags Tags;

	// 冷却
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	FFPAbilityCooldownData Cooldown;

	// 消耗
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	TMap<FGameplayAttribute, FScalableFloat> Costs;

	// 伤害
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	FFPAbilityDamageData Damage;

	// 组合
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (EditCondition = "bIsAbilityComboClass", EditConditionHides, HideEditConditionToggle))
	FFPAbilityComboData Combo;

	// 图标
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	TSoftObjectPtr<UTexture2D> Icon = nullptr;

#if WITH_EDITORONLY_DATA
private:

	// 首次启动时跳过。启动引擎时,不执行OnDataTableChanged()
	bool bSkipOnFirstLaunch = true;

	// 能力类的路径名称(仅用于蓝图类)。为空时,代表数据表格此行没有改动
	FString ClassPathName = "";

	// 上次能力标签
	UPROPERTY()
	FGameplayTag LastTag = FGameplayTag::EmptyTag;

	// 判断是否为运行能力组合的能力类
	UPROPERTY()
	bool bIsAbilityComboClass = false;
#endif

#if WITH_EDITOR
public:

	// 保存蓝图能力类。保存数据表格时,仅当ClassPathName不为空时保存能力类,保存完成后会清空ClassPathName
	void SaveBlueprintAsset();

private:

	// 数据表格改变时调用
	virtual void OnDataTableChanged(const UDataTable* InDataTable, const FName InRowName) override;

	// 仅当能力标签被修改时才会执行
	void DataTableTagChanged();
#endif
};

2、在能力模型添加能力标签容器

// 能力标签
USTRUCT(BlueprintType)
struct FFPAbilityTags
{
	GENERATED_BODY()

public:

	// 当此能力执行时,带有这些标签的能力将被取消
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FGameplayTagContainer CancelAbilitiesWithTag;

	// 当此能力处于活动状态时,带有这些标签的能力将被阻止
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FGameplayTagContainer BlockAbilitiesWithTag;

	// 当此能力处于活动状态时,应用到激活所有者的标签
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FGameplayTagContainer ActivationOwnedTags;

	// 仅当激活的演员/组件拥有所有这些标签时,此能力才能被激活
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FGameplayTagContainer ActivationRequiredTags;

	// 如果激活的演员/组件拥有这些标签中的任何一个,此能力将被阻止
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FGameplayTagContainer ActivationBlockedTags;

	// 仅当源演员/组件拥有所有这些标签时,此能力才能被激活
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FGameplayTagContainer SourceRequiredTags;

	// 如果源演员/组件拥有这些标签中的任何一个,此能力将被阻止
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FGameplayTagContainer SourceBlockedTags;

	// 仅当目标演员/组件拥有所有这些标签时,此能力才能被激活 
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FGameplayTagContainer TargetRequiredTags;

	// 如果目标演员/组件拥有这些标签中的任何一个,此能力将被阻止
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FGameplayTagContainer TargetBlockedTags;
};

3、在能力模型添加能力冷却和消耗,可以根据自己的属性集添加消耗的属性

// 能力冷却数据
USTRUCT(BlueprintType)
struct FFPAbilityCooldownData
{
	GENERATED_BODY()

public:

	// 冷却时间
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	FScalableFloat Duration;

	// 冷却标签
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (Categories = "FPAbility.Cooldown"))
	FGameplayTag Tag = FGameplayTag::EmptyTag;
};

// 消耗
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
TMap<FGameplayAttribute, FScalableFloat> Costs;

4、在能力模型添加能力伤害,调用函数UFPAbilityBase::MakeDamageGameplayEffectSpecHandles()返回的TArray<FGameplayEffectSpecHandle>,给目标应用伤害调用函数UFPAbilityFunctionLibrary::ApplyDamage()
伤害类型标签:标签为空时,为普通伤害计算。插件提供了百分比伤害真实伤害关闭命中反馈, 添加关闭命中反馈标签后将不执行UFPAbilityManagerComponent::OnReceivedDamage,会停止播放受击动画、声音等
伤害给与目标的效果:如着火、眩晕等

// UFPAbilityBase的函数↓↓↓
// 生成伤害GE规格句柄
UFUNCTION(BlueprintCallable, Category = "FPAbility.Damage")
TArray<FGameplayEffectSpecHandle> MakeDamageGameplayEffectSpecHandles() const;

// UFPAbilityFunctionLibrary的函数↓↓↓
// 应用伤害
// @param InAvatarActor 目标AvatarActor
// @param InSpecHandles 伤害GE规格委托,索引0是伤害数值,其他是状态GE
UFUNCTION(BlueprintCallable, Category = "FPAbility")
static TArray<FActiveGameplayEffectHandle> ApplyDamage(AActor* InAvatarActor, TArray<FGameplayEffectSpecHandle> InSpecHandles);

// 接收伤害委托,源和目标的服务器和客户端都可接收到委托。攻击拥有"FPAbility.Damage.Type.NotHitReact"标签将不执行此委托,可以播放被击反应的动画和声音,也用来显示伤害数字
UPROPERTY(BlueprintAssignable, Category = "FPAbility")
FFPAbilityReceivedDamageDelegate OnReceivedDamage;
// 能力伤害数据
USTRUCT(BlueprintType)
struct FFPAbilityDamageData
{
	GENERATED_BODY()

public:

	// 伤害数值
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (ClampMin = 0))
	float Value = 0.0f;

	// 伤害类型标签
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (Categories = "FPAbility.Damage.Type"))
	FGameplayTagContainer TypeTags;

	// 伤害给与目标的效果
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	TArray<TSubclassOf<UGameplayEffect>> GiveEffects;

	// 是否有效
	FORCEINLINE bool IsValid() const
	{
		return Value > 0;
	}
};

5、仅当能力继承UFPAbilityComboBase时,才会显示此能力组合设置

// 能力组合数据
USTRUCT(BlueprintType)
struct FFPAbilityComboData
{
	GENERATED_BODY()

public:

	// 能力组合
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	TSoftObjectPtr<UFPAbilityCombo> AbilityCombo = nullptr;

	// 初始输入标签,转换到导管节点后的第一个动画节点,存在导管节点时才会生效
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (Categories = "FPInput.Ability"))
	FGameplayTag InitialInputTag = FGameplayTag::EmptyTag;

	// 是否使用EventReceived代理广播内部游戏事件,AI使用此能力时会自动开启
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	bool bBroadcastInternalEvents = false;
};

  • 能力映射表

管理所有能力映射,添加到UFPAbilityProjectSettings::AbilityMapTable通过能力属性配置或任何能力模型保存时自动更新(不支持手动修改),也可以通过RefreshMapTable()刷新

1、功能
(1)、通过能力属性配置Key能力模型的技能标签查询能力
(2)、能力模型保存时,检测保存的能力模型和其他能力模型的能力是否有重复,有重复会弹窗提示
(3)、用于构造C++能力(蓝图会自己更新保存)

2、能力映射表的数据资产继承的类

// 能力映射表,不支持手动修改,添加到UFPAbilityProjectSettings::AbilityMapTable会自动更新
UCLASS()
class FPABILITYSYSTEM_API UFPAbilityMapTable : public UDataAsset
{
	GENERATED_BODY()

protected:

	// 能力映射,通过能力属性配置的Key和能力模型的技能标签查询能力
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (EditCondition = "false"), Category = "Config")
	TMap<FName, FFPAbilityMap> AbilityMaps;

	// 能力模型映射;1、能力模型保存时,检测所有能力模型的能力是否有重复;2、用于构造C++能力(蓝图会自己更新保存)
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (EditCondition = "false"), Category = "Config")
	TMap<FSoftClassPath, FFPAbilityModelMap> AbilityModelMaps;

public:

	// 查找能力映射
	// @param InKey UFPAbilityProjectSettings::AttributeConfig数据表格的Key
	const FFPAbilityMap* FindAbilityMap(const FName& InKey) const;

	// 查找能力类
	// @param InKey UFPAbilityProjectSettings::AttributeConfig数据表格的Key
	// @param InAbilityTag 能力标签
	TSoftClassPtr<UFPAbilityBase> FindAbilityClass(const FName& InKey, const FGameplayTag& InAbilityTag) const;

	// 查找能力数据
	// @param InAbilityClass 能力类
	// @param bCppOnly bCppOnly = true时,仅获取C++能力的数据
	const FFPAbilityData* FindAbilityData(UFPAbilityBase* InAbilityClass, bool bCppOnly = true) const;

#if WITH_EDITOR

	// 添加能力映射
	// @param InDataTable 数据表格需继承FFPAbilityAttributeConfig
	void AddAbilityMaps(UDataTable* InDataTable);

	// 添加能力模型映射
	// @param InAbilityModel 能力模型,数据表格需继承FFPAbilityData
	void AddAbilityModelMap(UDataTable* InAbilityModel);

	// 刷新映射表,通过读取UFPAbilityProjectSettings::AttributeConfig和所有能力模型刷新映射表
	UFUNCTION(CallInEditor, Category = "Config")
	void RefreshMapTable();
#endif
};
// UFPAbilityMapTable使用的结构体↓↓↓

// 能力映射
USTRUCT(BlueprintType)
struct FFPAbilityMap
{
	GENERATED_BODY()

public:

	// 能力映射
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
	TMap<FGameplayTag, TSoftClassPtr<UFPAbilityBase>> Abilities;
};

// 能力模型映射
USTRUCT(BlueprintType)
struct FFPAbilityModelMap
{
	GENERATED_USTRUCT_BODY()

public:

	// 行句柄
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
	FDataTableRowHandle RowHandle;

	// 是否为蓝图类
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
	bool bIsBlueprintClass = false;
};

  • 使用指南

1、根据自己的游戏需求添加UFPAttributeSetUAbilitySystemComponent,继承IAbilitySystemInterface接口,并实现接口的函数GetAbilitySystemComponent

2、使用能力模型能力属性配置

3、给APawn添加UFPAbilityManagerComponent组件,并通过能力属性配置行命名选择对应的配置。
然后服务器调用UFPAbilityManagerComponent::InitAbilityManager()初始化组件;
客户端调用UFPAbilityManagerComponent::InitAbilityInput()绑定能力输入。
根据需求调用以下UFPAbilityManagerComponent的函数,没有蓝图API的函数使用函数库的函数。

// 初始化能力管理组件,建议在APawn::PossessedBy()中调用
// @param InAbilitySystemComp 能力管理组件管理的能力系统组件
// @param NewServerData 服务器保存的数据
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "FPAbility")
bool InitAbilityManager(UAbilitySystemComponent* InAbilitySystemComp, const FFPAbilityServerData& NewServerData);

// 重置能力管理组件
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "FPAbility")
void ResetAbilityManager();

// 接收伤害委托,源和目标的服务器和客户端都可接收到委托。攻击拥有"FPAbility.Damage.Type.NotHitReact"标签将不执行此委托,可以播放受击的动画和声音,也可以显示伤害数字
UPROPERTY(BlueprintAssignable, Category = "FPAbility")
FFPAbilityReceivedDamageDelegate OnReceivedDamage;

// 死亡委托,绑定委托后执行死亡动画或者布娃娃,如果使用FPOnlineSystem调用UFPOnlineFunctionLibrary::PawnDied()重生
UPROPERTY(BlueprintAssignable, BlueprintAuthorityOnly, Category = "FPAbility")
FFPAbilityDiedDelegate OnDied;

// 属性配置
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (RowType = "/Script/FPAbilitySystem.FPAbilityAttributeConfig"), Category = "FPAbility")
FDataTableRowHandle AttributeConfig;

// 获取能力系统组件
UFUNCTION(BlueprintCallable, Category = "FPAbility")
UAbilitySystemComponent* GetAbilitySystemComponent() const;

// 获取属性集
UFUNCTION(BlueprintCallable, Category = "FPAbility")
UFPAttributeSetBase* GetAttributeSet() const;

// 移除所有效果
// @param bIgnoreInitialEffects 是否忽略初始添加效果
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "FPAbility")
void RemoveEffects(bool bIgnoreInitialEffects = true);

// 移除所有能力
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "FPAbility")
void RemoveAbilities();

// 给予能力
void GiveAbility(const FGameplayTag& InAbilityTag);

// 清除能力
void ClearAbility(const FGameplayTag& InAbilityTag);

// 激活能力
void ActivateAbility(const FGameplayTag& InAbilityTag);

// 取消能力
void CancelAbility(const FGameplayTag& InAbilityTag);

// 属性点添加到属性
UFUNCTION(BlueprintCallable, Category = "FPAbility")
void PointsAddToAttributePoints(const FGameplayAttribute& InAttribute);

// 初始化能力输入,通过AttributeConfigPtr绑定输入,建议在APawn::SetupPlayerInputComponent中调用
UFUNCTION(BlueprintCallable, Category = "FPAbility")
void InitAbilityInput();

// 移除所有能力输入
UFUNCTION(BlueprintCallable, Category = "FPAbility")
void RemoveAllAbilityInput();

// 绑定能力输入(仅支持本地调用),按键被使用时会自动解绑之前的能力
bool BindAbilityInput(const FGameplayTag& InAbilityTag, const FFPAbilityInput& InAbilityInput);

// 解除此按键绑定的能力(仅支持本地调用)
UFUNCTION(BlueprintCallable, Category = "FPAbility")
void RemoveAbilityInput(const FFPAbilityInput& InAbilityInput);

// 能力中断标签,添加这些标签会中断当前正在施放的能力
UPROPERTY(EditDefaultsOnly, meta = (Categories = "FPAbility"), Category = "FPAbility|TagChange")
FGameplayTagContainer AbilityInterruptTags;

// 取消能力标签,添加这些标签会取消对应的能力
UPROPERTY(EditDefaultsOnly, meta = (Categories = "FPAbility"), Category = "FPAbility|TagChange")
FGameplayTagContainer CancelAbilityTags;

// 忽略取消能力标签,添加这些标签时不会取消对应的能力
UPROPERTY(EditDefaultsOnly, meta = (Categories = "FPAbility"), Category = "FPAbility|TagChange")
FGameplayTagContainer IgnoredCancelAbilityTags;

4、继承FPAttributeSetBase创建自己的属性集,可以根据需求重写以下函数

// 初始化属性存档数据
UFUNCTION(BlueprintCallable, Category = "Attribute")
virtual void InitaAttributeSaveData(TMap<FGameplayAttribute, float> InSaveAttributes);

// 添加到属性的属性点,初始化调用
UFUNCTION(BlueprintCallable, Category = "Points")
virtual bool AddAttributePoints(const FGameplayAttribute& InAttribute, int32 NewValue);

// 恢复属性至满值,复活时调用
UFUNCTION(BlueprintCallable, Category = "Attribute")
virtual void RestoreFullAttribute() {};

// 应用受到到伤害
virtual void ApplyDamage(const FGameplayEffectModCallbackData& Data);

// 获取被杀死后给与伤害源的奖励
virtual UGameplayEffect* GetBountyGameplayEffect() const;

5、AI激活能力,激活普通技能只需要设置AbilityTag,能力结束时会结束AI任务,也可以通过设置WaitTime强制取消能力,InputTags只对继承UFPAbilityComboBase的能力有效,用来释放连招技能。

// 能力标签
UPROPERTY(EditAnywhere, meta = (Categories = "FPAbility.Ability"), Category = "FPAbility")
FGameplayTag AbilityTag = FGameplayTag::EmptyTag;

// 等待强制取消能力时间(s),时间为0时不强制取消能力
UPROPERTY(EditAnywhere, meta = (ClampMin = 0), Category = "FPAbility")
float WaitTime = 0.0f;

// 输入标签,能力UFPAbilityComboBase会使用此标签切换组合动画
UPROPERTY(EditAnywhere, meta = (Categories = "FPInput.Ability"), Category = "FPAbility")
TArray<FGameplayTag> InputTags;

AI激活能力的行为树任务: FPAbilitySystem_AIActivateAbility_BTT

AI激活能力的状态树任务:运行激活能力任务的节点必须开启CustomTickRate;上下文Actor除了支持添加ActorPawn,还支持添加AIController FPAbilitySystem_AIActivateAbility_STT

6、根据情况调用UFPAbilityFunctionLibrary的函数

// 获取能力管理组件
UFUNCTION(BlueprintPure, Category = "FPAbility")
static UFPAbilityManagerComponent* GetAbilityManagerComp(AActor* InAvatarActor);

// 获取能力管理组件
UFUNCTION(BlueprintPure, Category = "FPAbility")
static UFPAttributeSetBase* GetAttributeSet(UAbilitySystemComponent* InASC);

// 应用伤害
// @param InAvatarActor 目标AvatarActor
// @param InSpecHandles 伤害GE规格委托,索引0是伤害数值,其他是状态GE
UFUNCTION(BlueprintCallable, Category = "FPAbility")
static TArray<FActiveGameplayEffectHandle> ApplyDamage(AActor* InAvatarActor, TArray<FGameplayEffectSpecHandle> InSpecHandles);

// 获取命中反应方向
// @param InTargetAvatarActor 目标AvatarActor
// @param InImpactPoint 被攻击的位置
UFUNCTION(BlueprintPure, Category = "FPAbility")
static const FGameplayTag GetHitReactDirectionTag(AActor* InAvatarActor, const FVector& InImpactPoint);

// 给予能力
// @param InAbilityManager 能力管理组件
// @param InAbilityTag 能力标签
UFUNCTION(BlueprintCallable, Category = "FPAbility")
static void GiveAbility(UFPAbilityManagerComponent* InAbilityManager, UPARAM(meta = (Categories = "FPAbility.Ability")) FGameplayTag InAbilityTag);

// 清除能力
// @param InAbilityManager 能力管理组件
// @param InAbilityTag 能力标签
UFUNCTION(BlueprintCallable, Category = "FPAbility")
static void ClearAbility(UFPAbilityManagerComponent* InAbilityManager, UPARAM(meta = (Categories = "FPAbility.Ability")) FGameplayTag InAbilityTag);

// 激活能力
// @param InAbilityManager 能力管理组件
// @param InAbilityTag 能力标签
UFUNCTION(BlueprintCallable, Category = "FPAbility")
static void ActivateAbility(UFPAbilityManagerComponent* InAbilityManager, UPARAM(meta = (Categories = "FPAbility.Ability")) FGameplayTag InAbilityTag);

// 取消能力
// @param InAbilityManager 能力管理组件
// @param InAbilityTag 能力标签
UFUNCTION(BlueprintCallable, Category = "FPAbility")
static void CancelAbility(UFPAbilityManagerComponent* InAbilityManager, UPARAM(meta = (Categories = "FPAbility.Ability")) FGameplayTag InAbilityTag);

// 获取能力等级
// @param InAbilityManager 能力管理组件
// @param InAbilityTag 能力标签
UFUNCTION(BlueprintPure, Category = "FPAbility")
static int32 GetAbilityLevel(UFPAbilityManagerComponent* InAbilityManager, UPARAM(meta = (Categories = "FPAbility.Ability")) FGameplayTag InAbilityTag);

// 绑定能力输入(仅支持本地调用),按键被使用时会自动解绑之前的能力
// @param InAbilityManager 能力管理组件
// @param InAbilityTag 能力标签
// @param InAbilityInput 能力输入
UFUNCTION(BlueprintCallable, Category = "FPAbility")
static bool BindAbilityInput(UFPAbilityManagerComponent* InAbilityManager, UPARAM(meta = (Categories = "FPAbility.Ability.Active")) FGameplayTag InAbilityTag, const FFPAbilityInput& InAbilityInput);

  • 属性集

这是我自己项目中使用的属性集,非插件内容,仅供参考

属性 描述 数据来源 网络复制
Level 等级,升级会提供属性点 存档数据
MaxLevel 最大等级 项目设置
XP 杀死敌人获取的经验值 存档数据
XPBaseValue 角色1级升级时所需的经验 项目设置
MaxXP 当前等级升级时所需的经验
$MaxXP=XPBaseValue \times Level^2$
计算
XPBounty 角色死亡时奖励给杀手的经验值 = $XPBounty \times Level$ 能力属性配置
Points 加点剩余的属性点
可以加点的属性包括:血量、耐力、能量、速度和力量
已经使用的属性点 + $Points = LevelUpPoints \times Level$
存档数据
LevelUpPoints 升级提供的属性点 项目设置
MaxPoints 单个属性的最大点数 项目设置
Health 当前血量 存档数据
MaxHealth 血量最大值,当最大血量变化时,当前血量保持百分比不变
$MaxHealth=HealthInitial+HealthPerPoints\times HealthPoints$
计算
HealthInitial 血量初始值 能力属性配置
HealthRegenRate 血量恢复率,恢复血量会消耗能量 能力属性配置
HealthPoints 血量属性点 存档数据
HealthPerPoints 每个属性点添加的血量值 能力属性配置
Stamina 当前耐力 存档数据
MaxStamina 耐力最大值,当最大耐力变化时,当前耐力保持百分比不变
$MaxStamina=StaminaInitial+StaminaPerPoints\times StaminaPoints$
计算
StaminaInitial 耐力初始值 能力属性配置
StaminaRegenRate 耐力恢复率,恢复耐力会消耗能量 能力属性配置
StaminaPoints 耐力属性点 存档数据
StaminaPerPoints 每个属性点添加的耐力值 能力属性配置
Energy 当前能量,恢复血量和耐力会额外消耗能量 存档数据
MaxEnergy 能量最大值,当最大耐力变化时,当前能量保持不变(百分比改变)
$MaxEnergy=EnergyInitial+EnergyPerPoints\times EnergyPoints$
计算
EnergyInitial 能量初始值 能力属性配置
EnergyUseRate 能量消耗率,角色活着会持续消耗能量;没有能量时,持续消耗血量 能力属性配置
EnergyPoints 能量属性点 存档数据
EnergyPerPoints 每个属性点添加的能量值 能力属性配置
Speed 影响所有行为的速度,按百分比增速Speed%
$Speed=100+SpeedPerPoints\times SpeedPoints$
计算
SpeedPoints 速度属性点 存档数据
SpeedPerPoints 每个属性点添加的速度值 能力属性配置
Strength 力量,按百分比增伤Strength%
$Strength=100+StrengthPerPoints\times StrengthPoints$
计算
StrengthPoints 力量属性点 存档数据
StrengthPerPoints 每个属性点添加的力量值 能力属性配置
WeaponDamage 武器伤害 装备
Armor 护甲 装备
IncreaseDamage 百分比增伤,取值范围[-1, +∞] Buff
ReduceDamage 百分比减伤,取值范围[-∞, 1] Buff
Damage 受到的伤害,仅用于伤害计算 计算
MaxWeight 最大负重 能力属性配置

  • 伤害计算

未减伤前伤害(UnmitigatedDamage);能力基础伤害(BaseDamage);减伤后伤害/实际伤害(MitigatedDamage)。 $UnmitigatedDamage = (BaseDamage + WeaponDamage) \times \dfrac{Strength}{100} \times (1 + IncreaseDamage)$ $MitigatedDamage = UnmitigatedDamage\times \dfrac{100}{100 + Armor}\times (1 -ReduceDamage)$

  • 调试指令
指令 描述
FP_God 无敌
FP_FullState 状态一直全满(需要在项目设置配置自己的GE)
FP_NoCost 能力无消耗
FP_NoCooldown 能力无冷却
FP_AddXP (float) 增加经验
FP_AddHealth (float) 增加血量
FP_AddStrength (float) 增加力量
FP_AddWeaponDamage (float) 增加武器伤害
FP_AddArmor (float) 增加护甲
FP_AddIncreaseDamage (float) 增加百分比增伤
FP_AddReduceDamage (float) 增加百分比减伤

以下是我自己项目使用的调试指令,非插件内容,仅供参考

指令 描述
FP_AddStamina (float) 增加耐力
FP_AddEnergy (float) 增加能量
FP_AddSpeed (float) 增加速度
FP_AddMaxWeight (float) 增加速度

FPAbilityCombo

能力组合(技能连招系统)。此模块参考Combo Graph(插件已购买), 复刻后移除了工具栏的模式切换节点自动排列非GAS的逻辑(现在插件仅对GAS有效)、旧粒子系统(仅留下Niagara);
不同部分:必须基于骨架设置动画组合,输入基于FPInput用游戏标签设置输入,将序列节点和蒙太奇节点组合成一个动画节点(可以通过枚举切换),节点Slate参考了动画蓝图, 为配合FPAbilitySystem模块做了很多修改,但不影响此模块独立使用。

  • 此模块的主要类
类名 描述
FPAbilityTask_RunAbilityCombo 运行能力组合任务
FPAbilityTask_PlayMontage 播放蒙太奇任务
FPAbilityTask_NetworkSyncPoint 网络同步点任务:为客户端和服务器提供通用同步点的任务
FPAbilityComboTasksComponent 能力组合任务组件,用于发送网络复制的游戏事件(按键输入后切换动画节点)
FPAbilityComboCollisionComponent 能力组合碰撞组件:为网格提供基本的攻击碰撞检测机制
FPAbilityComboInterface 技能组合接口,建议添加给释放技能的角色,重写接口函数GetCollisionComponent(),用来管理FPAbilityComboTasksComponentFPAbilityComboCollisionComponent组件
FPAbilityComboAnimNotifyState 能力组合动画通知状态:通过FPAbilityComboTasksComponent在组合动画开始或结束时发送事件
FPAbilityCollisionAnimNotifyState 能力碰撞动画通知状态,用来控制FPAbilityComboCollisionComponent的碰撞检测
FPAbilityGameplayCueNotify_HitImpact 能力游戏提示通知_命中打击,用于生成打击目标的粒子和声音
FPAbilityCombo 能力组合,将动画组合成连击动作
FPAbilityComboNodeBase 能力组合节点基类
FPAbilityComboNodeTrans 能力组合节点转换,处理节点转换
FPAbilityComboNodeConduit 能力组合导管节点,建立分支
FPAbilityComboNodeEntry 能力组合开始节点
FPAbilityComboNodeAnim 能力组合动画节点,用来添加动画序列或动画蒙太奇,网络环境仅支持动画蒙太奇
  • 使用指南

1、FPAbilityCombo项目设置

属性 数据类型 描述
DynamicMontageSlotName FName 动画序列创建动态蒙太奇的插槽名称
NotifyStates TMap<TSoftClassPtr<UAnimNotifyState>, FFPAbilityComboNotifyStateAutoSetup> 自动设置动画通知状态,给所有播放的动画添加动画通知状态
bAutoAddAbilityCollisionNotify bool 伤害有效时自动给动画节点添加UFPAbilityCollisionAnimNotifyState
CostGameplayEffectClass TSoftClassPtr<UGameplayEffect> 消耗GE类,所有动画都使用此GE,插件已设置好,不建议修改
DamageGameplayEffectClass TSoftClassPtr<UGameplayEffect> 伤害GE类,所有动画都使用此GE,根据自己的需求更换计算逻辑
bSequencesNetworkedWarning bool 网络环境中,使用动画序列发送消息警告(网络环境仅支持动画蒙太奇)
TraceColor FLinearColor 绘制攻击碰撞检测轨迹的检测颜色
TraceHitColor FLinearColor 绘制攻击碰撞检测轨迹的检测命中颜色
DebugDrawTime float 绘制攻击碰撞检测轨迹的调试绘制时间

FPAbilityComboSettings

2、在UGameplayAbility中调用RunAbilityCombo运行能力组合。也可以直接使用FPAbilitySystemFPAbilityComboBase来运行能力组合

DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FFPAbilityComboTaskDelegate, FGameplayTag, EventTag, FGameplayEventData, EventData);

// 开始能力组合时调用的委托
UPROPERTY(BlueprintAssignable)
FFPAbilityComboTaskDelegate OnComboStart;

// 结束能力组合时调用的委托
UPROPERTY(BlueprintAssignable)
FFPAbilityComboTaskDelegate OnComboEnd;

//  接收能力组合节点事件时调用的委托
UPROPERTY(BlueprintAssignable)
FFPAbilityComboTaskDelegate EventReceived;

// 创建并运行能力组合,从GA中启动能力组合的资产
// @param InOwningAbility 拥有的能力
// @param InAbilityCombo 要运行的能力组合资源
// @param InInitialInputTag 初始输入标签,转换到导管节点后的第一个动画节点,存在导管节点时才会生效
// @param bInBroadcastInternalEvents 是否使用EventReceived代理广播内部游戏事件(包括组合开始和结束事件)
UFUNCTION(BlueprintCallable, Category = "FPAbility|Tasks", meta = (DisplayName = "RunAbilityCombo", AdvancedDisplay = "InInitialInputTag, bInBroadcastInternalEvents", HidePin = "InOwningAbility", DefaultToSelf = "InOwningAbility", BlueprintInternalUseOnly = "TRUE"))
static UFPAbilityTask_RunAbilityCombo* CreateRunAbilityCombo(UGameplayAbility* InOwningAbility, UFPAbilityCombo* InAbilityCombo, UPARAM(meta = (Categories = "FPInput.Ability")) FGameplayTag InInitialInputTag, bool bInBroadcastInternalEvents = false);

FPAbilityCombo_Run

3、在内容浏览器中创建新的能力组合动画节点蓝图

FPAbilityCombo_AssetType

4、选择要组合动画的骨架创建能力组合,类似动画蓝图;选择父类动画节点蓝图创建动画节点蓝图(可选)

FPAbilityCombo_Filter FPAbilityCombo_Panel FPAbilityCombo_AnimNodeBlueprint

5、节点转换

FPAbilityCombo_NodeTrans

// 能力组合转换行为
UENUM(BlueprintType)
enum class EFPAbilityComboTransitionBehavior : uint8
{
	// 输入按键后,动画结束时执行(预输入)
	OnComboEnd,

	// 输入按键后,立即触发组合转换
	Immediately,

	// 输入按键后,动画通知触发组合转换,如果已动画通知,则立即触发
	OnAnimNotify,
};

// 转到下一个节点的输入标签
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (Categories = "FPInput.Ability"), Category = "FPAbility|Transition")
FGameplayTag TransitionInputTag;

// 输入事件类型
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (EditCondition = "bIsValidInputTag", EditConditionHides, HideEditConditionToggle), Category = "FPAbility|Transition")
ETriggerEvent TriggerEvent = ETriggerEvent::Triggered;

// 能力组合转换行为,转换到下一个节点
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (EditCondition = "bIsValidInputTag", EditConditionHides, HideEditConditionToggle), Category = "FPAbility|Transition")
EFPAbilityComboTransitionBehavior TransitionBehavior = EFPAbilityComboTransitionBehavior::OnComboEnd;

// 根据动画通知名称触发转换,接受到通知后转换
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (EditCondition = "bShowAnimNotifyName", EditConditionHides, HideEditConditionToggle), Category = "FPAbility|Transition")
FName TransitionAnimNotifyName = NAME_None;

// 根据动画通知触发转换,接受到通知后转换
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (EditCondition = "bShowAnimNotify", EditConditionHides, HideEditConditionToggle), Category = "FPAbility|Transition")
TSoftClassPtr<UAnimNotify> TransitionAnimNotify;

6、动画节点,可以通过拖拽动画资产创建动画节点,也可以右键添加创建设置好的动画节点蓝图

FPAbilityCombo_AnimNode

// 动画类型
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "FPAbility|Anim")
EFPAbilityComboAnimType AnimType = EFPAbilityComboAnimType::Montage;

// 动画序列
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (EditCondition = "AnimType == EFPAbilityComboAnimType::Sequence", EditConditionHides), Category = "FPAbility|Anim")
TSoftObjectPtr<UAnimSequence> Sequence;

// 蒙太奇
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (EditCondition = "AnimType == EFPAbilityComboAnimType::Montage", EditConditionHides), Category = "FPAbility|Anim")
TSoftObjectPtr<UAnimMontage> Montage;

// 蒙太奇开始部分
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (EditCondition = "AnimType == EFPAbilityComboAnimType::Montage", EditConditionHides), Category = "FPAbility|Anim")
FName StartSection = NAME_None;

// 动画蒙太奇播放率
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (ClampMin = "0.0"), Category = "FPAbility|Anim")
float MontagePlayRate = 1.0f;

// 根运动平移的比例
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (ClampMin = "0.0"), Category = "FPAbility|Anim")
float RootMotionScale = 1.0f;

// 能力结束时停止动画
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "FPAbility|Anim")
bool bStopAnimationWhenAbilityEnds = true;

// 通知状态覆盖,播放动画的之前给动画添加此通知状态和UFPAbilityComboProjectSettings::NotifyStates
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "FPAbility|Notify")
TMap<TSoftClassPtr<UAnimNotifyState>, FFPAbilityComboNotifyStateAutoSetup> NotifyStatesOverrides;

// 能力消耗
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "FPAbility|Abilities")
TMap<FGameplayAttribute, FScalableFloat> AbilityCosts;

// 能力伤害
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "FPAbility|Abilities")
FFPAbilityDamageData AbilityDamage;

// GE容器映射
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "FPAbility|Abilities")
TMap<FGameplayTag, FFPAbilityGameplayEffectContainer> EffectsContainerMap;

// GC容器映射
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "FPAbility|Abilities")
TMap<FGameplayTag, FFPAbilityGameplayCueContainer> CuesContainerMap;

// 事件标签容器,当有这些标签时触发事件
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "FPAbility|Abilities")
FGameplayTagContainer EventTags;
// 能力伤害数据
USTRUCT(BlueprintType)
struct FFPAbilityDamageData
{
	GENERATED_BODY()

public:

	// 伤害数值
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (ClampMin = 0))
	float Value = 0.0f;

	// 伤害类型标签
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (Categories = "FPAbility.Damage.Type"))
	FGameplayTagContainer TypeTags;

	// 伤害给与目标的效果
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
	TArray<TSubclassOf<UGameplayEffect>> GiveEffects;

	// 是否有效
	FORCEINLINE bool IsValid() const
	{
		return Value > 0;
	}
};

// 游戏效果容器
USTRUCT(BlueprintType)
struct FFPAbilityGameplayEffectContainer
{
	GENERATED_BODY()

public:

	FFPAbilityGameplayEffectContainer() {};

	// 应用于目标的GE列表
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "GameplayEffectContainer")
	TArray<TSubclassOf<UGameplayEffect>> TargetGameplayEffectClasses;

	// 是否使用设置调用者数量
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "GameplayEffectContainer")
	bool bUseSetByCallerMagnitude = false;

	// 设置调用者数据标签
	UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (EditCondition = "bUseSetByCallerMagnitude", EditConditionHides), Category = "GameplayEffectContainer")
	FGameplayTag SetByCallerDataTag;

	// 设置调用者数量
	UPROPERTY(EditAnywhere, BlueprintReadOnly, meta = (EditCondition = "bUseSetByCallerMagnitude", EditConditionHides), Category = "GameplayEffectContainer")
	float SetByCallerMagnitude = 1.0f;
};

// GC容器
USTRUCT(BlueprintType)
struct FFPAbilityGameplayCueContainer
{
	GENERATED_BODY()

public:

	// GC列表容器
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "GameplayCueContainer")
	TArray<FFPAbilityGameplayCueContainerDefinition> Definitions;

	// 获取GT对应的GC列表和原对象
	void GetAggregatedDefinitionsAndObjects(TMap<FGameplayTag, FFPAbilityGameplayCueContainerDefinition>& OutDefinitions, TArray<TWeakObjectPtr<UObject>>& OutSourceObjects);

	// 获取GT对应的GC列表和原对象的路径
	void GetAggregatedDefinitionsAndPaths(TMap<FGameplayTag, FFPAbilityGameplayCueContainerDefinition>& OutDefinitions, TArray<FSoftObjectPath>& OutSoftObjectPaths);
};

7、添加攻击碰撞检测,给APawn添加UFPAbilityComboCollisionComponent, 对UFPAbilityComboCollisionComponent做基础设置后,调用RegisterCollisionMesh()UnregisterCollisionMesh()注册或注销网格碰撞。 只有添加了动画通知状态UFPAbilityCollisionAnimNotifyState的动画(技能伤害有效时,自动添加),才能启动此组件的检测
绘制攻击轨迹的调试指令:FP.Ability.Debug.DrawAttackTrace (bool)

// 跟踪类型
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "FPAbility|Traces")
EFPAbilityCollisionTraceType TraceType = EFPAbilityCollisionTraceType::Line;

// 检测半径
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (EditCondition = "TraceType == EFPAbilityCollisionTraceType::Sphere", EditConditionHides), Category = "FPAbility|Traces")
float SphereTraceRadius = 3.0f;

// 盒体检测尺寸(模型的长, 宽, 高)
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (EditCondition = "TraceType == EFPAbilityCollisionTraceType::Box", EditConditionHides), Category = "FPAbility|Traces")
FVector BoxTraceSize = FVector(10.0f);

// 检测复杂碰撞,为false时简化碰撞
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "FPAbility|Traces")
bool bTraceComplex = true;

// 碰撞跟踪通道
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "FPAbility|Traces")
TEnumAsByte<ETraceTypeQuery> CollisionTraceChannel = TraceTypeQuery2;

// 要忽略的Actor类型
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "FPAbility|Traces")
TArray<TSubclassOf<AActor>> ActorTypesToIgnore;

// 要忽略的碰撞配置文件
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "FPAbility|Traces")
TArray<FName> CollisionProfilesToIgnore;

// 仅在服务器上成功命中时调用委托
UPROPERTY(BlueprintAuthorityOnly, BlueprintAssignable, Category = "FPAbility")
FFPAbilityComboHitRegisteredDelegate OnHitRegistered;

// 检查到网格时调用委托
UPROPERTY(BlueprintAssignable, Category = "FPAbility")
FFPAbilityComboSimpleDelegate OnTraceStart;

// 结束检查到网格时调用委托
UPROPERTY(BlueprintAssignable, Category = "FPAbility")
FFPAbilityComboSimpleDelegate OnTraceEnd;

// 注册网格碰撞
UFUNCTION(BlueprintCallable, Category = "FPAbility")
virtual void RegisterCollisionMesh(UPrimitiveComponent* InMesh);

// 注销网格碰撞
UFUNCTION(BlueprintCallable, Category = "FPAbility")
virtual void UnregisterCollisionMesh(UPrimitiveComponent* InMesh);
// 能力碰撞跟踪类型
UENUM(BlueprintType)
enum class EFPAbilityCollisionTraceType : uint8
{
	// 球体检测
	Sphere,

	// 盒体检测
	Box,
};

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FFPAbilityComboSimpleDelegate);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FFPAbilityComboHitRegisteredDelegate, FHitResult, HitResult);

FPAbilityComboEditor

能力组合编辑器

  • 此模块的主要类
类名 描述
FPAbilityComboAssetTypeActions 能力组合资产类型操作,注册内容浏览器右键菜单的能力组合资产
FPAbilityComboAnimNodeAssetTypeActions 能力组合动画节点资产类型操作,注册内容浏览器右键菜单的能力组合资产
FPAbilityComboFactory 能力组合工厂
FPAbilityComboAnimNodeFactory 能力组合动画节点工厂
FPAbilityComboPanelNodeFactory 能力组合面板节点工厂
FPAbilityComboAssetEditor 能力组合编译器设置
FPAbilityComboPersonaBlueprintEditor 能力组合角色蓝图编辑器:可重复使用的角色功能,适用骨骼相关资产的资产编辑器
FPAbilityComboAnimAssetBrowser 能力组合动画资产浏览器
FPAbilityComboEditorToolbar 能力组合编辑器工具栏
FPAbilityComboEdGraph 能力组合编辑器图表
FPAbilityComboSchema 能力组合编辑器图表架构:定义和管理能力组合图表节点
FPAbilityComboApplicationMode 能力组合应用程序模式,创建此模式的选项卡
FPAbilityComboAnimAssetTabFactory 能力组合动画资产选项卡工厂
FPAbilityComboGraphViewportTabFactory 能力组合图表视口选项卡工厂
FPAbilityComboPropertyDetailsTabFactory 能力组合属性细节选项卡工厂
FPAbilityComboDebugger 能力组合调试器,编辑器播放时,可以在能力组合编辑器选择调试的对象进行调试
FPAbilityComboConnectionDrawingPolicy 能力组合连接绘制策略
FPAbilityComboDragDropAction 能力组合拖放操作
FPAbilityComboEdNodeBase 能力组合编辑器节点基类
FPAbilityComboEdNodeEntry 能力组合编辑器开始节点
FPAbilityComboEdNodeConduit 能力组合编辑器导管节点,建立分支
FPAbilityComboEdNodeTrans 能力组合编辑器节点转换
FPAbilityComboEdNodeAnim 能力组合编辑器动画节点
SFPAbilityComboNodeEntry 能力组合开始节点Slate
SFPAbilityComboNodeConduit 能力组合导管节点Slate,建立分支
SFPAbilityComboOutputPin 能力组合输出引脚Slate
SFPAbilityComboNodeTrans 能力组合节点转换Slate
SFPAbilityComboNodeAnim 能力组合动画节点Slate

About

Ability system

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors