Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Why can't we reference TextMeshProUGUI inside IComponentData?

Discussion in 'Entity Component System' started by alexandre-fiset, Feb 18, 2020.

  1. alexandre-fiset

    alexandre-fiset

    Joined:
    Mar 19, 2012
    Posts:
    702
    At the moment it is unfortunately impossible to reference TextMeshProUGUI inside an IComponentData class.

    At build time it throws this error:

    Code (CSharp):
    1. Something went wrong while Post Processing the assembly (Main.dll) :
    2. Member 'UnityEngine.TextCore.Glyph' is declared in another module and needs to be imported
    3.   at Mono.Cecil.MetadataBuilder.LookupToken (Mono.Cecil.IMetadataTokenProvider provider) [0x0003c] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    4.   at Mono.Cecil.SignatureWriter.MakeTypeDefOrRefCodedRID (Mono.Cecil.TypeReference type) [0x00000] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    5.   at Mono.Cecil.SignatureWriter.WriteTypeSignature (Mono.Cecil.TypeReference type) [0x00161] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    6.   at Mono.Cecil.SignatureWriter.WriteGenericInstanceSignature (Mono.Cecil.IGenericInstance instance) [0x00021] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    7.   at Mono.Cecil.SignatureWriter.WriteTypeSignature (Mono.Cecil.TypeReference type) [0x000cf] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    8.   at Mono.Cecil.SignatureWriter.WriteGenericInstanceSignature (Mono.Cecil.IGenericInstance instance) [0x00021] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    9.   at Mono.Cecil.MetadataBuilder.GetMethodSpecSignature (Mono.Cecil.MethodSpecification method_spec) [0x00023] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    10.   at Mono.Cecil.MetadataBuilder.CreateMethodSpecRow (Mono.Cecil.MethodSpecification method_spec) [0x00012] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    11.   at Mono.Cecil.MetadataBuilder.GetMethodSpecToken (Mono.Cecil.MethodSpecification method_spec) [0x00000] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    12.   at Mono.Cecil.MetadataBuilder.LookupToken (Mono.Cecil.IMetadataTokenProvider provider) [0x000cb] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    13.   at Mono.Cecil.Cil.CodeWriter.WriteOperand (Mono.Cecil.Cil.Instruction instruction) [0x00229] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    14.   at Mono.Cecil.Cil.CodeWriter.WriteInstructions () [0x0002c] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    15.   at Mono.Cecil.Cil.CodeWriter.WriteResolvedMethodBody (Mono.Cecil.MethodDefinition method) [0x0002e] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    16.   at Mono.Cecil.Cil.CodeWriter.WriteMethodBody (Mono.Cecil.MethodDefinition method) [0x0002b] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    17.   at Mono.Cecil.MetadataBuilder.AddMethod (Mono.Cecil.MethodDefinition method) [0x00013] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    18.   at Mono.Cecil.MetadataBuilder.AddMethods (Mono.Cecil.TypeDefinition type) [0x00013] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    19.   at Mono.Cecil.MetadataBuilder.AddType (Mono.Cecil.TypeDefinition type) [0x000a2] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    20.   at Mono.Cecil.MetadataBuilder.AddTypes () [0x00018] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    21.   at Mono.Cecil.MetadataBuilder.BuildTypes () [0x00014] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    22.   at Mono.Cecil.MetadataBuilder.BuildModule () [0x0009f] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    23.   at Mono.Cecil.MetadataBuilder.BuildMetadata () [0x00000] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    24.   at Mono.Cecil.ModuleWriter+<>c.<BuildMetadata>b__2_0 (Mono.Cecil.MetadataBuilder builder, Mono.Cecil.MetadataReader _) [0x00000] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    25.   at Mono.Cecil.ModuleDefinition.Read[TItem,TRet] (TItem item, System.Func`3[T1,T2,TResult] read) [0x00025] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    26.   at Mono.Cecil.ModuleWriter.BuildMetadata (Mono.Cecil.ModuleDefinition module, Mono.Cecil.MetadataBuilder metadata) [0x0000f] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    27.   at Mono.Cecil.ModuleWriter.Write (Mono.Cecil.ModuleDefinition module, Mono.Disposable`1[T] stream, Mono.Cecil.WriterParameters parameters) [0x000fb] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    28.   at Mono.Cecil.ModuleWriter.WriteModule (Mono.Cecil.ModuleDefinition module, Mono.Disposable`1[T] stream, Mono.Cecil.WriterParameters parameters) [0x00002] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    29.   at Mono.Cecil.ModuleDefinition.Write (System.IO.Stream stream, Mono.Cecil.WriterParameters parameters) [0x00019] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    30.   at Mono.Cecil.AssemblyDefinition.Write (System.IO.Stream stream, Mono.Cecil.WriterParameters parameters) [0x00000] in <58b86858c52b4b5fbb6efedd16c9c16a>:0
    31.   at Unity.Entities.CodeGen.EntitiesILPostProcessors.Process (Unity.CompilationPipeline.Common.ILPostProcessing.ICompiledAssembly compiledAssembly) [0x000df] in C:\Plastic\2019_kona2\Library\PackageCache\com.unity.entities@0.6.0-preview.24\Unity.Entities.CodeGen\EntitiesILPostProcessor.cs:58
    32.   at UnityEditor.Scripting.ScriptCompilation.ILPostProcessing.RunILPostProcessors (UnityEditor.Scripting.ScriptCompilation.ScriptAssembly assembly, System.String outputTempPath) [0x0011b] in <c10752821eec4acbb89ccd53fbbc5e27>:0
    33.   at UnityEditor.Scripting.ScriptCompilation.ILPostProcessing.PostProcess (UnityEditor.Scripting.ScriptCompilation.ScriptAssembly assembly, System.Collections.Generic.List`1[T] messages, System.String outputTempPath) [0x00061] in <c10752821eec4acbb89ccd53fbbc5e27>:0
    34.  

    Is there any reason for this?

    The workaround is to store it in a Monobehaviour and add it on an entity through AddComponentObject. This is not very convenient.
     
  2. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    IComponentData cannot contain any managed references. The MonoBehaviour/AddComponentObject workaround you describe is the only way to do it for the time being.
     
  3. alexandre-fiset

    alexandre-fiset

    Joined:
    Mar 19, 2012
    Posts:
    702
    That is not true, a IComponentData class can hold managed references.
     
  4. l33t_P4j33t

    l33t_P4j33t

    Joined:
    Jul 29, 2019
    Posts:
    232
    i think thats only while running on the main thread and without burst.. no?
     
  5. alexandre-fiset

    alexandre-fiset

    Joined:
    Mar 19, 2012
    Posts:
    702
    Of course, anything "Ui" at the moment can't run anywhere else anyway.
     
  6. Curlyone

    Curlyone

    Joined:
    Mar 15, 2018
    Posts:
    41
    i have the same problem, were you able to fix this ? or you stick with AddComponentObject way ?
     
  7. alexandre-fiset

    alexandre-fiset

    Joined:
    Mar 19, 2012
    Posts:
    702
    What I do for UI is that I have one IComponentData struct that is just a tag, and a ComponentObject that is a Monobehaviour referencing every MonoBehaviour or ScriptableObject that I need in a specific context.

    This way all ECS systems requiring just some data can do it in burst and jobs, but UI-specific things are running in non-burst on the main thread.

    The advantage of this is as some components become available in ECS, I just have to move them to the struct until all are gone.

    Ex:

    Code (CSharp):
    1. using TMPro;
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4. namespace Ui.Views.ItemInspector
    5. {
    6.      public class ItemInspectorViewObject : MonoBehaviour
    7.      {
    8.          public TextMeshProUGUI TitleText = null;
    9.          public TextMeshProUGUI DescriptionText = null;
    10.          public Image SpriteImage = null;
    11.    
    12.      }
    13. }
    Code (CSharp):
    1. using Items.EquippedAnimation.InspectMode;
    2. using Parabole.Ui.ViewSystem;
    3. using Ui.ScriptableObjects;
    4. using Unity.Entities;
    5.  
    6. namespace Ui.Views.ItemInspector
    7. {
    8.     [UpdateInGroup(typeof(InspectModeSystemGroup))]
    9.     [UpdateAfter(typeof(TriggerInspectModeEquipSystem))]
    10.     public class ItemInspectorViewShowSystem : SystemBase
    11.     {
    12.         private EntityQuery _viewQuery;
    13.        
    14.         protected override void OnCreate()
    15.         {
    16.             _viewQuery = GetEntityQuery(
    17.                 ComponentType.ReadOnly<ItemInspectorView>(),
    18.                 ComponentType.ReadOnly<ItemInspectorViewObject>(),
    19.                 ComponentType.ReadOnly<ShowItemInspectorView>(),
    20.                 ComponentType.Exclude<Visible>());
    21.  
    22.             RequireForUpdate(_viewQuery);
    23.         }
    24.  
    25.         protected override void OnUpdate()
    26.         {
    27.             Entities
    28.                 .WithAll<ItemInspectorView>()
    29.                 .WithoutBurst()
    30.                 .ForEach((ItemInspectorViewObject viewObj, in ShowItemInspectorView showItem) =>{
    31.                     var uiData = EntityManager.GetComponentObject<ItemUiData>(showItem.ItemEntity);
    32.                     viewObj.TitleText.SetText(uiData.Name);
    33.                     viewObj.DescriptionText.SetText(uiData.Description);
    34.                     viewObj.SpriteImage.sprite = uiData.Sprites.Sprite_64;})
    35.                 .Run();
    36.  
    37.             EntityManager.AddComponent<Show>(_viewQuery);
    38.         }
    39.     }
    40. }
     
    Curlyone and thebanjomatic like this.