虚幻GameAbilitySystem源码与设计解析-GameEffectComponent的实现

news/2025/2/21 10:36:29/文章来源:https://www.cnblogs.com/mcwhirr/p/18724918
// 版权所有(c)Epic Games, Inc. 保留所有权利。#pragma once#include "CoreMinimal.h"
#include "GameplayEffectComponent.generated.h"struct FActiveGameplayEffect;
struct FActiveGameplayEffectsContainer;
struct FGameplayEffectSpec;
struct FPredictionKey;
class UGameplayEffect;
没有屁用的头文件

GEC

/*** 游戏玩法效果组件(简称 GEComponent)* * GE 组件用于定义游戏玩法效果(GameplayEffect)的行为。该组件在 UE 5.3 版本引入,出于设计考虑,UGameplayEffect 对 UGameplayEffectComponent 的调用非常少。* 实现者不能依赖提供的大型 API 来实现所有期望的功能,而必须仔细研读游戏玩法效果的流程,并注册所需的回调函数来达成目标。这在当前实际上将 GE 组件的实现限制在了原生代码层面。* * GE 组件存在于游戏玩法效果(通常是一个仅包含数据的蓝图资产)之中。因此,和游戏玩法效果一样,对于所有已应用的实例,仅存在一个 GE 组件。* 这带来的一个不太直观的问题是,GE 组件不应包含任何运行时可操作/实例化的数据(例如每次执行时的存储状态)。* 开发者必须仔细考虑数据的存储位置(以及数据的评估时机)。早期的实现通常通过在所需的回调函数中存储少量运行时数据来解决这个问题(例如通过在委托中绑定额外的参数)。* 这或许解释了为什么某些功能仍在 UGameplayEffect 中,而非 UGameplayEffectComponent 中。未来的实现可能需要在 FGameplayEffectSpec(即游戏玩法效果规格组件)中存储额外的数据。* * 有关更多说明,请参阅 GameplayEffect.h,尤其是其中使用的术语(添加、执行和应用之间的区别)。*/

 

UCLASS(Abstract, Const, DefaultToInstanced, EditInlineNew, CollapseCategories, Within=GameplayEffect)
class GAMEPLAYABILITIES_API UGameplayEffectComponent : public UObject
{GENERATED_BODY()
public:/** 构造函数 */UGameplayEffectComponent();/** 返回拥有此组件的游戏玩法效果(即外部对象) */UGameplayEffect* GetOwner() const;/** * 游戏玩法效果规格能否应用到传入的能力系统组件(ASC)上?游戏玩法效果的所有组件都必须返回 true,或者只要有一个组件返回 false 就会禁止应用。* 注意:应用和抑制是两个不同的概念。如果一个游戏玩法效果可以应用,那么我们要么将其添加到活动游戏玩法效果容器中(如果它有持续时间或需要预测),要么执行它(如果它是即时生效的)。*/virtual bool CanGameplayEffectApply(const FActiveGameplayEffectsContainer& ActiveGEContainer, const FGameplayEffectSpec& GESpec) const { return true; }/*** 当一个游戏玩法效果被添加到活动游戏玩法效果容器时调用。当游戏玩法效果有持续时间(或者在本地进行预测)时,会将其添加到该容器中。* 注意:在复制过程中也会触发此调用(例如,当服务器将一个游戏玩法效果复制到拥有该效果的客户端时 —— 包括预测后的“重复”效果)。* 返回该效果是否应保持活动状态,返回 false 则抑制该效果。注意:抑制不会移除效果(效果仍会被添加,但处于休眠状态,等待解除抑制)。*/virtual bool OnActiveGameplayEffectAdded(FActiveGameplayEffectsContainer& ActiveGEContainer, FActiveGameplayEffect& ActiveGE) const { return true; }/** * 当一个游戏玩法效果被执行时调用。游戏玩法效果只能在 ROLE_Authority(服务器端)执行。只有在应用即时效果时,游戏玩法效果才会被执行(否则会被添加到活动游戏玩法效果容器中)。* 注意:周期性效果会每隔一个周期执行一次(并且也会被添加到活动游戏玩法效果容器中)。可以将其理解为周期性地执行一个即时效果(因此只能在服务器端发生)。*/virtual void OnGameplayEffectExecuted(FActiveGameplayEffectsContainer& ActiveGEContainer, FGameplayEffectSpec& GESpec, FPredictionKey& PredictionKey) const {}/*** 当一个游戏玩法效果首次应用或堆叠时调用。无论是有持续时间的效果还是即时执行的效果,都会发生“应用”操作。此调用不会周期性发生,也不会通过复制触发。* 建议优先使用此函数,而非 OnActiveGameplayEffectAdded 和 OnGameplayEffectExecuted(不过根据具体情况,可能会同时使用多个函数)。*/virtual void OnGameplayEffectApplied(FActiveGameplayEffectsContainer& ActiveGEContainer, FGameplayEffectSpec& GESpec, FPredictionKey& PredictionKey) const {}/*** 通知我们拥有该组件的游戏玩法效果已被修改,因此对拥有的游戏玩法效果应用与资产相关的更改(例如其任何字段)*/virtual void OnGameplayEffectChanged() {}UE_DEPRECATED(5.4, "使用不带 const 的 OnGameplayEffectChanged 函数 —— 当游戏玩法效果更改时,我们通常希望在 GE 组件上缓存数据")virtual void OnGameplayEffectChanged() const {}

编辑器效果

protected:
#if WITH_EDITORONLY_DATA/** 在编辑器的游戏玩法效果组件索引中显示的友好名称(参见 UGameplayEffect::GEComponents)。我们在此处设置 EditCondition 为 False,这样它就不会在其他地方显示。 */UPROPERTY(VisibleDefaultsOnly, Transient, Category=AlwaysHidden, Meta=(EditCondition=False, EditConditionHides))FString EditorFriendlyName;
#endif
};

 

