UnityECS学习日记三:PureECS(纯ECS开发)

 

案例二:PureECS(纯ECS)动态创建指定数量的小球Entity(实体)(Scne3)

 

脚本:PureMain

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Entities;
using Unity.Collections;
using Unity.Rendering;
using Unity.Transforms;

public class PureMain : MonoBehaviour
{
    public int entityCount = 1000;    //动态生成实体数量
    public int entityRange = 100;     // 生成实体的范围乘值
    public Mesh mymesh;               // 实体的 网格
    public Material mymaterial;       // 实体的材质
    void Start()
    {
        this.CreatePureMain();
    }

    void CreatePureMain()
    {
        #region  1.创建本地实体数组
        // 世界自动创建的唯一实体管理器
        EntityManager entityManager = World.Active.EntityManager;

        // 创建一个原型模型(可以类比   GameObject.CreatePrimitive ), 函数参数代表该实体有哪些组件(注意要想实体在场景中显示必须有 Translation,RenderMesh,LoalToWorld这三个组件)
        EntityArchetype entityArchetype = entityManager.CreateArchetype
        (
            typeof(Translation),
            typeof(RenderMesh),
            ComponentType.ReadWrite<LocalToWorld>()                     // 实体的矩阵,
        );

        NativeArray<Entity> entities = new NativeArray<Entity>(entityCount, Allocator.Temp);

        entityManager.CreateEntity(entityArchetype, entities);

        #endregion

        #region 2.初始化数组中的实体数据

        for (int i = 0; i < entityCount; i++)
        {
            Translation translation = new Translation();
            translation.Value = Random.insideUnitSphere * entityRange;                      // 设置位置为随机的球体
            entityManager.SetComponentData<Translation>(entities[i], translation);  // 设置位置信息

            // 给所有实体 设置网格 和材质 信息 这些UnityECS做了优化处理,使用共享网格材质的函数进行添加
            entityManager.SetSharedComponentData<RenderMesh>(entities[i], new RenderMesh { mesh = mymesh, material = mymaterial });
        }

        entities.Dispose();     // 这里把内存缓冲区释放掉
        #endregion
    }
}

 

 

如上图,动态创建了10万个小球实体,Unity的FPS才70。

第一步,创建本地实体数组,通过unity提供的API创建,原型类型组件LoalToWrold包含了该物体的矩阵信息(个人觉得该矩阵信息主要用来进行坐标系(相机,本地,屏幕坐标系)的转变使用),而translation只存储了在世界(wrold)的坐标信息。

Unity提供了一套内置缓冲区的概念,上篇只是提到。

首先翻译官方的解释:NativeArray将本地内存的缓冲区公开给托管代码,从而使托管和本地之间共享数据成为可能,而无需花费任何成本。在后台,NativeArrays提供的系统使它们可以安全地与作业一起使用,并自动跟踪内存泄漏。

这里涉及到两个知识点:

1. 托管代码和非托管代码

大概就是 托管内存受c#内存管理机制控制,自动释放。

非托管内存必须得手动进行释放。

详情参考:http://blog.sina.com.cn/s/blog_3e51bb390102vv6b.html

2.为啥么使用缓冲区可以提高性能

这个涉及到cpu硬件的存读方式,可以记住按照Unity指定的格式存储,这样程序访问的数据会更快。

详情参考:https://zhuanlan.zhihu.com/p/44851549 这篇写的很详细

第二步,初始化数组中的实体数据

Unity并不能直接访问本地缓存的实体,必须通过EntityManager(实体管理类)提供的方法进行数据初始化,比如初始化位置信息。另外,Unity还提供了对数据量级的相同实体使用共享的网格和材质信息,从而对游戏进行优化处理。

 

远程仓库(github):https://github.com/h1031464180/UnityECS

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一: 什么是ECS?       ECS是一种新的架构模式(当然是针对Unity本身来说),这是一个取代GameObject / Component 的模式。 其模式遵循组合优于继承原则,游戏内的每一个基本单元都是一个实体,每个实体又由一个或多个组件构成,每个组件仅仅包含代表其特性的数据(即在组件中没有任何方法)。系统便是来处理拥有一个或多个相同组件的实体集合的工具,其只拥有行为(即在系统中没有任何数据)。       ECS旨在比GameObject / MonoBehaviour更容易处理大量物体。ECS由于是面向数据的设计,所以很容易并行高速处理,以及与Unity开发的C#JobSystem/Burst Compiler一起工作,从而获取更高的项目运行性能。二:ECS总体发展历史          目前Unity公司由Mike Acton 大佬主持DOD(Data Oriented Design 面向数据设计)的全面改革与推进工作,目的是旨在进一步推进Unity系统本身与Unity项目的执行效率。       ECS总体发展:       A: 在Unity2018引入Entities之前,其实ECS框架早已经出现,但是ECS还是因为守望先锋采用了这个框架才被我们所熟知,后来Git上面出现了一个Entitas的插件可以直接用在Unity上面。Entitas-Unity(有多个语言的port版本,Entitas-Unity下统一称为Entitas) 是 Unity的一个ECS(Entity/Component/System)框架,是在github上面的一个开源项目。      B: 经过Unity公司的认可与改造,目前Unity2018.x 版本已经通过 Package Manager 提供了Unity版本的ECS插件,名称为:“Entities”。      C: Unity2019.x 版本,对“Entities”插件的API进行了进一步改造与完善,以更规范的API实现更加高效的与规范的编程模式。 ECS(二)小试牛刀篇      本套课程在入门篇的基础之上,着重讲解ECS的两大分类:HyBridECS(混合ECS)与Pure ECS(ECS)      前者包含Pure ECS的所有功能,且可以使用特定类,把传统的GameObject转成Entities(实体),此种方式更加符合传统的Unity开发习惯。后者为粹的ECS,实体上没有多余的Mono脚本。数据存储在Components上,逻辑执行处理在System里面。可以配合利用C# 的 Job System进一步提高执行效率。     
Unity ECS(Entity Component System)是Unity引擎的一种编程范式,它是一种数据驱动的编程模型,它将游戏对象(Entity)分解为数据和行为两个部分,其中数据由组件(Component)来表示,行为则由系统(System)来实现。相对于传统的面向对象编程模型,ECS提供了更高效、更灵活的编程方式,可以有效地提高游戏的性能和扩展性。 下面是我学习Unity ECS时的笔记: ## Entity Entity是ECS中最基本的概念,它表示游戏对象。每个Entity由一个唯一的ID来标识,可以通过EntityManager来创建、销毁、查询和管理Entity。 ## Component Component是Entity的数据部分,用来描述Entity的属性和状态。每个Component包含一些数据成员和一些方法,用来操作这些数据成员。Component是以结构体(struct)的形式定义的,通常只包含数据成员,不包含方法。 ## System System是Entity的行为部分,用来实现游戏逻辑和操作Component。System可以访问和操作EntityManager和Component,但不能直接访问Entity。每个System包含一个或多个Component,表示它所处理的数据类型。System是以类(class)的形式定义的,通常包含一个Update方法,用来实现游戏逻辑。 ## Job Job是一种轻量级的线程,用于并行执行System中的任务。Job可以访问和操作Component,但不能直接访问Entity和EntityManager。Job通常是以结构体(struct)的形式定义的,不包含方法。 ## Archetype Archetype是Entity的集合,包含一组具有相同Component类型的Entity。Archetype可以用来优化数据的访问和处理,可以在不同的System之间共享。 ## Chunk Chunk是Archetype中的数据块,包含一组连续的Entity和它们的Component数据。Chunk可以用来优化内存的分配和访问,可以在Job中进行并行处理。 ## Buffer Buffer是一种Component类型,用来存储可变长度的数据,例如数组或列表。Buffer可以在System和Job中进行修改和访问。 以上是我学习Unity ECS时的笔记,希望对你有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值