Análisis central de la producción de horneado de filtros y prefabricados en horneado de la serie Unity DOTS

Recientemente, DOTS lanzó una versión oficial. Compartamos el mecanismo central de Baking en DOTS para facilitar que todos aprendan y dominen el desarrollo de Unity DOTS. Hoy compartiré con ustedes la salida de horneado del filtro y el horneado prefabricado en el mecanismo de horneado .

¡bien! Aquí hay un grupo de intercambio de desarrollo de juegos , que reúne a un grupo de principiantes a quienes les encanta aprender juegos, así como a algunos expertos técnicos que participan en el desarrollo de juegos. Le invitamos a venir, intercambiar y aprender.

Mecanismo de salida de horneado del filtro

De forma predeterminada, Baking generará Entidad y Componente para cada GameObject, y estas entidades se crearán en Conversion World. Entonces, no es necesario convertir todos los GameObjects en Entidades durante la creación. Por ejemplo: en una curva spline, se usa un punto de control durante la creación, pero ya no se puede usar después de incorporarlo a los datos de ecs, por lo que no es necesario incorporar este punto de control a una entidad.

Para no mostrar la Entidad generada por este GameObject Bake al mundo y guardarla en la escena de la entidad, podemos agregar un Componente de etiqueta BakingOnlyEntity a esta Entidad. Después de agregar este componente de etiqueta, el sistema Baking no almacenará su entidad en la escena de entidades, ni generará esta entidad en el mundo principal en ejecución. Podemos agregar directamente los datos del componente BakingOnlyEntity a la entidad en la función Baker, o agregar un componente BakingOnlyEntityAuthoring al Authoring GameObject. Ambos métodos pueden lograr el mismo efecto sin ninguna diferencia.

También puede agregar anotaciones [BakingType], atributos [TemporaryBakingType] al componente para filtrar el componente para que no se envíe a la entidad.

[TemporaryBakingType]: el componente anotado con estos atributos no se enviará a la entidad durante la salida de horneado. Este componente solo sobrevivirá durante el proceso Baker y será destruido una vez que finalice el Baker.

A veces necesitamos procesar por lotes algunos datos de componentes en el sistema de horneado y, después del procesamiento, estos componentes son inútiles. Por ejemplo, Baker convierte un cuadro delimitador en datos de componentes ecs. A continuación, definimos un sistema de horneado para procesar todas las entidades en lotes para calcular el casco convexo de la entidad. Una vez completado el cálculo, se puede eliminar el componente del cuadro delimitador original. En este caso, se puede utilizar el mecanismo de salida de horneado del componente de filtro anterior.

Prefabricado en mecanismo de horneado

Después de generar la entidad prefabricada para la escena de la entidad, podemos crear la entidad en el mundo como si usáramos una casa prefabricada normal para crear un GameObject. Pero antes de usar la entidad prefabricada, debe asegurarse de que Baker la haya agregado a la escena de la entidad. Cuando se crea una instancia de un prefabricado en la escena de creación, Baking lo convierte como un GameObject normal y no lo trata como un prefabricado.

Para generar una entidad prefabricada, debe registrar un Baker y agregar una dependencia en la función Bake para que dependa de Authoring GameObject Prefab. Luego se horneará la casa prefabricada. Si creamos un componente que guarda una referencia a la entidad prefabricada, Unity serializará la entidad prefabricada en la subescena. Puede obtenerlo cuando necesite utilizar esta entidad prefabricada. El código se muestra a continuación:

public struct EntityPrefabComponent : IComponentData
 {
 public Entity Value;
 }
 public class GetPrefabAuthoring : MonoBehaviour
 {
 public GameObject Prefab;
 }
 public class GetPrefabBaker : Baker<GetPrefabAuthoring>
 {
 public override void Bake(GetPrefabAuthoring authoring)
 {
 // Register the Prefab in the Baker
 var entityPrefab = GetEntity(authoring.Prefab, TransformUsageFlags.Dynamic);
 // Add the Entity reference to a component for instantiation later
 var entity = GetEntity(TransformUsageFlags.Dynamic);
 AddComponent(entity, new EntityPrefabComponent() {Value = entityPrefab});
 }
 }
    #endregion

Durante el horneado, cuando necesitamos hacer referencia a una entidad prefabricada, podemos usar EntityPrefabReference. Esto lo serializará en el archivo de escena de la entidad. Cuando se ejecute, cárguelo directamente y podrá usarlo. Esto evita que varias subescenas generen el mismo prefabricado sin realizar copias repetidas.

#region InstantiateLoadedPrefabs
 public partial struct InstantiatePrefabReferenceSystem : ISystem
 {
 public void OnStartRunning(ref SystemState state)
 {
 // Add the RequestEntityPrefabLoaded component to the Entities that have an
 // EntityPrefabReference but not yet have the PrefabLoadResult
 // (the PrefabLoadResult is added when the prefab is loaded)
 // Note: it might take a few frames for the prefab to be loaded
 var query = SystemAPI.QueryBuilder()
                .WithAll<EntityPrefabComponent>()
                .WithNone<PrefabLoadResult>().Build();
 state.EntityManager.AddComponent<RequestEntityPrefabLoaded>(query);
 }
 public void OnUpdate(ref SystemState state)
 {
 var ecb = new EntityCommandBuffer(Allocator.Temp);
 // For the Entities that have a PrefabLoadResult component (Unity has loaded
 // the prefabs) get the loaded prefab from PrefabLoadResult and instantiate it
 foreach (var (prefab, entity) in
 SystemAPI.Query<RefRO<PrefabLoadResult>>().WithEntityAccess())
 {
 var instance = ecb.Instantiate(prefab.ValueRO.PrefabRoot);
 // Remove both RequestEntityPrefabLoaded and PrefabLoadResult to prevent
 // the prefab being loaded and instantiated multiple times, respectively
 ecb.RemoveComponent<RequestEntityPrefabLoaded>(entity);
 ecb.RemoveComponent<PrefabLoadResult>(entity);
 }
 ecb.Playback(state.EntityManager);
 ecb.Dispose();
 }
 }
    #endregion
实例化entity prefab可以使用EntityManager与entity command buffer。
#region InstantiateEmbeddedPrefabs
 public partial struct InstantiatePrefabSystem : ISystem
 {
 public void OnUpdate(ref SystemState state)
 {
 var ecb = new EntityCommandBuffer(Allocator.Temp);
 // Get all Entities that have the component with the Entity reference
 foreach (var prefab in
 SystemAPI.Query<RefRO<EntityPrefabComponent>>())
 {
 // Instantiate the prefab Entity
 var instance = ecb.Instantiate(prefab.ValueRO.Value);
 // Note: the returned instance is only relevant when used in the ECB
 // as the entity is not created in the EntityManager until ECB.Playback
 ecb.AddComponent<ComponentA>(instance);
 }
 ecb.Playback(state.EntityManager);
 ecb.Dispose();
 }
 }
    #endregion
实例化EntityPrefabReference,可以使用如下代码:
 #region InstantiateLoadedPrefabs
 public partial struct InstantiatePrefabReferenceSystem : ISystem
 {
 public void OnStartRunning(ref SystemState state)
 {
 // Add the RequestEntityPrefabLoaded component to the Entities that have an
 // EntityPrefabReference but not yet have the PrefabLoadResult
 // (the PrefabLoadResult is added when the prefab is loaded)
 // Note: it might take a few frames for the prefab to be loaded
 var query = SystemAPI.QueryBuilder()
                .WithAll<EntityPrefabComponent>()
                .WithNone<PrefabLoadResult>().Build();
 state.EntityManager.AddComponent<RequestEntityPrefabLoaded>(query);
 }
 public void OnUpdate(ref SystemState state)
 {
 var ecb = new EntityCommandBuffer(Allocator.Temp);
 // For the Entities that have a PrefabLoadResult component (Unity has loaded
 // the prefabs) get the loaded prefab from PrefabLoadResult and instantiate it
 foreach (var (prefab, entity) in
 SystemAPI.Query<RefRO<PrefabLoadResult>>().WithEntityAccess())
 {
 var instance = ecb.Instantiate(prefab.ValueRO.PrefabRoot);
 // Remove both RequestEntityPrefabLoaded and PrefabLoadResult to prevent
 // the prefab being loaded and instantiated multiple times, respectively
 ecb.RemoveComponent<RequestEntityPrefabLoaded>(entity);
 ecb.RemoveComponent<PrefabLoadResult>(entity);
 }
 ecb.Playback(state.EntityManager);
 ecb.Dispose();
 }
 }
    #endregion

Antes de crear una instancia de EntityPrefabReference, Unity primero debe cargar la entidad prefabricada correspondiente antes de poder usarla. Agregar el componente RequestEntityPrefabLoaded puede garantizar que la entidad prefabricada esté cargada. Unity cargará PrefabLoadResult en la misma entidad con RequestEntityPrefabLoaded.

Las casas prefabricadas también son entidades y también se pueden consultar. Si necesita consultar una casa prefabricada, puede agregar IncludePrefab a las condiciones de consulta.

 #region PrefabsInQueries
 // This query will return all baked entities, including the prefab entities
 var prefabQuery = SystemAPI.QueryBuilder()
                .WithAll<BakedEntity>().WithOptions(EntityQueryOptions.IncludePrefab).Build();
#endregion
使用EntityManager与entity command buffer也可以销毁一个预制体节点,代码如下:
            #region DestroyPrefabs
 var ecb = new EntityCommandBuffer(Allocator.Temp);
 foreach (var (component, entity) in
 SystemAPI.Query<RefRO<RotationSpeed>>().WithEntityAccess())
 {
 if (component.ValueRO.RadiansPerSecond <= 0)
 {
 ecb.DestroyEntity(entity);
 }
 }
 ecb.Playback(state.EntityManager);
 ecb.Dispose();
            #endregion

La serie Baking de hoy se comparte aquí. Sígueme para obtener más información sobre las últimas habilidades de desarrollo de Unity DOTS.

Supongo que te gusta

Origin blog.csdn.net/voidinit/article/details/134017936
Recomendado
Clasificación