有一些单独定义的功能

// 在传入的游戏玩法效果的父类中查找相同的组件。这对于让子组件从父组件继承属性(例如继承标签)很有用。
template<typename GEComponentClass, typename LateBindGameplayEffect = UGameplayEffect> // LateBindGameplayEffect 用于避免包含 GameplayEffect.h
const GEComponentClass* FindParentComponent(const GEComponentClass& ChildComponent)
{const LateBindGameplayEffect* ChildGE = ChildComponent.GetOwner();const LateBindGameplayEffect* ParentGE = ChildGE ? Cast<LateBindGameplayEffect>(ChildGE->GetClass()->GetArchetypeForCDO()) : nullptr;return ParentGE ? ParentGE->template FindComponent<GEComponentClass>() : nullptr;
}

这段代码定义了 UGameplayEffectComponent 类,它是 Unreal Engine 中用于定义游戏玩法效果(GameplayEffect)行为的组件类。该类引入于 UE 5.3 版本,通过一系列回调函数来控制游戏玩法效果在不同阶段的行为,如应用、添加、执行等。同时,还提供了一个模板函数 FindParentComponent 用于在父类游戏玩法效果中查找相同类型的组件。

详细解释

 

    1. 类定义和特性
      • UCLASS 元数据:
        • Abstract:表示该类是抽象类,不能直接实例化,需要派生类来实现具体功能。
        • Const:表示该类的实例在运行时不会被修改。
        • DefaultToInstanced:默认情况下,该类的对象会被实例化。
        • EditInlineNew:允许在编辑器中直接创建该类的实例。
        • CollapseCategories:在编辑器中折叠类别显示。
        • Within=GameplayEffect:表示该类的对象必须存在于 GameplayEffect 对象内部。
      • 继承关系:继承自 UObject,是 Unreal Engine 中所有对象的基类。
    2. 公共成员函数
      • 构造函数 UGameplayEffectComponent():用于初始化 UGameplayEffectComponent 对象。
      • GetOwner():返回拥有此组件的 UGameplayEffect 对象指针。
      • CanGameplayEffectApply():判断游戏玩法效果规格是否可以应用到指定的活动游戏玩法效果容器上。所有组件都必须返回 true 才能允许应用,只要有一个组件返回 false 就会禁止应用。
      • OnActiveGameplayEffectAdded():当游戏玩法效果被添加到活动游戏玩法效果容器时调用,可用于控制效果是否保持活动状态。
      • OnGameplayEffectExecuted():当游戏玩法效果被执行时调用,仅在服务器端生效,用于处理即时效果的执行逻辑。
      • OnGameplayEffectApplied():当游戏玩法效果首次应用或堆叠时调用,推荐优先使用此函数来处理效果应用逻辑。
      • OnGameplayEffectChanged():当拥有该组件的游戏玩法效果被修改时调用,可用于更新组件的缓存数据等。有一个已弃用的 const 版本,建议使用非 const 版本。
  1. 编辑器相关功能
    • IsDataValid():在编辑器环境下,允许组件验证自身的数据。默认实现确保每个类只有一种类型,可重写该函数并调用基类版本。
  2. 受保护成员变量(仅编辑器环境)
    • EditorFriendlyName:在编辑器的游戏玩法效果组件索引中显示的友好名称,通过 EditCondition 控制其只在特定情况下显示。
  3. 模板函数 FindParentComponent
    • 功能:在传入组件所属的游戏玩法效果的父类中查找相同类型的组件,可用于实现属性继承。
    • 模板参数:
      • GEComponentClass:要查找的组件类型。
      • LateBindGameplayEffect:默认类型为 UGameplayEffect,用于避免包含 GameplayEffect.h 文件。
