Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by TigrisGames · Sep 17, 2020 at 05:26 AM · editorserializationeditorwindoweditorgui

how to display custom [system.serializable ] class in editor window

how to display custom serializable class in custom editor window

Comment
Add comment · Show 5
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ABerlemont · Nov 10, 2021 at 02:39 PM 0
Share

I just searched how to achieve this, here is my 2 cents for the next person in line xD

My understanding of the context :

Unity manage to draw something in the inspector because that thing go through SerializedObject/Property that you can imagine like a wrapper around the class you are trying to draw.

And WindowEditor doesn't have those tool accessible (doesn't go through the same functions when drawing).

So it would end up having a tool that draw each property of the class through reflection.

Using a ScriptableObject as a wrapper (that would include the target class) would be a way to have it drawn.

avatar image xxmariofer ABerlemont · Nov 10, 2021 at 06:34 PM 0
Share

mmmm, not really, unity serializes in the inspector the exact same way we serialize to a file. You don't need to do anything to display custom class in the unity editor, there is nothing fancy behind the serialization of the classes in the inspector.

avatar image ABerlemont xxmariofer · Nov 11, 2021 at 10:22 AM 0
Share

You can try to display something like :

[System.Serializable] public class TestClass { public int something = 1; }

and in an editor window script what would you use to draw that class ?

I tried multiple things but if it's not at least an Object, this won't work. Or I missed the specific EditorGuiLayout method to do it.

Show more comments
avatar image unity_ka6jgzfPPmtNCw · Nov 10, 2021 at 10:12 PM 0
Share

They also have to be of types that can be displayed in the inspector...

Otherwise, you need to create a customer editor.

3 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by ABerlemont · Nov 12, 2021 at 11:50 AM

Some experimentations based on what xxmariofer showed (reflexion & using UnityEngine.Object) and what Pangamini pointed out (window can have serialized field)

alt text

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEditor;
 using System;
 
 [System.Serializable]
 public class Test
 {
     public int var = 1;
 }
 
 [System.Serializable]
 public class TestMono : MonoBehaviour
 {
     public Test testInstance;
 
     private void Awake()
     {
         testInstance = new Test();
     }
 }
 
 public class TestSerialWin : EditorWindow
 {
     [MenuItem("Example/open")]
     static void Init()
     {
         EditorWindow.GetWindow(typeof(TestSerialWin));
     }
 
     TestMono carry;
 
     public Test myTestClassInstance;
 
     private void OnEnable()
     {
         myTestClassInstance = new Test();
     }
 
     private void OnGUI()
     {
         if (myTestClassInstance == null) myTestClassInstance = new Test();
 
         GUILayout.Space(10);
         GUILayout.Label("using mono");
 
         if (carry == null)
         {
             GameObject goc = GameObject.Find("lol");
             if (goc == null) goc = new GameObject("lol");
 
             if (goc == null) carry = goc.GetComponent<TestMono>();
             else goc.AddComponent<TestMono>();
 
             carry = goc.GetComponent<TestMono>();
         }
 
         drawByMonoCarry(carry);
 
         GUILayout.Space(10);
         GUILayout.Label("using window");
         drawBySerial(this);
 
         GUILayout.Space(10);
         GUILayout.Label("using reflection");
         drawByReflection();
     }
 
     /// <summary>
     /// this one is using a suer generated monobehavior to carry the Test instance
     /// </summary>
     void drawByMonoCarry(MonoBehaviour obj)
     {
         SerializedObject so = new SerializedObject(obj);
         
         SerializedProperty sp = so.FindProperty("testInstance"); // must match name of variable
         
         EditorGUILayout.PropertyField(sp);
     }
 
     /// <summary>
     /// this one is using the window editor as carrier of the Test instance
     /// </summary>
     void drawBySerial(UnityEngine.Object obj)
     {
         SerializedObject so = new SerializedObject(obj);
         
         SerializedProperty sp = so.FindProperty("myTestClassInstance"); // must match name of variable
 
         EditorGUILayout.PropertyField(sp);
     }
 
     /// <summary>
     /// this is one more "low level" and all GUILayout stuff must be done by hand
     /// </summary>
     void drawByReflection()
     {
         Type te = myTestClassInstance.GetType();
         System.Reflection.FieldInfo[] pi = te.GetFields();
         //Debug.Log(pi.Length);
 
         foreach (System.Reflection.FieldInfo p in pi)
         {
             EditorGUILayout.BeginHorizontal();
 
             Type pType = p.GetValue(myTestClassInstance).GetType();
 
             EditorGUILayout.LabelField(pType.ToString());
             EditorGUILayout.LabelField(p.Name);
             EditorGUILayout.LabelField(p.GetValue(myTestClassInstance).ToString());
 
             EditorGUILayout.EndHorizontal();
         }
         
     }
 }



