Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
2
Question by Berenger · Dec 05, 2012 at 10:34 PM · serializationeditorwindowinstancecast

EditorWindow - Child class gets cast back to parent class at compilation.

Hi,

I'm playing around with the EditorWindow class, and I got this annoying problem :

  • Open the window

  • Instantiate instances of the parent class and the child class, stored inside a list.

  • Change something in any script, save and back in Unity.

  • The list is now full of the parent class, the child instances have been cast.

My hierarchy is pretty simple. There is the parent, ClassA (with [System.Serializable]) and the child ClassB which inherits from ClassA.

alt text

-> You can test it with this package, or that code and that one.

Any idea how to get around this ? Is hierarchy not possible in the editor ? Or just the list ?

--------------------------- [EDIT] ----------------------------------

Yep, Bunny's right. Here are the links with a version that works, plus the loading and saving as assets (package, or script 1, 2, 3 and 4. The scripts are, and must stay separated, and the files must have the name of the class, ClassA inside ClassA.cs !).

Here is an interesting thingy about ScriptableObjects, or, what a surprise, this answer :p

compi.jpg (28.7 kB)
Comment
Add comment
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

2 Replies

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

Answer by Bunny83 · Dec 05, 2012 at 11:49 PM

That has nothing to do with EditorWindow ;) It's Unity's serializer. Unity can only serialize it's own types. When you create a custom serializable class (not derived from MonoBehaviour or ScriptableObject) Unity will serialize the data along with the referencing class. So your class acts more like a struct. The type which is serialized is determined by the type of your variable. Since the variable (your list) has as type your base class, it will always be serialized as baseclass.

Furthermore when you store the same object several times in the list you will have several individual copies after deserialization. Again, they work more like structs. Basically you can't serialize custom classes in a baseclass variable.

The only types which do get serialized correctly (and can be used as base classes) are MonoBehaviour or ScriptableObject derived classes. A ScriptableObject has to be stored as Asset because Unity does not store it along with the referencing object (like "normal" classes). The best way to implement a class hierarchy that can be serialized by Unity is to use MonoBehaviours. You can attach all to the same GameObject if you want but in a lot cases it's easier to attach them to seperate GameObjects.

MonoBehaviour references are serialized correctly.

I haven't looked at Unity4 yet but i guess the serializer still works the same.

edit

btw, i figured that out the hard way :D I've done a quite complex node based editor just to discover Unity doesn't save any of my classes correctly. I switched completely to a MonoBehaviour based system.

ps. As far as i remember Strumpy's Shader editor uses ScriptableObjects to store the node tree, but it requires you to store them as Asset in the project, so they can't be saved to an object in the scene (like most serialization works beside prefabs).

second edit

Just saw that you stored the list directly in the EditorWindow class. Well, it actually doesn't make a difference. Unity does always serialize and deserialize all loaded objects when something changed in the project. Same happens when you press play or stop. The editor state get serialized and deserialized at runtime. When you come back to the edit mode it restores everything from the saved state.

Comment
Add comment · Show 4 · 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 Berenger · Dec 06, 2012 at 12:55 AM 0
Share

Thanks for the answer Bunny :) It's too late though, I can barely keep my eyes opened ^^ I'll check it out tomorrow.

avatar image Bunny83 · Dec 06, 2012 at 01:01 AM 0
Share

Same here ;) good luck on finding a workaround that fits you best.

avatar image Berenger · Dec 06, 2012 at 08:25 AM 0
Share

All righty, I'm back on track. I'll give it a shot tonight. Just to be clear, I'm doing a GUI editor, where you can drag & drop a button here, a label there etc. Each one needs to be attached to a gameObject created specifically for it then ?

avatar image Bunny83 · Dec 06, 2012 at 01:51 PM 0
Share

Yes, especially for a class based GUI system i would attach each component to a new Gameobject. That way you can use the transform class for positioning / scaling ( / rotating ).

avatar image
0

Answer by lastprogrammer · Dec 06, 2012 at 01:03 AM

That's because, from what I could tell of your code, your list is: List< class a >. When unity goes to de-serialize after any code compilation, it is going to only remember everything in that list as a class a type, not a class b type.

Does that make sense?

Serialization only works for the class that is actually defined in a generic list, not for any inherited types that are stored in the same list.

Comment
Add comment · Show 1 · 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 Bunny83 · Dec 06, 2012 at 01:49 PM 0
Share

Yes, but as i said it actually treats the class like a struct.

An example:

 [System.Serializable]
 public class $$anonymous$$yClass
 {
     public string Name;
     public $$anonymous$$yClass(string aName)
     {
         Name = aName;
     }
 }
 
 
 public class $$anonymous$$yComponent : $$anonymous$$onoBehaviour
 {
     public List<$$anonymous$$yClass> list;
 }
 
 
 // in your editorwindow:
 $$anonymous$$yClass tmp = new $$anonymous$$yClass("Test");
 list.Add(tmp);  // add the same class 3 times
 list.Add(tmp);
 list.Add(tmp);

Do this right after the above code:

 list[0].Name = "NewName";
 Debug.Log(list[1].Name);  // prints "NewName" since all 3 points to the same class instance.

But when you do this, after deserialization you will have 3 independent instances of $$anonymous$$yClass

 list[0].Name = "Another name";
 Debug.Log(list[1].Name);  // prints "NewName"

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

11 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

Related Questions

UnityEngine.Object field pointing to Project file gets serialized by JSON as instance ID. After deserialization field points to different Object. Why? 1 Answer

SerializedProperty and PropertyField NullReference 1 Answer

PropertyDrawer and EditorWindow 1 Answer

Why does my Unity Serialization not work? Do i miss something? 1 Answer

Edit and persist serializable Assets in the Editor Window 1 Answer


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