最近和我的良师兼益友研究unity 18版本的新功能ECS,如上图,场景内只有这几个GameObject,然后只有Settings是添加了脚本,PlayerRenderPrototype是添加了组件的,其中PlayerRenderPrototype的GameObjectEntity组件是在加了MeshInstanceRenderer后unity自动添加的,而且要想让物体响应ECS,就必须需要这个组件,MeshInstanceRenderer组件和Settings脚本并没有任何的逻辑,一个是显示物体的mesh组件,另一个是设置角色移动速度的字段。然后点击运行后就会生成一架飞机,并按照一定的速度朝某个方向移动,接下来看源码。
1.首先是StartRoot脚本
首先Init方法上面的标签的意思是在场景加载前就运行,也就是先生成EntityManager和一个带有Position组件的原型,InitializeAfterSceneLoad这个方法是场景加载后运行的,就是找到场景里的Settings,由于我还有其他测试场景,所以就在两个方法里都加了查找Settings的判断,然后获取Player的Mesh,接着就是生成一个Entity,并设置初始坐标以及mesh。
2.Settings脚本
这个脚本就只是定义了一个移动速度的字段,然后继承MonoBehaviour,可以在外面修改数值。
3.PlayerMoveComponent脚本
这个脚本也只有数据,定义了一个结构体,里面只有一个速度的字段,但在我写的方式这是用不到的,其他方式可以用到,ECS的理念是数据和行为分开,不是面向对象,而是面向数据。
4.重要的来了,或者说真正使飞机移动的脚本是PlayerMoveSys(或PlayerMoveSystem)
这个脚本继承的是ComponentSystem,就是类似于控制component的系统,也就是在这里写一些逻辑,但并不需要挂载到游戏物体上,这种方式让我懵逼了一段时间。首先就是写一个结构体,Length的字段貌似是固定需要写的,不是很清楚,但运行后会在OnUpdate里自动注入Length的值。接着[Inject] private MyData m_Data;就是将我的结构体注入,应该就是反射吧,对反射并不是很清楚,这个m_Data 有点类似于group,如果尝试过用group来获取Entity的话应该会明白相似处。接着在OnUpdate里更新entity的坐标就行了。
下图是最绚丽的效果 https://unity3d.com/cn/learn/tutorials/topics/scripting/using-burst-compiler?playlist=17117
左图中左上角显示当前场景里共有15612个飞机模型,但FPS为150,上面的地址可以看到这个效果,不过需要翻墙,有兴趣的可以了解下。