Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Showing nonserialized objects in the editor during playback

Discussion in 'Scripting' started by NoiseFloorDev, Aug 27, 2017.

  1. NoiseFloorDev

    NoiseFloorDev

    Joined:
    May 13, 2017
    Posts:
    104
    I have a runtime-only object which is marked [NonSerialized], but I want it to show up in the inspector during playback for debugging/tuning.

    Is there a sane way to do this? The only way I've found so far is to create a temporary object in the CustomEditor:

    Code (csharp):
    1.  
    2. [CustomEditor(typeof(MyClass))]
    3. public class MyClassInspector: Editor
    4. {
    5.     [Serializable]
    6.     class MyDataHolder: ScriptableObject
    7.     {
    8.         public MyData myData;
    9.     };
    10.  
    11.     public override void OnInspectorGUI()
    12.     {
    13.         DrawDefaultInspector();
    14.  
    15.         if(Application.isPlaying && MyClass.myData != null)
    16.         {
    17.             var holder = ScriptableObject.CreateInstance<MyDataHolder>();
    18.             holder.myData = MyClass.myData;
    19.  
    20.             SerializedObject tempObject = new SerializedObject(holder);
    21.             SerializedProperty myData = tempObject.FindProperty("myData");
    22.  
    23.             Editor e = Editor.CreateEditor(myData.objectReferenceValue);
    24.             e.DrawDefaultInspector();
    25.  
    26.             DestroyObject(holder);
    27.             DestroyObject(e);
    28.         }
    29.     }
    30. }
    31.  

    That works, but it's a pretty nasty hack. It's probably harmless in practice, but is there a less dumb way to do this?
     
  2. Chris-Trueman

    Chris-Trueman

    Joined:
    Oct 10, 2014
    Posts:
    1,260
    I found this code somewhere that creates a ShowOnly attribute.

    The class for the actual attribute. This can be placed anywhere
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. /// <summary>
    4. /// This will allow the use of a [ShowOnly] Attribute in scripts making a value read only in the Editor.
    5. /// This script is complimented by one in the Editor folder that is for drawing the read only value.
    6. /// </summary>
    7. public class ShowOnlyAttribute : PropertyAttribute
    8. {
    9.  
    10. }
    This is the property drawer for the ShowOnly attribute. This must be placed in an Editor folder.
    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. [CustomPropertyDrawer(typeof(ShowOnlyAttribute))]
    5. public class ShowOnlyDrawer : PropertyDrawer
    6. {
    7.     public override void OnGUI(Rect position, SerializedProperty prop, GUIContent label)
    8.     {
    9.         string valueStr;
    10.  
    11.         switch (prop.propertyType)
    12.         {
    13.             case SerializedPropertyType.Integer:
    14.                 valueStr = prop.intValue.ToString();
    15.                 break;
    16.             case SerializedPropertyType.Boolean:
    17.                 valueStr = prop.boolValue.ToString();
    18.                 break;
    19.             case SerializedPropertyType.Float:
    20.                 valueStr = prop.floatValue.ToString("0.00000");
    21.                 break;
    22.             case SerializedPropertyType.String:
    23.                 valueStr = prop.stringValue;
    24.                 break;
    25.             default:
    26.                 if (prop.objectReferenceValue)
    27.                     valueStr = prop.objectReferenceValue.name;
    28.                 else
    29.                     valueStr = "Not Supported!";
    30.                 break;
    31.         }
    32.  
    33.         EditorGUI.LabelField(position, label.text, valueStr);
    34.     }
    35. }
    You still need to setup for each Type that you want it to show, as of right now it doesn't have much but some value types.
     
  3. NoiseFloorDev

    NoiseFloorDev

    Joined:
    May 13, 2017
    Posts:
    104
    This is a complex class and I need to display its full inspector, but PropertyDrawers only seem to work with non-layout GUI. I don't know any way to use GUILayout-based code inside it, like DrawDefaultInspector and OnInspectorGUI...