Meta编辑器

Meta简介

Meta属性系统是一个数据驱动的属性编辑系统,主要目的在于方便TA等非程序职能的同学在不修改代码的前提下,通过用Meta编辑器修改工具使用的Meta数据,改变工具内的属性编辑界面和保存的属性json文件,达到动态扩展工具的效果。

入口

通过Pangu窗口-菜单栏-Tools-Meta Editor进入Meta编辑器 Entry

Meta使用场景

目前Meta编辑的应用场景主要有两种 1.配置一种新的曲线 2.修改界面Meta属性

配置一种新的曲线

详细步骤可参考如何配置不同子系统所需的曲线

修改界面Meta属性

用户也可以可以通过修改Meta字段,控制创建的细节面板UI,下面的视频展示了几个典型的例子

  • 修改Float的Min、Max、Precision字段,控制ScrollBar的拖拽上下界的有效数字
  • 修改Color的ShowAlphaChannel字段,控制Color Picker是否包含Alpha通道
  • 修改Asset的AssetType字段,控制AssetDropTarget下拉菜单的可选资产范围
  • 修改Bool的Text字段,控制生成Bool属性的展示名称(可使用中文进行本地化)

编辑器界面总览

Overview01 Meta编辑器的预设部分 Overview02

编号名称简介
基础栏包含新建一份Meta数据,保存当前的Meta数据到某个文件,从某个文件加载Meta数据,展示当前Meta的文件名称等功能
Meta编辑界面主要负责增加和删除Meta数据,修改某个Meta数据的类型和名称
Meta字段编辑界面选中Meta编辑界面中的某个Meta后展示其属性细节
状态切换栏切换属性预览界面和预设编辑界面
属性预览界面展示编辑的Meta生成的属性的最终预览效果
预设编辑界面通过在④的Preview中选择Preset切换到预设编辑器界面。创建某一套属性的预设,依次是切换回预览属性,创建预设按钮,删除预设按钮,切换预设的下拉菜单

基础栏

area1

基础栏部分包含了Meta编辑器的几个最基础的按钮

  • New按钮: 在Meta编辑界面创建一个空的Meta属性
  • Save按钮: 点击后可指定json文件保存Meta编辑界面编辑的Meta数据
  • Load按钮: 点击后可从本地选取一个Meta文件, 加载其中的Meta数据
  • Show File in Explorer按钮: 在文件浏览器中展示当前编辑Meta文件所在位置

Meta编辑界面

area2 Meta编辑界面的各部分功能如下

序号模块释义
搜索栏用于快速过滤指定名称的Meta
Meta名称双击可重命名Meta,也可以通过长按拖拽调整同一层级下的Meta顺序
Meta类型通过下拉菜单调整Meta的类型, 详细说明见下表
Meta增删栏可以对Struct一类的多子Meta的容器进行增加,删除,清空等操作

Meta类型

Meta的类型意义
Bool创建一个Bool属性
Int创建一个Int属性
Float创建一个Float属性
Str创建一个String属性
Color创建一个Color属性
EnumInt存储枚举String->int的映射,用户通过下拉菜单选择枚举string,在json中保存int
EnumFloat存储枚举String->float的映射,用户通过下拉菜单选择枚举string,在json中保存float
EnumString存储枚举String->string的映射,用户通过下拉菜单选择枚举string,在json中保存string
Asset创建一个可由用户设置uasset, 保存uasset路径的属性
Class创建一个保存UE class名称的属性
Vector创建一个保存Vector3的属性
Vector4创建一个保存Vector4的属性
Vector2D创建一个保存Vector2的属性
Path保存一个Pangu Content/Kaitian下的相对路径(不推荐使用绝对路径)
FloatRamp用于创建Ramp类型的点线图,属性会保存点的Float坐标
Proxy(Special)Meta引用,可引用另一个Meta文件中的数据进行Meta嵌套
Array(Container)容器类型,包含一个子Meta。生成的Array容器属性可以动态添加
FixArray(Container)容器类型,生成的FixArray容器属性下面的所有属性Meta数据全部一致,固定长度
Dict(Container)容器类型,类似Array包含一个子Meta, 生成的Dict容器属性下面的所有属性可以设置key且可动态添加
Struct(Container)容器类型,可包含任意数量的子Meta

1.基础类型Meta

基础类型Meta与生成UI一一对应。一个Meta Color最终会在细节面板上生成一个对应的ColorPicker组件, Meta Asset在细节面板生成一个Asset设置器, 其他的基本类型Meta依次类推,如下图 BasicMeta

2.容器类型Meta

对于容器类型的Meta, Meta内部可以嵌套任意类型的子Meta。子Meta可以是任意类型的Meta(也包括容器类型本身),从而实现无限嵌套的能力。 Meta Struct容器内部能够添加任意数量的子Meta, 可以在Meta编辑区域通过Struct后面的加号和子Meta后面的减号来增删Struct中的Meta数量 StructMeta

Meta Array容器内部包含一个子Meta, 生成的Array属性容器可以任意增删子Attribute,子Attribute根据Array的子Meta构建,如下图。(Meta FixArray同Meta Array, 区别在于FixArray创建的属性子Attribute的数量是固定的,等同于FixArray的Meta字段中设置的Size) ArrayMeta

Meta Dict容器大致类似于Meta Array, 也是包含一个子Meta,生成的Dict属性可以任意地增删子Attribute。区别在于Dict生成的每个Attribute都可以设置一个Key值,用于根据Key值快速遍历出需要的子Attributes。 DictMeta

3.特殊类型Meta

Meta支持利用Meta Proxy引用其他的Meta, 通过设置Proxy Path字段的引用路径,实现对其他Meta的复用和Meta之间的组合逻辑。 ProxyMeta

Meta字段编辑界面

area3

Meta字段编辑界面的字段对应的含义如下:

通用属性

属性说明
Default属性的默认值
Tab所属Tab页签
Category所属分类
Text属性在编辑器中的显示名称
Tips鼠标移上去显示的Tips
Editable属性在编辑器中是否可编辑(反过来就是是否只读)
Visible属性是否可见
Sort属性显示顺序,数字越小越靠前
Optional属性是否是可选
Auto Expand对于容器类型,属性面板展示时是否自动展开子元素

高级属性

属性说明
Created Callbacks属性被加载时触发的回调逻辑
Value Changed Callbacks属性被修改时触发的回调逻辑
Visibility Conditions控制当前属性可见与否的条件, 例如VisibilityConditions 当表达式计算结果为true时该属性可见,目前仅支持数字计算表达式
Edit Conditions控制当前属性可被编辑的条件, 写法同Visibility Conditions

各Meta类型专属属性

以下属性需要在Meta编辑界面中选中需要编辑的Meta后,才会显示在Meta字段编辑界面中。比如选中的Meta为Int类型,那么Meta字段编辑器界面中才会含有Int属性分栏。

Int专属属性

属性说明
Min编辑器可以设置的最小值
Max编辑器可以设置的最大值
Slider是否有滚动条

Float专属属性

属性说明
Min编辑器可以设置的最小值
Max编辑器可以设置的最大值
Precision精度,精确至小数点后’x’位(输入值)
Slider是否有滚动条

Str专属属性

属性说明
PlaceHolder占位字符串
Required是否必须填数值

Color专属属性

属性说明
ShowAlphaChannel是否可编辑alpha值

EnumInt/EnumFloat/EnumString专属属性

属性说明
EnumItems储存展示下拉菜单栏到保存值(int, float, string)的对应关系
EnumItems支持添加多个映射关系,组成EnumInt/EnumFloat/EnumString类型Meta字段的下拉列表的选项

Asset专属属性

属性说明
AssetType可填入资产的类型,不设置可填全部类型

Class专属属性

属性说明
ParentClassType可填入UE类型的父类

Vector/Vector4/Vector2D专属属性

