Search Unity

Invisible MeshInstanceRenderer

Discussion in 'Graphics for ECS' started by Tony_Max, Dec 18, 2018.

  1. Tony_Max

    Tony_Max

    Joined:
    Feb 7, 2017
    Posts:
    353
    In my project I need dynamically change visibility of meshs. I think that creating and destroing entities every time I need change visibility is a bad way. I see no components like Invisible : IComponentData. Is there any way to do this without rewriting MeshInstanceRendererSystem with new substractive component?
     
  2. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    559
    you can create and destroy entities dynamically, and it's also fast (no GC allocations)

    so unless you need a stable and direct reference to those entities, you can just do that

    there is also a Disabled component that causes all queries to ignore those entities
     
  3. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    After playing with Disabled-as-invisible I think we need a proper Invisible component that just ignore the render part. It cause so many bugs when "no system is able to find the entity". Mainly in the TransformSystem : Attach registered but cannot attach Depth to disabled parent, disabling the parent throws tons of error from the child, if something starts with Disabled then it can miss the LocalToWorld assignment, then later routine is expecting LTW to be present when it comes out of Disabled and throws, etc.
     
    Tony_Max likes this.
  4. Tony_Max

    Tony_Max

    Joined:
    Feb 7, 2017
    Posts:
    353
    In my case I need stable reference to those entities. So way of creating/destroing entities requires sub reference to entity that contains MeshInstanceRenderer and also I will need to store data about what Mesh, Material etc. I makes visible and invisible.

    Also I can just have stable entity that will contain only MeshInstanceRenderer and add/remove Disable on it.
     
  5. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    559
    you can also just remove the MIR component (provided you have a way to restore it, like a dictionary somewhere)
     
  6. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    The way it can be done is create component DisabledMIR with one filed of type MeshInstanceRenderer
    and for disabling just copy MeshInstanceRenderer into DisabledMIR field and remove MIR component.

    For enabling make the opposite
     
  7. Tony_Max

    Tony_Max

    Joined:
    Feb 7, 2017
    Posts:
    353
    @Jes28 this is exactly what I meant
     
    Last edited: Dec 19, 2018
  8. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    I wrote a system for this a while ago (though after looking at it now and reading through it there's a few things i want to change, but it works as far as i'm aware.)

    System that disables entities from updating in the <see cref="TransformSystem"/> and stops them rendering in the <see cref="MeshInstanceRendererSystem"/>.


    Just add the Hidden component to any entity and voila, nothing else required. Works for both MeshInstanceRenderer as well as hybrid MeshRenderers.

    Code (CSharp):
    1. // <copyright file="Components.cs" company="Timothy Raines">
    2. //     Copyright (c) Timothy Raines. All rights reserved.
    3. // </copyright>
    4. // <summary>
    5. //   Components for the hidden system
    6. // </summary>
    7.  
    8. namespace BovineLabs.Systems.Hidden
    9. {
    10.     using Unity.Entities;
    11.  
    12.     /// <summary>
    13.     ///     Mark a mesh instance renderer as being hidden.
    14.     /// </summary>
    15.     public struct Hidden : IComponentData
    16.     {
    17.     }
    18. }
    Code (CSharp):
    1. // <copyright file="HiddenSystem.cs" company="Timothy Raines">
    2. //     Copyright (c) Timothy Raines. All rights reserved.
    3. // </copyright>
    4.  
    5. namespace BovineLabs.Systems.Hidden
    6. {
    7.     using System;
    8.     using Unity.Collections;
    9.     using Unity.Entities;
    10.     using Unity.Rendering;
    11.     using Unity.Transforms;
    12.     using UnityEngine;
    13.  
    14.     /// <summary>
    15.     /// System that disables entities from updating in the <see cref="TransformSystem"/> and stops them rendering in the <see cref="MeshInstanceRendererSystem"/>.
    16.     /// </summary>
    17.     public class HiddenSystem : ComponentSystem
    18.     {
    19.         private ComponentGroup hidePureQuery;
    20.         private ComponentGroup showQuery;
    21.         private ComponentGroup hideHybridQuery;
    22.         private ComponentGroup showHybridQuery;
    23.  
    24.         private ArchetypeChunkEntityType entityTypesRO;
    25.         private ComponentDataFromEntity<Frozen> frozenRO;
    26.  
    27.         /// <inheritdoc />
    28.         protected override void OnCreateManager()
    29.         {
    30.             this.hidePureQuery = this.GetComponentGroup(
    31.                 new EntityArchetypeQuery
    32.                 {
    33.                     Any = Array.Empty<ComponentType>(),
    34.                     None = new ComponentType[] { typeof(IsHiddenTag) },
    35.                     All = new[] { ComponentType.ReadOnly<Hidden>(), ComponentType.ReadOnly<LocalToWorld>() },
    36.                 });
    37.  
    38.             this.hideHybridQuery = this.GetComponentGroup(
    39.                 ComponentType.ReadOnly<Hidden>(),
    40.                 ComponentType.ReadOnly<Transform>(),
    41.                 ComponentType.Subtractive<IsHiddenTag>());
    42.  
    43.             this.showQuery = this.GetComponentGroup(
    44.                 new EntityArchetypeQuery
    45.                 {
    46.                     Any = Array.Empty<ComponentType>(),
    47.                     None = new ComponentType[] { typeof(Hidden), typeof(LocalToWorld) },
    48.                     All = new[] { ComponentType.ReadOnly<Frozen>(), ComponentType.ReadOnly<IsHiddenTag>() },
    49.                 });
    50.  
    51.             this.showHybridQuery = this.GetComponentGroup(
    52.                 ComponentType.Subtractive<Hidden>(),
    53.                 ComponentType.ReadOnly<IsHiddenTag>(),
    54.                 ComponentType.ReadOnly<Transform>());
    55.         }
    56.  
    57.         /// <inheritdoc/>
    58.         protected override void OnUpdate()
    59.         {
    60.             this.entityTypesRO = this.GetArchetypeChunkEntityType();
    61.             this.frozenRO = this.GetComponentDataFromEntity<Frozen>(true);
    62.  
    63.             this.HideHybridEntities();
    64.             this.HidePureEntities();
    65.  
    66.             this.ShowHybridEntities();
    67.             this.ShowEntities();
    68.         }
    69.  
    70.         private void HideHybridEntities()
    71.         {
    72.             var transforms = this.hideHybridQuery.GetTransformAccessArray();
    73.  
    74.             if (transforms.length == 0)
    75.             {
    76.                 return;
    77.             }
    78.  
    79.             for (var i = 0; i < transforms.length; i++)
    80.             {
    81.                 var transform = transforms[i];
    82.  
    83.                 transform.gameObject.SetActive(false);
    84.             }
    85.         }
    86.  
    87.         private void HidePureEntities()
    88.         {
    89.             var chunks = this.hidePureQuery.CreateArchetypeChunkArray(Allocator.TempJob);
    90.  
    91.             if (chunks.Length == 0)
    92.             {
    93.                 chunks.Dispose();
    94.                 return;
    95.             }
    96.  
    97.             foreach (var chunk in chunks)
    98.             {
    99.                 var chunkCount = chunk.Count;
    100.  
    101.                 var entities = chunk.GetNativeArray(this.entityTypesRO);
    102.  
    103.                 for (var i = 0; i < chunkCount; i++)
    104.                 {
    105.                     var entity = entities[i];
    106.  
    107.                     if (!this.frozenRO.Exists(entity))
    108.                     {
    109.                         this.PostUpdateCommands.AddComponent(entity, default(Frozen));
    110.                     }
    111.  
    112.                     this.PostUpdateCommands.RemoveComponent<LocalToWorld>(entity);
    113.                     this.PostUpdateCommands.AddComponent(entity, default(IsHiddenTag));
    114.                 }
    115.             }
    116.  
    117.             chunks.Dispose();
    118.         }
    119.  
    120.         private void ShowHybridEntities()
    121.         {
    122.             var transforms = this.showHybridQuery.GetTransformAccessArray();
    123.  
    124.             if (transforms.length == 0)
    125.             {
    126.                 return;
    127.             }
    128.  
    129.             for (var i = 0; i < transforms.length; i++)
    130.             {
    131.                 var transform = transforms[i];
    132.  
    133.                 transform.gameObject.SetActive(true);
    134.             }
    135.         }
    136.  
    137.         private void ShowEntities()
    138.         {
    139.             var chunks = this.showQuery.CreateArchetypeChunkArray(Allocator.TempJob);
    140.  
    141.             if (chunks.Length == 0)
    142.             {
    143.                 chunks.Dispose();
    144.                 return;
    145.             }
    146.  
    147.             foreach (var chunk in chunks)
    148.             {
    149.                 var chunkCount = chunk.Count;
    150.  
    151.                 var entities = chunk.GetNativeArray(this.entityTypesRO);
    152.  
    153.                 for (var i = 0; i < chunkCount; i++)
    154.                 {
    155.                     var entity = entities[i];
    156.                     this.PostUpdateCommands.RemoveComponent<Frozen>(entity);
    157.                     this.PostUpdateCommands.RemoveComponent<IsHiddenTag>(entity);
    158.                 }
    159.             }
    160.  
    161.             chunks.Dispose();
    162.         }
    163.  
    164.         /// <summary>
    165.         /// Tag to mark the entity as being hidden.
    166.         /// </summary>
    167.         private struct IsHiddenTag : IComponentData
    168.         {
    169.         }
    170.     }
    171. }