Search Unity

Inspector(entity debugger) for custom types

Discussion in 'Entity Component System' started by echeg, Mar 19, 2019.

  1. echeg

    echeg

    Joined:
    Aug 1, 2012
    Posts:
    90
    How extend inspector for custom structs?

    I try create boolean like:

    Code (CSharp):
    1. [Serializable]
    2. public struct Bool
    3. {
    4.     [SerializeField] private byte Value;
    5.  
    6.     public static implicit operator Bool(bool b) => new Bool() { Value = Convert.ToByte(b) };
    7.     public static implicit operator bool(Bool b) => b.Value == 1;
    8.  
    9.     public override string ToString() => Value == 1 ? "true" : "false";
    10.     public override int GetHashCode() => Value.GetHashCode();
    11. }
    12.  
    13. #if UNITY_EDITOR
    14. [CustomPropertyDrawer(typeof(Bool))]
    15. public class BlittableBoolDrawer : PropertyDrawer
    16. {
    17.     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    18.     {
    19.         EditorGUI.BeginProperty(position, label, property);
    20.         property.Next(true);
    21.         property.intValue = (EditorGUI.Toggle(position, label, property.intValue == 1 ? true : false) ? 1 : 0);
    22.         EditorGUI.EndProperty();
    23.     }
    24. }
    25. #endif
    Or like

    Code (CSharp):
    1. [Serializable]
    2. public struct TBool
    3. {
    4.     [SerializeField] private byte _value;
    5.     public TBool(bool value) { _value = (byte)(value ? 1 : 0); }
    6.     public static implicit operator TBool(bool value) { return new TBool(value); }
    7.     public static implicit operator bool(TBool value) { return value._value != 0; }
    8. }
    9.  
    10. #if UNITY_EDITOR
    11. [CustomPropertyDrawer(typeof(TBool))]
    12. class TBoolDrawer : PropertyDrawer
    13. {
    14.     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    15.     {
    16.         var field = property.FindPropertyRelative("_value");
    17.         field.intValue = EditorGUI.Toggle(position, label, field.intValue != 0) ? 1 : 0;
    18.     }
    19. }
    20. #endif
    In normal editor all looks fine



    Code (CSharp):
    1. public class InEditor : MonoBehaviour
    2. {
    3.  
    4.     public TBool b1;
    5.     public Bool b2;
    6.  
    7. }
    But in entity debugger I not see value



    Components and sys code:
    Code (CSharp):
    1. public class TickSystem : ComponentSystem
    2.     {
    3.         protected override void OnCreateManager()
    4.         {
    5.             var e = EntityManager.CreateEntity(typeof(Tick));
    6.             EntityManager.AddComponent(e, typeof(InPause));
    7.             EntityManager.AddComponent(e, typeof(InPause2));
    8.             EntityManager.SetComponentData(e, new InPause2(true));
    9.         }
    10.        
    11.         protected override void OnUpdate()
    12.         {
    13.             ForEach((ref Tick tick) => { tick.Value += 1; });
    14.         }
    15.     }
    16.    
    17.     [Serializable]
    18.     public struct Tick : IComponentData
    19.     {
    20.         public int Value;
    21.  
    22.         public Tick(int c)
    23.         {
    24.             Value = c;
    25.         }
    26.     }
    27.    
    28.     public struct InPause : IComponentData
    29.     {
    30.         public Bool Value;
    31.  
    32.         public InPause(bool c)
    33.         {
    34.             Value = c;
    35.         }
    36.     }
    37.    
    38.     public struct InPause2 : IComponentData
    39.     {
    40.         public TBool Value;
    41.  
    42.         public InPause2(bool c)
    43.         {
    44.             Value = c;
    45.         }
    46.     }

    How to make the Entity Debugger show the value of a Value (toogle or intfiled)?
     
  2. NoDumbQuestion

    NoDumbQuestion

    Joined:
    Nov 10, 2017
    Posts:
    186
    Add
    [Serializable]
    to InPause, InPause2. it will show up in inspector.

    And inside EntityInspector from package, it only use PropertyField to show serialized data from IComponentData so you have to write editor for custom Property for each ComponentData type
     
  3. echeg

    echeg

    Joined:
    Aug 1, 2012
    Posts:
    90
    I add [Serializable] to InPause and InPause2. And remove from Tick
    Code (CSharp):
    1.    
    2. //[Serializable]
    3. public struct Tick : IComponentData
    4. {
    5.     public int Value;
    6.  
    7.     public Tick(int c)
    8.     {
    9.         Value = c;
    10.     }
    11. }
    12.  
    13.     [Serializable]
    14.     public struct InPause : IComponentData
    15.     {
    16.         public Bool Value;
    17.  
    18.         public InPause(bool c)
    19.         {
    20.             Value = c;
    21.         }
    22.     }
    23.  
    24.     [Serializable]
    25.     public struct InPause2 : IComponentData
    26.     {
    27.         public TBool Value;
    28.  
    29.         public InPause2(bool c)
    30.         {
    31.             Value = c;
    32.         }
    33.     }
    But nothing change
     
  4. echeg

    echeg

    Joined:
    Aug 1, 2012
    Posts:
    90
    I looked at the source codes. Entity data draw by
    EntitySelectionProxy : ScriptableObject
    and
    Code (CSharp):
    1. selectionProxy = ScriptableObject.CreateInstance<EntitySelectionProxy>();
    2. selectionProxy.hideFlags = HideFlags.HideAndDontSave;
    3. selectionProxy.SetEntity(world, newSelection);
    4. Selection.activeObject = selectionProxy;
    He use EntitySelectionProxyEditor

    Code (CSharp):
    1.            
    2.               visitor = new EntityIMGUIVisitor((entity) =>
    3.                 {
    4.                     var targetProxy = (EntitySelectionProxy) target;
    5.                     if (!targetProxy.Exists)
    6.                         return;
    7.                     targetProxy.OnEntityControlDoubleClick(entity);
    8.                 });
    9.  
    If I add Interface in EntityIMGUIVisitor

    Code (CSharp):
    1.        
    2. internal class EntityIMGUIVisitor : PropertyVisitor
    3. ...
    4.  
    5. , ICustomVisit<float2x2>
    6. , ICustomVisit<TBool>
    7.  
    8.  
    9.         public void CustomVisit(TBool value)
    10.         {
    11.             Debug.Log("t bool");
    12.             EditorGUILayout.Toggle("custom bool", value);
    13.         }
    I achieve what i want )