// 自定义游戏玩法效果组件类
class UMyGameplayEffectComponent : public UGameplayEffectComponent
{GENERATED_BODY()public:virtual bool CanGameplayEffectApply(const FActiveGameplayEffectsContainer& ActiveGEContainer, const FGameplayEffectSpec& GESpec) const override{// 自定义应用条件判断逻辑return true;}virtual void OnGameplayEffectApplied(FActiveGameplayEffectsContainer& ActiveGEContainer, FGameplayEffectSpec& GESpec, FPredictionKey& PredictionKey) const override{// 处理游戏玩法效果应用时的逻辑
    }
};// 使用 FindParentComponent 函数
UMyGameplayEffectComponent* ChildComponent = ...;
const UMyGameplayEffectComponent* ParentComponent = FindParentComponent(*ChildComponent);
AI生成的例子

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/886798.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

建筑遗产的保护与活化利用:历史与现代的和谐交响

在时间的长河中,建筑遗产是凝固的记忆,承载着历史的厚重与文化的底蕴。如何在尊重与保护的前提下,让这些古老建筑焕发新生,融入现代生活,成为富有功能性和时代感的场所,是当代建筑设计面临的一大挑战。 1. 尊重历史,理解遗产价值一切活化利用的出发点,首先是深入研究与…

使用crewai创建属于你自己的AI团队

crewai介绍 CrewAI 是一个用于协调自主 AI 代理的前沿框架。 CrewAI 允许你创建 AI 团队,其中每个代理都有特定的角色、工具和目标,协同工作以完成复杂任务。 把它想象成组建你的梦之队——每个成员(代理)都带来独特的技能和专业知识,无缝协作以实现你的目标。 最近使用了…

解决 element-ui table表格内容上下垂直居中的解决方法

没处理的时候是不是看着很丑只需要在需要处理的 el-table-column 标签中添加 className 然后设置样式为 vertical-align: top; 完整代码 : 然后增加对应的样式<style>.el-table .my-store-management-cell {vertical-align: top;} </style>然后就可以了

老年人19

老年人项目大概情况效果展示

Vulnhub-kioptix2014靶机getshell及提权

靶机搭建 点击扫描虚拟机然后扫描文件夹即可信息收集 扫描ip nmap扫描得到目标靶机ip nmap -sn 192.168.108.0/24故 攻击机:192.168.108.130 目标靶机:192.168.108.140扫端口和服务信息 扫描开放端口信息 nmap -p 1-65535 192.168.108.140可用信息 22/tcp closed ssh …

自然资源数据促进数字化治理能力提升

在数字化时代,自然资源数据作为国家治理体系和治理能力现代化的重要支撑,其开发利用对于推动经济社会高质量发展具有重要意义。本文将从测绘地理信息与遥感专业的角度,探讨如何推动自然资源数据要素的开发利用,以促进数字化治理能力的提升。 一、自然资源数据要素的重要性自…

老年人11

编写日常评估表的servlet层代码

git学习 -2025/2/17

git 基础操作指令 git add / git commit -m "注释" /git statusgit log[option]参数版本回退添加文件至忽略列表分支操作远程仓库 添加远程仓库 git remote add <远端名称> <仓库路径> 查看远程仓库 git remote 推送到远程仓库 命令:git push [-f] [--s…

老年人5

编写老年人信息登记表的service层的代码

ASP.NET Core 6 基础入门系列(15) 项目在IIS下部署的两种进程托管模型

系列目录 【已更新最新开发文章,点击查看详细】  ASP.NET Core 6 基础入门系列(14) 项目发布与IIS部署 ASP.NET Core 6 基础入门系列(13) Web 服务器介绍 ASP.NET Core 6 基础入门系列(12) 项目的多种启动方式及问题 ASP.NET Core 6 基础入门系列(11) 项目结构详解之项目…

ASP.NET Core 6 基础入门系列(14) 项目发布与IIS部署

系列目录 【已更新最新开发文章,点击查看详细】ASP.NET Core 6 基础入门系列(13) Web 服务器介绍 ASP.NET Core 6 基础入门系列(12) 项目的多种启动方式及问题 ASP.NET Core 6 基础入门系列(11) 项目结构详解之项目入口Program.cs ASP.NET Core 6 基础入门系列(10) 项目结…

ASP.NET Core 6 基础入门系列(1) ASP.NET Core 6.0 简介

系列目录 【已更新最新开发文章,点击查看详细】预备知识1: C#5、C#6、C#7、C#8、C#9、C#10 预备知识2: .NET 对比 .NET Framework 预备知识3: ASP.NET Core 概述 预备知识4: ASP.NET Core 与 ASP.NET 宏观对比 预备知识5: ASP.NET 请求处理机制 预备知识6: AS…