欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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从而完成上述功能.

  1. 按我的理解Entity≠GameObject,而 GameObject = (Entity + Component(data) +System)
  2. 想要在场景中显示物体肯定要有Mesh(形状)Material(材质),所以我们要做的是为Entity添加这些Component(数据)
  3. 这个案例没有编写System(行为)

二. 搭建环境

  1. 我的Unity版本:Unity2019.4.7LTS
  2. 使用Window->PackageManage 搜索Entities,点击Install,记得勾选 show preview packages
  3. 同理安装Jobs,Mathematics,Hybrid Render
  4. 安装完成后即可开始编码了,以上步骤有问题可以自行搜索对应的问题或者留言

三. 编码实现创建一个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中有,场景中看不到,那就说明为他设置位置的数据有问题。

  1. 在场景中新建一个Cube,并添加ConvertToEntity脚本
  2. 运行然后打开Entity Debugger,查看转换成的Entity,发现多了几个数据,数据类型都是render bounds相关的
  3. Entity添加RenderBounds数据

unity2019 ECS入门实例:创建一个Entity
unity2019 ECS入门实例:创建一个Entity

修改后的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

相关标签: Unity 2019新特性