UE4反射机制UCLASS() USTRUCT() GENERATED_BODY() UPROPERTY() UFUNCTION()

来源:互联网 发布:美团大数据分析 编辑:程序博客网 时间:2024/04/29 09:27

建议看看官方完整API原文链接:https://docs.unrealengine.com/latest/CHN/Programming/Introduction/index.html

游戏性类使用特殊的标记。因此在开始了解它们之前,我们有必要了解虚幻属性系统的一些基础知识。UE4 使用其自身的反射实现,可启用动态功能,如垃圾回收、序列化、网络复制和蓝图/C++ 通信。这些功能为选择加入,意味着您需要为类型添加正确的标记,否则引擎将无视类型,不生成反射数据。以下是基础标记的快速总览:

  • UCLASS() - 告知虚幻引擎生成类的反射数据。类必须派生自 UObject。

  • USTRUCT() - 告知虚幻引擎生成结构体的反射数据。

  • GENERATED_BODY() - UE4 使用它替代为类型生成的所有必需样板文件代码。

  • UPROPERTY() - 使 UCLASS 或 USTRUCT 的成员变量可用作 UPROPERTY。UPROPERTY 用途广泛。它允许变量被复制、被序列化,并可从蓝图中进行访问。垃圾回收器还使用它们来追踪对 UObject 的引用数。

  • UFUNCTION() - 使 UCLASS 或 USTRUCT 的类方法可用作 UFUNCTION。UFUNCTION 允许类方法从蓝图中被调用,并在其他资源中用作 RPC。

以下是 UCLASS 的声明范例:

#include "MyObject.generated.h"UCLASS(Blueprintable)class UMyObject : public UObject{    GENERATED_BODY()public:    MyUObject();    UPROPERTY(BlueprintReadOnly, EditAnywhere)    float ExampleProperty;    UFUNCTION(BlueprintCallable)    void ExampleFunction();};

首先注意 - “MyClass.generated.h”文件已包含。虚幻引擎将生成所有反射数据并将放入此文件。必须在声明类型的头文件中将此文件作为最后的 include 包含。

您还会注意到,可以在标记上添加额外的说明符。此处已添加部分常用说明符用于展示。通过说明符可对类型拥有的特定行为进行说明。

  • Blueprintable - 此类可由蓝图延展。

  • BlueprintReadOnly - 此属性只可从蓝图读取,不可写入。

  • Category - 定义此属性出现在编辑器 Details 视图下的部分。用于组织。

  • BlueprintCallable - 可从蓝图调用此函数。

    使属性出现在编辑器中

    类创建好之后,现在即可创建一些属性(设计师可在虚幻编辑器中设置这些属性)。使用特殊宏 UPROPERTY() 即可轻松将属性公开到编辑器。只需在属性声明之前使用UPROPERTY(EditAnywhere) 宏即可,如以下类所示。

    UCLASS()class AMyActor : public AActor{    GENERATED_BODY()    UPROPERTY(EditAnywhere)    int32 TotalDamage;    ...};

    执行这些操作后,即可在编辑器中对数值进行编辑。有多种方式控制其编辑方法和位置。为 UPROPERTY() 宏传入更多信息可完成此操作。例如:如需 TotalDamage 属性和相关属性出现在一个部分中,可使用分类功能。以下属性声明对此进行演示。

    UPROPERTY(EditAnywhere, Category="Damage")int32 TotalDamage;

    用户需要编辑此属性时,它将和其他属性(这些属性已以此类型命名标记)一同出现在 Damage 标题之下。这可将常用设置放置在一起,便于设计师进行编辑。

    现在让我们将相同属性对蓝图公开。

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Damage")int32 TotalDamage;

    如您所见,存在一个蓝图特有的参数。正是此参数使属性为可读取和可编写状态。还存在一个单独选项 - BlueprintReadOnly。可通过此选项使属性在蓝图中被识别为常量。此外还有多个选项可控制属性对引擎公开的方式

    跨 C++ 和蓝图边界调用函数

    我们已经谈到如何对蓝图公开属性,在深入探索引擎之前还有最后一个需要介绍的要点。在游戏性系统的创建中,设计师需要调用 C++ 程序员创建的函数,而游戏性程序员需要从 C++ 代码调用蓝图中实现的函数。首先,我们先实现从蓝图中调用 CalculateValues() 函数。对蓝图公开函数和公开属性同样简单。在函数声明前放置一个宏即可!以下代码片段显示了所需内容。

    UFUNCTION(BlueprintCallable, Category="Damage")void CalculateValues();

    UFUNCTION() 宏把 C++ 函数对反射系统公开。BlueprintCallable 选项将其对蓝图虚拟机公开。每个对蓝图公开的函数都需要与其相关的类型,右键单击快捷菜单才能正常使用。下图显示了类型对快捷菜单的影响。

    image alt text

    如您所见,可从 Damage 类型选择函数。以下蓝图代码显示 TotalDamage 数值发生变化后将进行调用,重新计算依赖数据。

    image alt text

    计算依赖属性使用的函数与之前添加的函数相同。引擎的大部分通过 UFUNCTION() 宏对蓝图公开,开发者无需编写 C++ 代码即可构建游戏。然而,最佳方法是使用 C++ 构建基础游戏性系统和与性能关系密切的代码,而蓝图则用于自定义行为或从 C++ 构建块创建合成行为。

    实现设计师调用 C++ 代码的操作后,我们来寻找一个越过 C++/蓝图边界的好方法。此方法允许 C++ 代码调用蓝图中定义的函数。通常使用此方法告知设计师在适当时可进行反馈的事件。通常这包括特效生成或其他视觉效果,如 actor 的隐藏和现身。以下代码片段显示蓝图实现的函数。

    UFUNCTION(BlueprintImplementableEvent, Category="Damage")void CalledFromCpp();

    此函数的调用方式和其他 C++ 函数相同。虚幻引擎在后台生成一个基础 C++ 函数实现;它理解如何调入蓝图 VM。这通常被称作 Thunk(形实转换程序)。如讨论中的蓝图不为此方法提供函数主体,函数的行为则与不含主体行为的 C++ 函数一样:不执行任何操作。如果希望提供 C++ 默认实现,同时仍允许蓝图覆写此方法,结果会怎样?UFUNCTION() 宏也拥有针对此情况的选项。以下代码片段显示达成此效果需要在头中进行的的变更。

    UFUNCTION(BlueprintNativeEvent, Category="Damage")void CalledFromCpp();

    此版本仍然生成 thunking 法,以调入蓝图 VM。那么如何提供默认实现呢?工具还将生成外观与 _Implementation() 相似的新函数实现。您必须提供函数的这个版本,否则项目将无法链接。以下是上方声明的实现代码。

    void AMyActor::CalledFromCpp_Implementation(){    // 玩点花活}

    现在,讨论中的蓝图不覆写方法时将调用函数的这个版本。需要注意:在编译工具的旧版本中,_Implementation() 声明为自动生成。在 4.8 或更高版本中,这会被显式添加到头中。

  • 本文转自:http://blog.csdn.net/a359877454/article/details/52515290

0 0
原创粉丝点击