目前的ECS分为两种 Pure ECS 与 HyBridECS 区别主要就是Pure版的不能使用GameObjects 和 MonoBehaviours ,当然这中理解很表面,但是刚开始嘛?
Pure——》干净纯洁
HyBrid——》混合的
我也从Youtube上找到了一些资料分享出来。
Pure ECS系统特点:
1.Entities是一个新的Gameobjects
2.实体上没有多余的Mono脚本:数据存储在Components上;逻辑执行处理在System里面
3.可以利用C# 的 Job System系统来进行工作,这点很有优势啊
Hybrid ECS系统特点:
1.包括所有Pure ECS 的功能
2.一些特别的工具类:把GameObject当成Entities;把Mono脚本当成Components
3.更多的支持原生Unity的类
当然可以看出来Hybrid ECS 更加具有开发游戏和原先的开发习惯也比较符合。
————————————————————————————————————————————————————————
当然我们用ECS开发首先要打开Entity Debugger的功能在 Windows菜单栏下——》Analysis——》Entity Debugger。ECS有别于传统的Unity游戏开发需要有专门的窗口来查看创建的物体信息。
Hybrid ECS使物体移动(Unity2018.3f2):
1.首先创建场景中的平面和一个胶囊体:
胶囊体上挂在一个GameObjectEntity脚本,此时可以在Debugger中看到存在一个实体:
我们要让胶囊体进行移动,按照ECS思想需要先创建Components把数据存放在里面,并且由于Hybrid特点我们可以把Components当成原先Unity开发的Components挂载到GameObjec上。
Hybrid ECS 中的Speed组建(Components):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace HyBridECS//这里就是为了和后面的Pure区别加了个命名空间
{
public class Speed : MonoBehaviour
{
public float Value;//Speed 组件中的数据值
}
}
Hybrid ECS 中的PlayerInput组建(Components):
namespace HyBridECS
{
public class PlayerInput : MonoBehaviour
{
public float Horizontal;//数据
}
}
然后我们需要添加数据处理的System,创建一个PlayerMovementSystem继承自ComponentSystem:
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
namespace HyBridECS
{
public class PlayerMovementSystem : ComponentSystem
{
/// <summary>
/// 创建一个结构体,ECS现在处理的只能是结构体(关于结构体和类的区别自行Google就好)
/// </summary>
private struct Group//这里的意思就是说查找到符合这种结构的实体
{
public Transform Transform;
public PlayerInput PlayerInput;
public Speed Speed;
}
protected override void OnUpdate()//这里是处理的逻辑核心
{
foreach (var entity in GetEntities<Group>())//寻找到所有符合Group结构的实体
{
Vector3 position = entity.Transform.position;
Quaternion rotation = entity.Transform.rotation;
position.x += entity.Speed.Value * entity.PlayerInput.Horizontal * Time.deltaTime;
rotation.w += math.clamp(entity.PlayerInput.Horizontal, -.5f, .5f);
entity.Transform.position = position;
entity.Transform.rotation = rotation;
}
}
}
}
写道这里其实只是处理完成移动的System,由于ECS特点C要单独对应S(嗯这点有点烦 很操蛋?),所以就会发现我们没有处理玩家输入的System!!!所以接着添加一个PlayerInputSystem:
using Unity.Entities;
using UnityEngine;
namespace HyBridECS
{
public class PlayerInputSystem : ComponentSystem
{
/// <summary>
/// 创建一个结构体
/// </summary>
public struct Group//这里的意思就是说查找到符合这种结构的实体
{
public PlayerInput PlayerInput;
}
protected override void OnUpdate()
{
foreach (Group entity in GetEntities<Group>())
{
entity.PlayerInput.Horizontal = Input.GetAxis("Horizontal");
}
}
}
}
我们可以在Debugger中看到有我们自己添加的组建信息
在System中可以看到系统调用的System,可以手动取消勾选System这样系统就不会在执行Systems了:
用ECS写了BUG估计调试就麻烦了,想问一下大家调试有什么好的方法吗?
然后你在编辑器中就可以点击“A”或者“S”就可以看到游戏物体的移动了?,ECS中调用System并不需要我们自己进行操作,这是由系统自己调用的,So我也不是很清楚里面的具体代码 还没有研究过!!!有大神可以指导一下小弟我啊。
PureECS使物体移动(Unity2018.3f2):
不同于Hybrid ECS ,Pure ECS的组建不需要挂载到游戏中的物体上同时组建继承也有所区别是:
namespace PureECS
{
public class Speed : IComponentData//继承有所区别
{
public float Value;
}
}
using System.Collections;
using Unity.Entities;
namespace PureECS
{
public class PlayerInput : IComponentData//继承有所区别
{
public float Horizontal;
}
}
因为我们不要把脚本挂在Go上但是场景中我们还是需要一个Mono脚本来进行调用,在场景中创建一个Boot物体并在Boot上进行添加控制脚本Boot:
using Unity.Entities;
using Unity.Rendering;
using Unity.Transforms;
using UnityEngine;
namespace PureECS
{
public class Boot : MonoBehaviour
{
public float Speed;//这里外面设置参数好进行代码生成物体
public Mesh Mesh;
public Material Material;
void Start()
{
EntityManager entityManager = World.Active.GetOrCreateManager<EntityManager>();//获取场景中EntityManager脚本,这个可以在Debugger中System看到
Entity playerEntity = entityManager.CreateEntity(//创建出来是一个结构体,通过代码创建
ComponentType.Create<Speed>(),//只有俩个自己定义的组建
ComponentType.Create<PlayerInput>(),//只有俩个自己定义的组建
ComponentType.Create<Position>(),
ComponentType.Create<Transform>(),
ComponentType.Create<MeshInstanceRenderer>()
);
entityManager.SetComponentData(playerEntity, new Speed { Value = Speed });//设置组建关联信息
entityManager.SetSharedComponentData(playerEntity, new MeshInstanceRenderer
{
mesh = Mesh,
material = Material
});
}
}
}
这时候运行代码就可以看到在场景中有了生成的物体(别忘了Boot上设置参数)但是在Hierarchy中是看不到生成的物体的只能在Debugger中进行查看。
在Pure ECS中C对应的S所要继承的是JobComponentSystem,俩个System:
using Unity.Entities;
using Unity.Jobs;
using Unity.Transforms;
using UnityEngine;
namespace PureECS
{
public class PlayerMovementSystem : JobComponentSystem
{
/// <summary>
/// 类似于HyBrid ECS的Struct,我这理解也不是很深
/// </summary>
private struct PlayerMovementJob : IJobProcessComponentData<Speed, PlayerInput, Position>
{
public float DeltaTime;
public void Execute(ref Speed speed, ref PlayerInput input, ref Position position)
{
position.Value.x += speed.Value * input.Horizontal * DeltaTime;
}
}
protected override JobHandle OnUpdate(JobHandle inputDeps)//这里是处理的逻辑核心
{
PlayerMovementJob job = new PlayerMovementJob
{
DeltaTime = Time.deltaTime
};
return job.Schedule(this, inputDeps);
}
}
}
using Unity.Entities;
using Unity.Jobs;
using UnityEngine;
namespace PureECS
{
public class PlayerInputSystem : JobComponentSystem
{
private struct PlayerInputJob : IJobProcessComponentData<PlayerInput>
{
public float Horizontal;
public void Execute(ref PlayerInput input)
{
input.Horizontal = Horizontal;
}
}
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
PlayerInputJob job = new PlayerInputJob
{
Horizontal = Input.GetAxis("Horizontal")
};
return job.Schedule(this, inputDeps);
}
}
}
然后你就会发现场景里面的物体又可以移动了。ECS现在最主要的就是这俩个 先了解会用 深入问题慢慢搞。
关于一些API接口后续再来讨论。