使用Unity ECS简单实现物体的移动

最近和我的良师兼益友研究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,上面的地址可以看到这个效果,不过需要翻墙,有兴趣的可以了解下。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
UnityECS实现物体拖尾效果的基本步骤如下: 1. 创建一个自定义的拖尾组件,该组件包含一个数组来存储每个帧的位置和旋转信息,以及一个变量来指定拖尾的长度。 2. 在Update系统中,将当前帧的位置和旋转信息添加到拖尾组件的数组中,并删除超出拖尾长度的旧帧信息。 3. 使用渲染系统在每个帧之间绘制线条,将拖尾效果呈现出来。可以使用LineRenderer组件或Graphics.DrawMeshInstanced来实现。 以下是一个简单的示例代码,用于演示如何在UnityECS实现物体拖尾效果: ```csharp using Unity.Entities; using Unity.Mathematics; using Unity.Transforms; using UnityEngine; public struct TrailComponent : IComponentData { public float3[] positions; public quaternion[] rotations; public int currentIndex; public int maxTrailLength; } public class TrailSystem : SystemBase { protected override void OnUpdate() { Entities.ForEach((Entity entity, ref Translation translation, ref Rotation rotation, ref TrailComponent trail) => { // Add current position and rotation to trail trail.positions[trail.currentIndex] = translation.Value; trail.rotations[trail.currentIndex] = rotation.Value; trail.currentIndex = (trail.currentIndex + 1) % trail.maxTrailLength; // Draw trail var lineRenderer = EntityManager.GetComponentObject<LineRenderer>(entity); lineRenderer.positionCount = trail.maxTrailLength; for (int i = 0; i < trail.maxTrailLength; i++) { int index = (trail.currentIndex + i) % trail.maxTrailLength; lineRenderer.SetPosition(i, trail.positions[index]); } }).Schedule(); } } public class TrailBootstrap : MonoBehaviour { public GameObject trailPrefab; private void Start() { var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; var trailEntity = entityManager.CreateEntity(); entityManager.AddComponentData(trailEntity, new TrailComponent { positions = new float3[10], rotations = new quaternion[10], currentIndex = 0, maxTrailLength = 10 }); entityManager.AddComponentData(trailEntity, new Translation { Value = Vector3.zero }); entityManager.AddComponentData(trailEntity, new Rotation { Value = Quaternion.identity }); var lineRenderer = trailPrefab.GetComponent<LineRenderer>(); entityManager.AddComponentObject(trailEntity, lineRenderer); } } ``` 在此示例代码中,我们创建了一个名为TrailComponent的自定义组件,该组件包含一个float3数组来存储位置信息,一个quaternion数组来存储旋转信息,以及一个整数变量来指定拖尾的最大长度。我们还创建了一个名为TrailSystem的系统,该系统在每个帧中将当前位置和旋转信息添加到TrailComponent中,并使用LineRenderer组件将拖尾效果呈现出来。最后,我们在TrailBootstrap脚本中创建了一个拖尾实体,并将LineRenderer组件添加到该实体中。 注意:在使用LineRenderer组件时,需要将其设置为使用“Local”空间,并将其材质的渲染模式设置为“Transparent”。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值