赞
踩
书接上回,在介绍完整个编辑器框架的实现逻辑后,接下来讲解一下编辑器的各个模块的具体功能实现,市面上大多数数字孪生相关的编辑器都比较简单,当然一方面因为以前的数字孪生业务都比较单一化,偏向于电子沙盘,也不需要复杂的功能,还有一部分原因是数字孪生的业务功能模块也很难抽象出来,大都是订制开发,与其做一个runtime的编辑器还不如用ue直接上,特别是前几年,大量的电子沙盘类的孪生大屏,业务表达单一,后续没有人维护,数据也没有更新和关联,一锤子买卖的项目,称其为“数字垃圾”也不为过。当然最近几年,业务方对数字孪生的项目交付要求也越来越高:超大场景的渲染,数据的实时更新维护,iot数据的接入,仿真模拟,项目的全流程管理,多端协同,等等。当然也有一些大佬基于slate开发的较为复杂的runtime编辑器界面,这里我还是基于quiet runtime editor来讲解一下各个runtime模块的实现。
首先是大纲的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操作的实现和三位场景的联动
先看效果:
首先可拖拽的组件分两种,一个是工具栏上的灯光,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的逻辑:
效果如下:
主要是用的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 面板
本来很好奇场景中的Light的debug框是怎么生成的,结果发现都是mesh
00:04
在改变灯光参数的时候,改变debug mesh的scale即可
ue自带的high res shot可以默认截图全屏,也可以截指定的viewport范围大小,可以通过图片所示蓝图拼接截对应范围的图片
00:06
总的来说quiet runtime editor这一套runtime下的编辑器框架很有参考价值,包括使用蓝图的json插件对object的参数进行序列化,读取保存,还有game play tag的蓝图通信都给我很大启发,抽时间也把这部分详细讲一下,也在平时的开发工作中参考了相关思路。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。