unity2019 ECS入门实例:创建一个Entity
程序员文章站
2022-06-25 17:30:45
Unity2019 ECS 入门实例:创建一个Entity一. 前言本篇要实现创建一个实体,并将这个Entity在场景中显示出来,用ECS框架来解释就是创建一个Entity,并为这个Entity添加ComponentData从而完成上述功能.按我的理解Entity≠GameObject,而 GameObject = (Entity + Component(data) +System)想要在场景中显示物体肯定要有Mesh(形状)和Material(材质),所以我们要做的是为Entity添加这些Com...
Unity2019 ECS 入门实例:创建一个Entity
一. 前言
本篇要实现创建一个实体,并将这个Entity在场景中显示出来,用ECS框架
来解释就是创建一个Entity
,并为这个Entity
添加ComponentData
从而完成上述功能.
- 按我的理解
Entity≠GameObject,而 GameObject = (Entity + Component(data) +System)
- 想要在场景中显示物体肯定要有
Mesh(形状)
和Material(材质)
,所以我们要做的是为Entity
添加这些Component(数据)
- 这个案例没有编写
System(行为)
二. 搭建环境
- 我的Unity版本:Unity2019.4.7LTS
- 使用Window->PackageManage 搜索Entities,点击Install,记得勾选
show preview packages
- 同理安装Jobs,Mathematics,Hybrid Render
- 安装完成后即可开始编码了,以上步骤有问题可以自行搜索对应的问题或者留言
三. 编码实现创建一个Entity,并在场景中显示
在Unity中,提供了很多方法去创建或者将GameObject
转换成Entity
,这里我们主要采用创建的方式,在新建的项目中,创建一个脚本CreateEntity.cs
CreateEntity.cs
using Unity.Entities;
using Unity.Rendering;
using Unity.Transforms;
using UnityEngine;
public class CreateEntity : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
manager = World.DefaultGameObjectInjectionWorld.EntityManager;//获取默认世界的实体管理器
CreateEntityObj();
}
// Update is called once per frame
void Update()
{
}
private EntityManager manager;
private void CreateEntityObj()
{
//在EntityManager中提供了public Entity CreateEntity(EntityArchetype archetype);方法
//在此之前,我们需要一个
//同样在EntityManager中,有一个 CreateArchetype(params ComponentType[] types);方法
var archeType = manager.CreateArchetype
(
//以下等于规定了Entity中一系列数据类型
ComponentType.ReadWrite<LocalToWorld>(),
ComponentType.ReadWrite<Translation>(),
ComponentType.ReadOnly<RenderMesh>()
);
var entity = manager.CreateEntity(archeType);//到此我们就创建了一个entity
manager.SetName(entity, "cube");//设置一个名字方便观察
//需要为Entity设置位置,形状,材质等信息,这里的信息可以使用公有变量在检视面板中设置
//此处直接使用一个标准的数据
var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
//为实体设置数据
manager.SetComponentData<LocalToWorld>(entity, new LocalToWorld() { Value = Unity.Mathematics.float4x4.zero });
manager.SetComponentData<Translation>(entity, new Translation() { Value = new Unity.Mathematics.float3(0, 0, 0) });
manager.SetSharedComponentData<RenderMesh>(entity, new RenderMesh()
{
material = cube.GetComponent<MeshRenderer>().material,
mesh = cube.GetComponent<MeshFilter>().sharedMesh,
subMesh = 0,
castShadows = UnityEngine.Rendering.ShadowCastingMode.On,
receiveShadows = true,
needMotionVectorPass = true
});
Destroy(cube);//临时使用的cube进行销毁
}
}
但是!挂载运行后在在场景中并没有找到我我们想要的那个Cube
,但是在Entity Debugger
中可以看到那个Entity
确实已经存在了,那就说明场景中应该是有的,只能说我们没找到。
四. 问题解决
在Entity Debugger
中有,场景中看不到,那就说明为他设置位置的数据有问题。
- 在场景中新建一个
Cube
,并添加ConvertToEntity
脚本 - 运行然后打开
Entity Debugger
,查看转换成的Entity
,发现多了几个数据,数据类型都是render bounds
相关的 - 为
Entity
添加RenderBounds
数据
修改后的CreateEntity.cs
using Unity.Entities;
using Unity.Rendering;
using Unity.Transforms;
using UnityEngine;
public class CreateEntity : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
manager = World.DefaultGameObjectInjectionWorld.EntityManager;//获取默认世界的实体管理器
CreateEntityObj();
}
// Update is called once per frame
void Update()
{
}
private EntityManager manager;
private void CreateEntityObj()
{
//在EntityManager中提供了public Entity CreateEntity(EntityArchetype archetype);方法
//在此之前,我们需要一个
//同样在EntityManager中,有一个 CreateArchetype(params ComponentType[] types);方法
var archeType = manager.CreateArchetype
(
//以下等于规定了Entity中一系列数据类型
ComponentType.ReadWrite<LocalToWorld>(),
ComponentType.ReadWrite<Translation>(),
ComponentType.ReadOnly<RenderMesh>(),
ComponentType.ReadWrite<RenderBounds>()
);
var entity = manager.CreateEntity(archeType);//到此我们就创建了一个entity
manager.SetName(entity, "cube");//设置一个名字方便观察
//需要为Entity设置位置,形状,材质等信息,这里的信息可以使用公有变量在检视面板中设置
//此处直接使用一个标准的数据
var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
//为实体设置数据
RenderBounds rb = new RenderBounds()
{
Value = new Unity.Mathematics.AABB()
{
Center = new Unity.Mathematics.float3(0, 0, 0),
Extents = new Unity.Mathematics.float3(0.5f,0.5f,0.5f)
}
};
manager.SetComponentData<RenderBounds>(entity,rb)//只需添加archerType即可,不需要手动设置数据
manager.SetComponentData<LocalToWorld>(entity, new LocalToWorld() { Value = Unity.Mathematics.float4x4.zero });
manager.SetComponentData<Translation>(entity, new Translation() { Value = new Unity.Mathematics.float3(0, 0, 0) });
manager.SetSharedComponentData<RenderMesh>(entity, new RenderMesh()
{
material = cube.GetComponent<MeshRenderer>().material,
mesh = cube.GetComponent<MeshFilter>().sharedMesh,
subMesh = 0,
castShadows = UnityEngine.Rendering.ShadowCastingMode.On,
receiveShadows = true,
needMotionVectorPass = true
});
Destroy(cube);//临时使用的cube进行销毁
}
}
欢迎访问我的个人博客 Snail’s Blog
转载请注明出处,侵权必究!!!https://blog.csdn.net/weixin_36382492/article/details/109266676
本文地址:https://blog.csdn.net/weixin_36382492/article/details/109266676
上一篇: LINUX查看进程的4种方法(小结)