讨论群: 827072601
爱发电: https://afdian.net/@taohuayuan
任务板: https://trello.com/b/StForyw7/taohuayuan
twitter: https://twitter.com/zephyr1125
wiki: https://taohuayuanwiki.a2hosted.com
好久不见!各位猪年快乐!
Unity ECS
Unity ECS的改造终于基本完成啦,但是边探索边学习边写的代码,回头看来会有明显的一个渐进提高的过程,不过鉴于都还能正常工作,而且Untity ECS还没有最终定型,等将来ECS的稳定版本发布后再统一重构一遍吧。
在开发过程中正好赶上了Unity ECS的新版本0.0.12-p23发布,在随之更新的Samplel里新增了很重要的一个文档:Best Practices:
虽然目前内容很短,但是基本确定了一个最重要的方向问题,也就是在我之前日志里提过的多种实现方式,现在趋于统一了:
Injection和ComponentDataArray这两个方式被抛弃,IJobProcessComponentData[WithEntity]统一江湖,必要时可以使用chunk遍历获取更底层的控制。
在实际使用中,IJPCD配合此次新增的ComponentGroup.ToComponentDataArray/ToEntityArray获取观测组的组件,以及GetComponentDataFromEntity/GetBufferFromEntity获取任意目标Entity身上的组件,我目前的所有需求都得到了满足。所以现在已经很清楚了,这条路就是王道。
FlowCanvas
在Unity ECS改造中,之所以说是“基本完成”,是因为我对自己的旧Quest/Task系统有了新的想法。
在我这个项目的制作过程中,我逐渐产生了这样一种概念:ECS可以比喻为一个工厂,每一个System就是一台机械臂,根据其关心的组件“抓取”原件,将他们从一个模样改造成另一个模样。比如把所有具有Velocity的Entity身上的Position从一个值改为另一个值(也就是移动)。通过无数这样的“机械臂”,这个世界可以按照既定"规则"(Rule)运转起来。(*需要注意的是我这个比喻中,Entity过重,具有了一种组件容器的感觉,但是实质上在UnityECS下,Entity只是个用于寻找组件的id而已。)
但是,当角色在这个世界里生活的时候,会出现一些连续动作,也就是出现“过程”(Process)的时候,仅仅靠既定规则就不够了,因为角色的行为本就不是可以提前确定的既定流程,再加上玩家的操作介入,这时候就需要有一个描述过程的"订单"来列出过程,串起与此相关的机械臂们,比如“运输”包括这样一串动作“寻找空闲运输者->运输者移动到物品->运输者拿取物品->运输者移动到目的地->运输者放下物品->释放运输者”。注意其中出现了两次的移动步骤,一次是接在寻找运输者之后,另一次接在拿取物品之后。因此只靠硬性的“规则”是难以在ECS里实现这种“随机串联”机械臂的过程的。所以这个时候就需要有一个“工人”拿着“订单”为各个步骤下的产物去逐步骤“喂给”机械臂。
如果要硬编码这样的“过程”那是绝对愚蠢的,我是制作了预定义的Define文件的方式来从外部进行过程的驱动,一个例图:
这就是一个预定义的运输的define文件,我借助插件odin实现的可视化编辑与序列化。每一个这样的过程我称为quest,然后每一个节点我称为Task。在运行时有一套专用的System来进行Quest的订单维护,然后有一组System来执行Task,将他们分配到具体的System去,并且观测结果后更新Task的完成状态并通知给Quest。
当想明白这一套系统之后,我意识到这个Quest/Task系统其实最终可以用于描述游戏里的一切过程。比如建立新游戏的过程:随机地图、创建资源、创建角色、等等等。也就是说,理想的话,游戏代码中只有针对“规则”的代码,而一切“过程”都不再是硬编码的了,是可以脱离编译,易于维护,易于mod的外部配置文件。
其实这也就是很多公司正规流程中嵌入脚本语言比如lua所要实现的目的之一。只是说我是从另一个层面去殊途同归的吧。(那么我为什么不一样选择嵌入lua呢?嗯...值得思考一下)
不过现实是骨感的,我简单制作的这个Quest/Task系统有很多的缺陷,比如不直观,只能线性,手动赋值等等。直到有朋友跟我推荐了这个插件FlowCanvas。
看这个官网例图,我当时立刻就high了,这tm不就是我想要的吗?他所谓的“流”Flow正是我所谓的“过程”Process啊。而且完美解决我的所有缺陷,唯一需要做的事情就是要把它改造为适合ECS系统。于是我很快就联系了自己的好哥们找他帮忙研究,不过后来还是意识到这个跟我的核心牵扯太深,他不太好上手,于是转到我自己来做。于是FlowCanvas的改造就是我年前最后1周的工作内容了。
这是试做的一个flow。我目前对flow的改造方案是5个步骤:
- 制作占位节点用于画图。
- 输出json转成我自己的define格式,以纳入到我目前已有的一整套Define解析结构中来。
- 运行时按需基于define生成task序列entity。
- 类似旧方案的一组System对flow流程进行管理。
- 各个task序列的各自执行System。
目前试做flow的1,2,3步骤都已完成。等到全部工作完成之后,将来在制作流程的过程时如果需要新增task,只需要重复1,5两个步骤即可。
那么大年初三的工作汇报就是这样了
暂无关于此日志的评论。