UE5 runtime 编辑器的实现思路(二)

前言

书接上回,在介绍完整个编辑器框架的实现逻辑后,接下来讲解一下编辑器的各个模块的具体功能实现,市面上大多数数字孪生相关的编辑器都比较简单,当然一方面因为以前的数字孪生业务都比较单一化,偏向于电子沙盘,也不需要复杂的功能,还有一部分原因是数字孪生的业务功能模块也很难抽象出来,大都是订制开发,与其做一个runtime的编辑器还不如用ue直接上,特别是前几年,大量的电子沙盘类的孪生大屏,业务表达单一,后续没有人维护,数据也没有更新和关联,一锤子买卖的项目,称其为“数字垃圾”也不为过。当然最近几年,业务方对数字孪生的项目交付要求也越来越高:超大场景的渲染,数据的实时更新维护,iot数据的接入,仿真模拟,项目的全流程管理,多端协同,等等。当然也有一些大佬基于slate开发的较为复杂的runtime编辑器界面,这里我还是基于quiet runtime editor来讲解一下各个runtime模块的实现。

1.大纲视图

大纲结构树

首先是大纲的umg的container的结构:

通过WBP_OutlinerItemWidget嵌套WBP_OutlinerBranchWidget再嵌套WBP_QuietOutlinerWidget

其中item widget负责每个item名字,类型,点击高亮,选择等和场景中物体一一对应等功能实现。

branch widget负责搜索,父子关系,打组,合并/展开,拖拽等相关逻辑的实现。

OutlinerWidget负责最终把branch合并成tree。

大纲的抓取

抓取场景中的actor:

在生成大纲之前,场景中已经有manager的相关actor叫quiet tree manager,所有和场景相关的逻辑都会在这个manager bp里实现,毕竟actor可以很方面的拿到level的引用,并且也能把场景的管理和ui的逻辑解耦。

manager里抓取场景actor并且生成大纲item的大概逻辑如下:

其中比较关键的是world treecomponent,这个有点东西,意思是只要有带有这个component的actor都会被manager bp管理起来,包括相关的name,guid,属性,和最终的序列化的读取和保存都在写在这个component里,这样的话也能和actor本身的逻辑解耦开,麻烦的是要在这个component里写一堆的判断outer的逻辑,先判断类型,再执行相关操作

大纲父子关系

动图封面

这部分分两块,ui操作的实现和三位场景的联动

新建一个actor到大纲中

先看效果:

动图封面

首先可拖拽的组件分两种,一个是工具栏上的灯光,box,sphere等基本物体,还有是资源池里的模型,蓝图等物体。

这里先说前者,工具栏上的按钮都继承自一个toolbar smart button的组件,

作者非常机智的封装了icon,mode,command等参数,可以实现按钮,checkbox,拖拽,radiobutton等操作也基本涵盖了工具栏上的按钮常用操作,这里先说拖拽。

大致逻辑如下:

总的来说就是在umg里触发dragdrop操作,再通过一个事件代理触发actor的spawn,这里这个作者又一次很机智的使用了ue的gameplay tag,方便的定义了不同ui状态下三维场景的不同操作

最终在之前说的treemanager的bp里做和场景相关的操作,(新建actor执行的是register actor):

register actor执行的具体逻辑如下:

大致流程是new一个actor后,新建一个json,记录相关的field,添加到大纲中,对新的物体命名(包括查重等操作),

其中比较有意思的是:

这里面封装了大纲中物体的常规操作(包括物体的显示隐藏,hover,命名等等操作):

还有用蓝图生成唯一displayname的逻辑:

资源窗口

效果如下:

动图封面

umg结构:

主要是用的tileview来嵌套item,tileview的好处是可以自动适配要素的大小,并且和继承自listview,可以使用entry class widget,适合大量要素的滚动查看和选择等操作,而且性能很好

动图封面

资源抓取

这里讲的是从ue的content browser中抓取已经挂在到工程里的资源,asset是可以通过path找到的,资源的热更不在讨论范围内,

首先有两大类资源,文件夹和asset,

文件夹通过get当前目录下的sub path,然后排除掉特定目录,然后construct 一个folder的umg,添加到tileview中。

asset的抓取,蓝图也提供了相应的接口

这里建议新手要注意区分object path,package name,package path等等的区别和应用场景

如果要做按资源类型递归检索,要把recursive勾上即可,然后通过string判断asset的类型

动图封面

最后在对文件夹目录个资源进行排序,蓝图排序string有点麻烦,还不如c++抄一段代码过来

缩略图的生成

蓝图生成缩略图是有点曲线救国的,c++的话可能更方便,但是本质原理都一样,架一个相机,拍一张rt,存下来,

首先新建一个bp,用来拍缩略图

在需要生成缩略图的时候spawn,应该只有模型和材质需要thumbnail,毕竟文件夹和贴图的thumbnail直接就有了

另外要注意生成mesh和材质缩略图的时候,逻辑稍有不同,材质是赋在一个球上面,再拍,模型是直接拍

记得根据物体的boundingbox动态调整capture2d的位置和角度

拍完后的图可以存在本地,记录相应的json字段,下次就不用从新拍了

记得capture后删掉用来生成thumbnail的actor,以防止场景中多出来灯光

材质编辑

创建材质实例

content browser里的实例材质资源类型是material instance constant,如果需要在场景中动态修改参数,需要先创建一个material instance dynamic。

00:15

然后根据parameter更改material dynamic instance的预览参数样式

在场景中拖拽材质

动图封面

可以通过linetrace,hit 的component物体的face index来获得mesh的material index

详情面板

00:12

所有的拖拽都是通过umg的drap drop函数实现,当drag detected的时候,在场景中spawn 物体,并且设置位置

判断actor spawn的位置依然是使用linetrace

由于这套quiet runtime editor对每一种component的detail的参数都做了序列化的保存,比较麻烦的是要预先手动设置序列化参数的结果,最终再去根据序列化的结果生产对应的datail 面板

Debug View

本来很好奇场景中的Light的debug框是怎么生成的,结果发现都是mesh

00:04

在改变灯光参数的时候,改变debug mesh的scale即可

截图

ue自带的high res shot可以默认截图全屏,也可以截指定的viewport范围大小,可以通过图片所示蓝图拼接截对应范围的图片

00:06

总的来说quiet runtime editor这一套runtime下的编辑器框架很有参考价值,包括使用蓝图的json插件对object的参数进行序列化,读取保存,还有game play tag的蓝图通信都给我很大启发,抽时间也把这部分详细讲一下,也在平时的开发工作中参考了相关思路。

猜你喜欢

转载自blog.csdn.net/ttod/article/details/135139214