属性说明
Precision精度,小数点后位数

Path专属属性

属性说明
IsDirectionPath是否限制为文件夹/文件
Base文件夹/文件的存储方式,可选的存储绝对路径, 存储相对于Content、ArtData、HouTools、PcgMaps的路径
Format可选的文件格式

Proxy专属属性

属性说明
Path引用的Meta文件路径

Array专属属性

属性说明
MaxSize数组所能添加的最大元素容量

FixArray专属属性

属性说明
Size固定数组的容量

状态切换栏

area4

状态切换栏: 通过在Preview后面的下拉菜单,在属性预览状态(Default)和预设编辑状态(Preview)两种状态下切换。属性预览见属性预览界面,预设编辑见预设编辑界面

属性预览界面

area5

①. 顶部按钮

  • Save as Default按钮: 将当前属性预览面板的属性修改值保存到Meta作为默认值
  • Revert to Default按钮: 使属性预览面板的全部属性应用Meta的预设值 ②. 面板展示Meta编辑区的Meta生成属性的UI实际效果,用于预览编辑的Meta是否符合预期。可在此面板上任意编辑实验
  • Export To按钮:将当前预览的属性导出为指定的json文件,用于确认属性输出的文件是否符合预期。

预设编辑界面

area6 预设功能以快速批量设置属性值。用户可以在Meta编辑器中切换到Preset模式设置模式,勾选需要存储的属性预设设置值并保存到Meta后,就可以应用预设到编辑器的细节面板。

预设界面可以在编辑的Meta中保存几组属性预设值(可部分预设),保存的属性预设可以使Pangu界面中Meta生成的属性快速应用预设值。

序号模块释义
顶部按钮Preview:可切换属性预览/预设编辑状态
Preset: 在不同的Preset之前切换
Create: 创建新的预设, 预设编号自动递增,在弹出输入框中可以输入预设的名称
Rename: 重命名当前的预设
Delete: 删除当前的预设
搜索栏用于快速过滤指定属性
编辑界面基本和属性预览界面的属性预览面板相同,可自由编辑
勾选框勾选中的属性会成为需要保存的预设属性。当在Pangu编辑器中应用预设时,保存的预设属性值会覆盖Pangu编辑器中对应属性值,未保存的不会产生任何影响

下面是视频展示

其他

项目自定义扩展Meta及Meta存储位置

用户可以通过Inherit Meta进行项目的自定义扩展。Meta是Kaitian数据的源头,也是Pangu Editor部分界面数据的源头,Pangu为了区分项目自定义与官方的Meta,在属性界面上,区分显示不同的颜色。

下表以默认的项目SharePrj为例

颜色存储位置含义
绿色avatar./PanguForUnreal/Plugins/Pangu/Config/Meta模板Templates,公用模板用户不可以修改,可基于公用模版,继承同样的Meta资产并继续修改,继承方式为在Meta生成的数据处右键点击执行 Inherit Metaavatar
黄色avatar./PanguForUnreal/Config/Pangu/SharePrj/Meta继承的Meta属性,可修改上传提交

Meta属性的右键菜单说明

ModifyMeta 如图所示, 对于Pangu编辑器中的属性界面,右键点击时可以召唤出弹出菜单

  • Show in explore: 在文件浏览器中展示当前的属性json所在位置
  • Export attribute: 导出当前编辑的属性数据到json中
  • Show meta in explore: 在文件浏览器中展示当前属性的Meta对应json所在位置
  • Inherit Meta/Edit meta: 点击会弹出类似Meta编辑器的界面,可以进行当前属性的Meta的修改(Inherit Meta会在项目未自定义时展示,Edit meta会在用户已经对Meta自定义时展示)
  • Load preset: 通过下拉菜单将对应编号的预设应用到当前属性上

在编辑器界面中插入Meta细节面板(程序向)

调用LoadAttrContainer指定Attribute Root的Meta json路径,Attribute json路径

