UPROPERTY 说明符示例
反射是程序在运行时进行自检的一种能力。它非常有用并且是虚幻引擎中的基础技术,支撑了诸如编辑器中的细节面板、序列化、垃圾回收、网络复制、以及蓝图与C++交互等功能。
C++原生并不支持任意形式的反射,因此虚幻引擎有它自己的系统用来利用、查询以及操作关于C++类、结构体、函数 、成员变量以及枚举的信息。
给暴露给反射系统的类型或属性添加注解,这样 Unreal Header Tool (UHT) 就会在编译工程的时候利用那些信息生成特定的代码。目前可以使用 UENUM()、UCLASS()、USTRUCT()、UFUNCTION()、以及 UPROPERTY() 来在头文件中注解不同的类型以及成员变量。
这些宏可以标记在类型或者成员变量的前面,并且可以包含额外的说明符(又称修饰符)和关键字,使用这些说明符,可以基于反射快速的完成一些特殊的功能,对于编辑器开发而言,基于这些说明符,也能让我们快速完成细节面板的开发,因此本文也主要针对 UPROPERTY() 与 UFUNCTION() 在编辑器细节面板开发中常用的几种说明符使用方法进行讨论。
一、热编译
在插件开发的过程中,尤其是 UI 的开发过程中,可以使用 UE 的热编译功能,这样在我们简单的修改了说明符后,不需要重新启动工程就可以查看 UI 变化效果。
热编译控制入口在引擎的右下方,单击此处进入 Settings...
在红框处,可以填写我们需要热编译的插件,提升编译速度。修改后提示重启,重启即可。
重启后在我们在代码里进行修改后,在 VS 或 Rider 按键盘快捷键 Ctrl + Alt + F11 (或点击刚刚右下角的热编译按钮)即可开始热编译,不需要在 IDE 重新编译工程,重启 UE。
二、系统案例
1.系统案例
UE 自己提供了一个 UPROPERTY 说明符的参考案例,但是不知道为什么,无论官方文档,或是其他博客都很少提到这一点,笔者在官方论坛的一条回复里发现了这一功能。
在 UE 的 cmd 键入 testprops,即可打开示例界面
这里的功能应该能满足大部分的开发需求,不能满足的可能需要 DetailCustomization 来完成。
此示例源码位于:Engine\Source\Editor\UnrealEd\Classes\Editor\PropertyEditorTestObject.h
2.说明符定义
说明符定义:Engine\Source\Runtime\CoreUObject\Public\UObject\ObjectMacros.h
系统中定义说明符时添加的注释也挺详细,也可以在这里查找相关用法。
三. 常用说明符总结
笔者记录此文,主要还是想总结下开发中经常用到的一些说明符,也是避免遗忘。
官方文档链接如下,虽为官方文档,但也不全,仅供参考
属性关于为Gameplay类创建和实现属性的参考。
此处文章总结的很全 benui UPROPERTY
不仅给出了示例,很多示例还贴出了 gif,和笔者的示例比起来属实是小巫见大巫了,既然如此,笔者也便不再赘述相关说明符的使用方式,可以查看上述文章。
这里只保留部分链接中未提到的部分。
4.使用自定义 Tag 对需要显示的属性进行过滤
直接反射系统类的细节面板时,可能有很多属性是我们所不需要的,这种时候可能需要对我们想要显示的属性进行过滤,可以通过添加自定义 Tag 的方式来实现。
我们想要的属性标记一个我们自定义的统一的 Tag。
反射生成自定义面板时,指定属性显示的代理绑定到一个控制显隐的函数即可:
DetailsView->SetIsPropertyVisibleDelegate(FIsPropertyVisible::CreateRaw(this, &FXXXCtrl::GetIsPropertyVisible));
函数里,利用我们自定义的统一的 Tag 即可完成过滤。
UPROPERTY(EditDefaultsOnly, meta = (MyCustomTag))
FLinearColor Color;
bool FXXXCtrl::GetIsPropertyVisible(const FPropertyAndParent& PropertyAndParent) const
{
if (PropertyAndParent.Property.HasMetaData("MyCustomTag"))
{
return true;
}
return false;
}
5. 使用 USTRUCT 对数据进行管理
系统中很多的属性会使用 USTRUCT 来进行管理,那么如何使用 USTRUCT 又能保证效果与直接定义在头文件中相同呢?这里与一些说明符的作用机制有关。
-
自定义 Tag
经笔者测试,上文中使用自定义 Tag 过滤显示属性的方式对于 USTRUCT 包裹的属性亦能生效,只有在 USTRUCT 属性说明符与 USTRUCT 内部属性说明符均指定 Tag 的情况下才会被过滤出来。 -
ShowOnlyInnerProperties
此说明符用于控制 UPROPERTY struct 属性的层级显示方式,添加此说明符后,struct 内部属性不会以层叠方式展开,而是提升到与外部 Category 一个层级。USTRUCT() struct FCat { GENERATED_BODY() UPROPERTY(EditDefaultsOnly, meta = (MyCustomTag)) FString Name; UPROPERTY(EditDefaultsOnly, meta = (MyCustomTag)) int32 Age; UPROPERTY(EditDefaultsOnly, meta = (MyCustomTag)) FLinearColor Color; };
UPROPERTY(EditAnywhere, Category="Cat Without ShowOnlyInnerProperties", meta = (MyCustomTag)) FCat Cat1; UPROPERTY(EditAnywhere, Category="Cat2 With ShowOnlyInnerProperties", meta=(ShowOnlyInnerProperties), meta = (MyCustomTag)) FCat Cat2;
-
下拉列表
benui UPROPERTY 文章指出,GetOptions 会从继承关系中寻找可以使用的函数,找到第一个作为返回列表的方法使用,因此我们应该可以在持有 Struct 的 Section 类中定义数组以及返回对应数组的 UFUNCTION,指定 Struct 的 GetOptions 说明符来完成下拉列表的需求。
Comments NOTHING