[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) 直接看看第二個例子

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);
        }
    }
}

 

最後記得給你想要旋轉的物體掛載組件

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

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章