UAttrRoot* ProxyInfo =  UMetaAttributeSystem::Get()->LoadAttrContainer(GetMetaPath(), GetAttrPath(), InOuter);

在外层的MetaBase对象上持有Attribute Root对象, 并在GetMetaViewArgs中指定

UPROPERTY(meta=(UIType=SObjectMetaView, bAllowSearch=false))
UAttrRoot* ProxyInfo;

就可以在外层MetaBase创建的UI中找到动态Meta创建的细节面板 CreateDetail

用户可以不修改一行代码,编辑属性面板的Meta数据,生产自己需要的属性细节面板

编辑器数据联动说明(程序向)

Meta生成的属性支持通过触发OnValueChanged回调,实现与编辑器中的其他数据的联动效果。如下图所示,曲线的属性界面由Meta生成,当属性值非Default值时,曲线控制点的颜色联动变红,属性回退到Default值后控制点变回原来的颜色 CustomLayoutLayer

用户的编辑方式如下图, 在Meta中设置OnValueChanged回调函数SetSpriteOverrideColor和颜色参数。由开发编辑器的程序在曲线控制点类中完成UFunction SetSpriteOverrideColor,实现属性值非Default曲线控制点变色的逻辑。修改属性时,MetaAttribute系统会通过反射执行设置的回调 CustomLayoutLayer

项目扩展Meta说明(程序向)

MetaToUI官方提供了一系列的通用Meta, 项目如果有扩展Meta类型的需求,可以通过继承Meta的方式实现自定义扩展。

以UPanguMetaLayoutLayer类型为例, 项目提出了一种通用Meta不支持的复杂下拉菜单UI类型。可以通过创建继承自UMetaValue的UPanguMetaLayoutLayer类型,实现下面必要的成员定义和虚函数

UCLASS()
class PANGU_API UPanguMetaLayoutLayer : public UMetaValue
{
    GENERATED_BODY()

public:
    // Meta序列化到json文件的名称
    const static FString MetaType;
    // 注册Meta类型
    virtual const FString& RegisterType() override { return UPanguMetaLayoutLayer::MetaType; }
    // 声明Meta创建的Attribute类型
    virtual TSubclassOf<UAttrM2U> GetAttrClass() const override;
    // 实现创建Widget UI的逻辑
    virtual TSharedRef<SWidget> CreateValueWidget(const TArray<UAttrM2U*>& InAttrs) const override;

protected:
    TArray<FString> OptionSource;
};

在项目模块初始化的时候,向MetaToUI的AllMetaTypes注册自定义的UPanguMetaLayoutLayer(注册的先后顺序决定Meta在Meta编辑编辑器的前后排序)

AllMetaTypes().Emplace(UPanguMetaLayoutLayer::MetaType);

然后实现UPanguMetaLayoutLayer对应的Attribute类型UPanguAttrLayoutLayer,实现下面的序列化、必要的Getter&Setter等逻辑

UCLASS()
class PANGU_API UPanguAttrLayoutLayer : public UAttrValue, public TAttrInterface_v<UPanguAttrLayoutLayer>
{
    GENERATED_BODY()

public:
    // 声明Attribute存储的数据类型
    using ValueType = FLayoutLayer;
    // 实现序列化到Json的逻辑
    virtual TSharedPtr<FJsonValue> ExportAttrToJsonValue() const override;
    // 实现从Json反序列化的逻辑
    virtual bool ImportAttrByJsonValue(const TSharedPtr<FJsonValue> JsonValue) override;

    // 实现从Json反序列化的逻辑
    FLayoutLayer& GetValueRef() { return Value; };
    const FLayoutLayer& GetValue() const { return Value; };
    virtual bool SetValue(const FLayoutLayer& InValue);

protected:
    // Attribute存储的数据类型
    UPROPERTY()
    FLayoutLayer Value;
};

就可以在Meta编辑界面选取PanguLayoutLayer类型,生成复杂的下拉菜单。

CustomLayoutLayer LayoutLayerShow