下一篇 : [3]Unity ECS 探路日記 https://blog.csdn.net/u010294054/article/details/96097197
這一篇我們來跑一跑Unity的ECS Samples
下載Samples: https://github.com/Unity-Technologies/EntityComponentSystemSamples
我們跳過第一個例子(沒有使用Job System) 直接看看第二個例子
README 機器翻譯
#HelloCube_02_IJobForEach
此示例演示了基於作業的ECS系統,該系統可旋轉一對立方體。
##它顯示了什麼?
此示例構建在HelloCube_01_ForEach之上,並說明了如何在多線程作業中而不是在主線程上執行相同的工作。
與前面的示例一樣,** RotationSpeedSystem ** *使用存儲在** RotationSpeed ** Component中的* data *更新對象的旋轉。
##作業組件系統和IJobForEach
使用IJobForEach的系統是可用於處理組件數據的最簡單有效的方法。 對於您設計的任何系統,我們建議從此方法開始。
在此示例中,RotationSpeedSystem現在實現爲JobComponentSystem。 該類創建一個IJobForEach結構來定義需要完成的工作。 此作業計劃在System的OnUpdate()函數中。
讓我們來擼例子
RotationSpeed.cs 這個結構體是組件 實現了 IComponentData接口 用來儲存組件裏需要的數據並序列號保存
拓展閱讀:
組件是實體組件系統體系結構的三個主要元素之一。它們代表您的遊戲或程序的數據。實體本質上是標識符,用於索引組件集合。系統提供行爲。
using System;
using Unity.Entities;
namespace Samples.HelloCube_01
{
// Serializable attribute is for editor support.
[Serializable]
public struct RotationSpeed : IComponentData
{
public float RadiansPerSecond;
}
}
RotationSpeedProxy.cs 這個類是MonoBehaviour轉Entity的代理類
繼承 IConvertGameObjectToEntity 接口並實現轉換方法
void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem);
這個類是繼承於MonoBehaviour
所以可以把這個類掛載到GameObject上面
類裏面的public float DegreesPerSecond;字段能很方便的儲存你想設置的每秒旋轉角度
在轉換方法裏面實例化組件 RotationSpeed 並賦值
組件實例化後添加到實體管理類 EntiryManager 裏面
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
namespace Samples.HelloCube_01
{
[RequiresEntityConversion]
public class RotationSpeedProxy : MonoBehaviour, IConvertGameObjectToEntity
{
public float DegreesPerSecond;
// The MonoBehaviour data is converted to ComponentData on the entity.
// We are specifically transforming from a good editor representation of the data (Represented in degrees)
// To a good runtime representation (Represented in radians)
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
var data = new RotationSpeed { RadiansPerSecond = math.radians(DegreesPerSecond) };
dstManager.AddComponentData(entity, data);
}
}
}
RotationSpeedSystem.cs 是組件系統 繼承於JobComponentSystem
拓展閱讀:
ComponentSystem
(也稱爲標準ECS術語中的系統)對實體執行操作。AComponentSystem
不能包含實例數據。根據舊的Unity系統來說,這有點類似於舊的Component類,但只包含方法。一個ComponentSystem
負責用一組匹配的組件(在一個名爲EntityQuery的結構中定義)更新所有實體。Unity ECS提供了一個名爲的抽象類
ComponentSystem
,您可以在代碼中進行擴展。
繼承於JobComponentSystem的類需要實現抽象方法 protected abstract JobHandle OnUpdate(JobHandle inputDeps);
我們先創建一個 RotationSpeedJob 結構體 繼承於IJobForEach接口
在 RotationSpeedJob 的 Execute 方法中實現實體的旋轉
在 RotationSpeedSystem 的 OnUpdate方法中 創建RotationSpeedJob任務,並添加到任務到執行隊列中進行處理
在任務執行隊列中會遍歷所有任務的 Execute 方法並調用 ,我們在Execute中實現了旋轉的代碼,所以此時模型開始旋轉了
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;
namespace Samples.HelloCube_02
{
// This system updates all entities in the scene with both a RotationSpeed and Rotation component.
public class RotationSpeedSystem : JobComponentSystem
{
// Use the [BurstCompile] attribute to compile a job with Burst. You may see significant speed ups, so try it!
[BurstCompile]
struct RotationSpeedJob : IJobForEach<Rotation, RotationSpeed>
{
public float DeltaTime;
// The [ReadOnly] attribute tells the job scheduler that this job will not write to rotSpeed
public void Execute(ref Rotation rotation, [ReadOnly] ref RotationSpeed rotSpeed)
{
// Rotate something about its up vector at the speed given by RotationSpeed.
rotation.Value = math.mul(math.normalize(rotation.Value), quaternion.AxisAngle(math.up(), rotSpeed.RadiansPerSecond * DeltaTime));
}
}
// OnUpdate runs on the main thread.
protected override JobHandle OnUpdate(JobHandle inputDependencies)
{
var job = new RotationSpeedJob()
{
DeltaTime = Time.deltaTime
};
return job.Schedule(this, inputDependencies);
}
}
}
最後記得給你想要旋轉的物體掛載組件
就這樣 第二個ECS例子解讀完畢