天天看點

[2]Unity ECS 探路日記 官方Sample2

下一篇 : [3]Unity ECS 探路日記  https://blog.csdn.net/u010294054/article/details/96097197

這一篇我們來跑一跑Unity的ECS Samples

下載下傳Samples: https://github.com/Unity-Technologies/EntityComponentSystemSamples

我們跳過第一個例子(沒有使用Job System) 直接看看第二個例子

[2]Unity ECS 探路日記 官方Sample2

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術語中的系統)對實體執行操作。A 

ComponentSystem

不能包含執行個體資料。根據舊的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);
        }
    }
}
           

最後記得給你想要旋轉的物體挂載元件

[2]Unity ECS 探路日記 官方Sample2

就這樣 第二個ECS例子解讀完畢