2021-11-12-001054.png (13.4 kB)
2021-11-12-001052.png (14.0 kB)
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by Pangamini · Nov 11, 2021 at 11:33 AM

I'd go with EditorGUILayout.PropertyField. Nothing is stopping you from using that in a custom editor, however you probably need to create and manage the SerializedObject yourself. You could create a SerializedObject from the editor window, if you have a serialized field there (EditorWindows are ScriptableObjects and are serialized in the editor's window layout)

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by xxmariofer · Nov 11, 2021 at 12:00 PM

You only need a rerference to the custom class from the custom editor, this example to reproduce: this is the custom class with the variables:

 [System.Serializable]
 public class Test2
 {
     public string val { get; set; }
 }

this is the Monobehaviour in which the class exist, you dont serialize classes, you serialize instance of that class, so that instance must exist somewhere, in this case, a monobehaviour

 using UnityEngine;
 
 [System.Serializable]
 public class Test3 : MonoBehaviour
 {
     private void Awake()
     {
         t = new Test2();
         t.val = "this is an example";
     }
 
     public Test2 t;
 }

now the editor script:

 using UnityEditor;
 using UnityEngine;
 using System.Collections;
 using System;
 
 public class Test : EditorWindow
 {
     public System.Object source;
 
     [MenuItem("Example/ObjectField Example _h")]
     static void Init()
     {
         EditorWindow.GetWindow(typeof(Test));
     }
 
     void OnGUI()
     {
         EditorGUILayout.BeginVertical();
         //source = EditorGUILayout.ObjectField(source, typeof(UnityEngine.Object), true);
         source = GameObject.Find("PlaceHolder").GetComponent<Test3>().t;
 
         if (source != null)
         {
             Type te = source.GetType();
             System.Reflection.PropertyInfo[] pi = te.GetProperties();
             foreach (System.Reflection.PropertyInfo p in pi)
             {
                 try
                 {
                     EditorGUILayout.BeginHorizontal();
 
                     Debug.LogWarning(p.Name + " : " + p.GetValue(source));
                     EditorGUILayout.LabelField(p.Name);
                     EditorGUILayout.LabelField(p.GetValue(source).ToString());
 
                     EditorGUILayout.EndHorizontal();
                 }
                 catch
                 {
 
                 }
             }
         }
 
         EditorGUILayout.EndVertical();
     }
 }

you can use whatever method you prefer to get the class, this is the simplest example I could think of, the end result:

alt text


captura.png (2.3 kB)
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ABerlemont · Nov 11, 2021 at 01:53 PM 0
Share

Without using a custom specific drawer I think this might be the easiest setup to achieve this xD But feels kinda hack-y :)

avatar image xxmariofer ABerlemont · Nov 11, 2021 at 02:11 PM 0
Share

Without any details its hard to give another answer, probably he only needs to serialize some specifiq classes and overloading the tostring method to return the properties you expected to be shown would be probably a better solution without using reflection, but this is the most generic I could came up with

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

192 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Can't See all content of Editor 0 Answers

Weird action in Unity editor when pressing the "E" key? 1 Answer

Editor GUI Foldout header style customization 0 Answers

Detect when the Build button was pressed 2 Answers

OnSerialize event 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges