当前的Unity开发模式
当前的开发方式我们称为"Classic", 是基于Monobehaviours,把代码当成组件的形式关联到gmaeObject上,通常情况下数据和逻辑是紧密的关联在一起的。这种方式可以很快速的进行开发,但对性能会有一定的影响。
Unity正在尝试解决什么样的问题?
基于Unity的GameObject/Monobehaviour机制,可以很简单的为创作游戏编写代码, 但最终往往会让代码陷入难以阅读,维护和优化的境地。数据分散在内存的各个地方,想要找到这些数据并传送到cpu会消耗很多性能。
2. 很多时候会把不需要的数据或者变量一起传送给cpu,这里会有很多浪费的。
3. 单线程
Entity-Component-System登场
ECS就是为了解决以上的问题而出现的,使用Entity的方式将数据分离出来,然后在需要的地方提供相应的数据,其中System是为了处理Entity中数据的具体逻辑,还有一个很重要的部分"Filter"进行数据的过滤。简单来讲ECS就是数据与数据处理的一个关系。
Entity-Component-System的优点高性能
易编写出高度优化的代码
易编写出可重用的代码
数据在内存中是紧密排列的
和Job System、Burst一起可以获得更高的性能
Job System
大多数使用多线程代码的人都知道编写线程安全代码很难,线程争抢资源可能会发生,但机会非常少,如果程序员没有想到这个问题,可能会导致潜在的严重错误。除此之外,上下文切换的成本很高,因此学习如何平衡工作负载以尽可能高效地运行是很困难的。新的 Unity C# Jobs System将解决这些问题。
如何使用ECS
1. 目前ECS尚处于开发阶段,只有Unity2018.1版本以上才能开启:
2. 新建一个项目,设置.NET
Build Settings - Player Settings ,设置c# runtime:
3. 导入ECS包
Window - Package Manager,选择Entities和Hybird Renderer并安装
4. 新建一个场景,并创建一个Cube,去掉Cube上除了Transform的所有组件,并添加ECS组件,如下图:
5. 新建HelloRotationSpeedProxy.cs和HelloRotationSpeedSystem.cs脚本
using Unity.Entities;
using System;
namespace HelloCube.Cube
{
[Serializable]
public struct HelloRotationSpeed : IComponentData
{
public float Value;
}
[UnityEngine.DisallowMultipleComponent]
public class HelloRotationSpeedProxy : ComponentDataProxy
{
}
}
using Unity.Burst;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;
namespace HelloCube.Cube
{
public class HelloRotationSpeedSystem : JobComponentSystem
{
[BurstCompile]
struct HelloRotationSpeedJob : IJobProcessComponentData
{
public float dT;
public void Execute(ref Rotation rotation, ref HelloRotationSpeed rotSpeed)
{
rotation.Value = math.mul(math.normalize(rotation.Value), quaternion.AxisAngle(math.up(), rotSpeed.Value * dT));
}
}
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
var job = new HelloRotationSpeedJob
{
dT = Time.deltaTime
};
return job.Schedule(this, inputDeps);
}
}
}
相关链接