Introdução ao ECS 2. IJobEntityBatch

prefácio

Este exemplo demonstra um sistema ECS baseado em trabalho que gira um par de cubos. Em vez de iterar por entidade, este exemplo itera por bloco. (Um bloco é um bloco de memória que contém entidades com o mesmo protótipo, ou seja, todas possuem o mesmo conjunto de componentes.

O que isso mostra?

Este exemplo demonstra uma maneira alternativa de iterar sobre entidades acessando blocos diretamente. Em alguns casos, isso pode fornecer mais flexibilidade do que entidades.
Como no exemplo anterior, RotationSpeedSystem_IJobEntityBatch atualiza a rotação do objeto usando dados armazenados no componente RotationSpeed_IJobEntityBatch.
Esta amostra também demonstra como escrever um componente de autoria personalizado. Isso permite mais flexibilidade do que gerar um usando a propriedade "Gerar componente de autorização".

Sistemas e IJobEntityBatch

Neste exemplo, RotationSpeedSystem_IJobEntityBatchas tarefas agora são implementadas usando IJobEntityBatch.
Em um trabalho implementado usando IJobEntityBatch, a estrutura do ECS passa para sua Execute()função uma instância protótipodump de cada bloco de memória que contém os componentes necessários. Você pode, então, percorrer a matriz de componentes armazenados nesse bloco.
Observe que você precisa fazer mais configurações manuais para trabalhos em lote da entidade IJob. Isso envolve a construção de uma consulta de entidade ( EntityQuery) que identifica o tipo de componente no qual o sistema opera. Você também precisa ArchetypeChunkComponentTypepassar para o trabalho e, em seguida, usá-lo no trabalho para obter a instância de matriz nativa necessária para acessar a própria matriz de componentes.
O sistema utilizado IJobEntityBatchpode lidar com Entities.ForEachsituações mais complexas do que as suportadas, mantendo a máxima eficiência. IJobEntityBatch Fornece controle explícito sobre quais blocos, entidades e componentes processar. Você também pode processar entidades em lotes menores que blocos completos, o que pode ser mais eficiente em alguns casos, por exemplo, quando você tem algoritmos computacionalmente caros e um pequeno número de entidades.

Converter de GameObject para Entidade

ConvertToEntityO MonoBehaviour converte um GameObject e seus filhos em Entidades e Componentes ECS na ativação. Atualmente, o conjunto de one-liners integrados do Unity que convertem entidades pode converter arquivos include Transforme MeshRenderer. Você pode usar o "Depurador de Entidades" (menu: "Janela" > "Análise" > "Depurador de Entidades") para inspecionar as entidades e componentes ECS criados pela transformação.
Você pode implementar a interface "IConvertGameObjectEntity" em seu MonoBehaviour para fornecer uma função de conversão, e "ConvertToEntity" será usado para converter os dados armazenados no MonoBehaviour em um componente ECS.
Neste exemplo, RotationSpeedAuthoring_IJobEntityBatcho MonoBehaviour usa o objeto IConvertGame para adicionar componentes a entidades ao converter arquivos RotationSpeed_IJobEntityBatch.

projeto

Layout da cena

Crie um Cubedos dois como o objeto pai e verifique Inspectoro painel noConvertToEntity
Layout da cena

escrita de código

RotationSpeed_IJobEntityBatch.cs

using System;
using Unity.Entities;

// ReSharper disable once InconsistentNaming
// 在Editor显示出来
[Serializable]
public struct RotationSpeed_IJobEntityBatch : IComponentData
{
    
    
    public float RadiansPerSecond;
}

RotationSpeedAuthoring_IJobEntityBatch.cs

using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;

// ReSharper disable once InconsistentNaming
//添加快捷菜单
[AddComponentMenu("DOTS Samples/IJobEntityBatch/Rotation Speed")]
//通过声明版本号,ComponentSystem 可以确保资产管道的任何缓存数据都是使用活动代码准备的。如果任何转换系统或优化系统的版本号发生变化或添加了新的转换系统,则将重新转换场景。
//[ConverterVersion("joe", 1)]
//继承自IConvertGameObjectToEntity在 GameObject 转换期间,各种转换系统会处理它们识别的 MonoBehaviour 组件并将它们转换为基于 ECS 的组件。
//例如,其中一个 Unity.Transforms 转换系统检查 UnityEngine.Transform 组件并添加 ECS 组件(例如LocalToWorld)来替换它。
//您可以实施一个IConvertGameObjectToEntityMonoBehaviour 组件指定自定义转换步骤。
//转换的 GameObjects 数量和创建的实体数量之间通常不会存在一一对应的关系;
//GameObject 上的 MonoBehaviours 数量与添加到实体的 ECS 组件数量之间也不存在差异。
public class RotationSpeedAuthoring_IJobEntityBatch : MonoBehaviour, IConvertGameObjectToEntity
{
    
    
    public float DegreesPerSecond = 360.0F;

    // The MonoBehaviour data is converted to ComponentData on the entity.
    // MonoBehaviour数据将转换为实体上的组件数据。
    // 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)
    {
    
    
        //新建一个RotationSpeed_IJobEntityBatch组件
        var data = new RotationSpeed_IJobEntityBatch {
    
     RadiansPerSecond = math.radians(DegreesPerSecond) };
        //添加组件
        dstManager.AddComponentData(entity, data);
    }
}


RotationSpeedSystem_IJobEntityBatch.cs

using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;

// This system updates all entities in the scene with both a RotationSpeed_IJobChunk and Rotation component.
// 此系统使用RotationSpeed_IJobChunk和Rotation组件更新场景中的所有实体。
// ReSharper disable once InconsistentNaming
public partial class RotationSpeedSystem_IJobChunk : SystemBase
{
    
    
    /// <summary>
    /// 实体查询
    /// </summary>
    EntityQuery m_Query;

    protected override void OnCreate()
    {
    
    
        // Cached access to a set of ComponentData based on a specific query
        // 基于特定查询对一组组件数据的缓存访问
        m_Query = GetEntityQuery(typeof(Rotation), ComponentType.ReadOnly<RotationSpeed_IJobEntityBatch>());
    }

    // Use the [BurstCompile] attribute to compile a job with Burst. You may see significant speed ups, so try it!
    // 使用 [BurstCompile] 属性编译具有突发的作业。您可能会看到明显的加速,所以试试吧!
    [BurstCompile]
    struct RotationSpeedJob : IJobEntityBatch
    {
    
    

        public float DeltaTime;
        public ComponentTypeHandle<Rotation> RotationTypeHandle;
        [ReadOnly] public ComponentTypeHandle<RotationSpeed_IJobEntityBatch> RotationSpeedTypeHandle;

        public void Execute(ArchetypeChunk batchInChunk, int batchIndex)
        {
    
    
            var chunkRotations = batchInChunk.GetNativeArray(RotationTypeHandle);
            var chunkRotationSpeeds = batchInChunk.GetNativeArray(RotationSpeedTypeHandle);
            for (var i = 0; i < batchInChunk.Count; i++)
            {
    
    
                var rotation = chunkRotations[i];
                var rotationSpeed = chunkRotationSpeeds[i];

                // Rotate something about its up vector at the speed given by RotationSpeed_IJobChunk.
                chunkRotations[i] = new Rotation
                {
    
    
                    Value = math.mul(math.normalize(rotation.Value),
                        quaternion.AxisAngle(math.up(), rotationSpeed.RadiansPerSecond * DeltaTime))
                };
            }
        }
    }

    // OnUpdate runs on the main thread.
    // OnUpdate 在主线程上运行。
    protected override void OnUpdate()
    {
    
    
        // Explicitly declare:明确声明:
        // - Read-Write access to Rotation - 对旋转的读写访问权限
        // - Read-Only access to RotationSpeed_IJobChunk - 对RotationSpeed_IJobChunk的只读访问权限
        var rotationType = GetComponentTypeHandle<Rotation>();
        var rotationSpeedType = GetComponentTypeHandle<RotationSpeed_IJobEntityBatch>(true);
        //新建一个Job
        var job = new RotationSpeedJob()
        {
    
    
            RotationTypeHandle = rotationType,
            RotationSpeedTypeHandle = rotationSpeedType,
            DeltaTime = Time.DeltaTime
        };
        //并行Job
        Dependency = job.ScheduleParallel(m_Query, Dependency);
    }
}

Adicionar e definir script

Adicionar e definir script

Resumir

GameObject é convertido automaticamente para Entity

Quando MonoBehavioura herança IConvertGameObjectToEntitypode implementar componentes de montagem personalizados
GameObject é convertido automaticamente para Entity

Operação multiencadeada BurstCompile

Use [BurstCompile]atributos para alterar o método para multithreading
Criar um trabalho
criar um trabalho

chamada no sistema
chamada no sistema

resultado em execução

resultado em execução

Acho que você gosta

Origin blog.csdn.net/a71468293a/article/details/127508084
Recomendado
Clasificación