• 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 alvaro-em · Sep 25, 2013 at 06:01 PM · prefabserializationarraysinheritance

Serializating a base class array to a prefab

I have been dealing with this issue for the whole week and I am kind of stuck and out of ideas.

I am working in a quick item editor. Each item may have one or more properties. These properties have all a common parent since they have common properties. Each child may also have particular properties.

I want to use the editor to show the properties array, edit it, and when finished, save the created gameobject to a prefab.

I almost have it working but I am facing a problem:

  • If I make MyBaseClass not to inherit from ScriptableObject (see comments on code below), everything works almost like a charm, but the child objects are casted to the parent class and they will remain like that forever. This problem was already stated here and was supposed to be solved with the next option, which is:

  • If I make MyBaseClass to inherit from ScriptableObject everything works fine before prefab creation, but then after creating the prefab, the array seems to be in a corrupted state. It seems that the CustomEditor is no longer correctly executed for that prefab.

This is my code, simplified for a better understanding. Just create each script separately (it should run as it is) and drag the SerializeMe.cs to a gameobject to reproduce the scenery. Remember to store SerializeMeInspector.cs into the Editor folder.

SerializeMe.cs

 using System;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEditor;
 
 [Serializable]
 public class SerializeMe : MonoBehaviour
 {
     [SerializeField]
     public List<MyBaseClass> m_Instances;
 
     public void OnEnable ()
     {
         if (m_Instances == null)
             m_Instances = new List<MyBaseClass>();
 
         hideFlags = HideFlags.HideAndDontSave;
     }
 }

MyBaseClass.cs

 using UnityEngine;
 using System;
 
 [Serializable]
 public class MyBaseClass : ScriptableObject
 //public class MyBaseClass
 {
     [SerializeField]
     public int m_IntField;
     
     public void OnEnable()
     {
         hideFlags = HideFlags.HideAndDontSave;
     }
 }
 

ChildClass.cs

 using UnityEngine;
 using System;
 
 [Serializable]
 public class ChildClass : MyBaseClass
 {
     [SerializeField]
     public float m_FloatField;
 }

SerializeMeInspector.cs (stored in the Editor folder)

 using UnityEngine;
 using System.Collections.Generic;
 using System;
 
 [CustomEditor(typeof(SerializeMe))]
 public class SerializeMeInspector : Editor
 {
     SerializedProperty SP_m_Instances;
     
     public void OnEnable()
     {
         SP_m_Instances = serializedObject.FindProperty ("m_Instances");
     }
     
     public override void OnInspectorGUI() 
     {
         serializedObject.Update ();
         
         if (GUILayout.Button ("Add Base"))
         {
             //(target as SerializeMe).m_Instances.Add(new MyBaseClass());
             (target as SerializeMe).m_Instances.Add(
                 (MyBaseClass) ScriptableObject.CreateInstance("MyBaseClass"));
         }
         
         if (GUILayout.Button ("Add Child"))
         {
             //(target as SerializeMe).m_Instances.Add(new ChildClass());
             (target as SerializeMe).m_Instances.Add(
                 (MyBaseClass) ScriptableObject.CreateInstance("ChildClass"));
         }
         
         for (int i = 0; i < SP_m_Instances.arraySize; i++)
         {    
             EditorGUILayout.Foldout(false,"Element #"+i);
             
             MyBaseClass parent = (target as SerializeMe).m_Instances[i];
             
             // Base common display
             parent.m_IntField = EditorGUILayout.IntField(
                 "Base prop", parent.m_IntField);
             
             // Child display if casting is a success
             ChildClass child;
             try 
             {    
                 child = (ChildClass) parent;
             }
             catch (InvalidCastException)
             {
                 child = null;
             }
             
             if (child != null)
             {
                 child.m_FloatField = EditorGUILayout.FloatField(
                     "Child prop", child.m_FloatField);
             }
             
         }
         
         serializedObject.ApplyModifiedProperties ();
     }
 }

I'd really appreciate any ideas or help with this.

Thank you very much in advance.

EDITED: Some code added as suggested by Bunny83, but still not working

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
0

Answer by alvaro-em · Sep 26, 2013 at 04:47 PM

I have found this great post about this exact issue. It seems that Unity does not serialize polymorphic types properly. In this post, a kind of workaround is offered. I will try it and let you know the results.

I am still willing to hear any other idea to get rid of this issue.

Additionally, you can vote for an idea to solve this issue right here.

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
0

Answer by Bunny83 · Sep 25, 2013 at 07:22 PM

You simply forgot to set the hideflags in OnEnable of your MyBaseClass.

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 alvaro-em · Sep 26, 2013 at 07:25 AM 0
Share

I have already set hideflags in OnEnable in $$anonymous$$yBaseClass, but it is still not working. As soon as I drag the object and create a prefab, the prefab get corrupted and it doesn't display the elements correctly. It only displays the first element.

I have been doing some debugging and I have realized that, at this line in Serialize$$anonymous$$eInspector.cs, inside the 'for' loop:

 $$anonymous$$yBaseClass parent = (target as Serialize$$anonymous$$e).m_Instances[i];

It happens that parent equals null, but SP_m_Instances.arraySize has the right value, so it kind of stops processing the file. That's why it only displays the first item.

Any ideas on what might be happening?

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

16 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

Related Questions

Script variable reverted to prefab when hit play. 1 Answer

Array of Arrays of GameObjects/Prefabs (C#) 1 Answer

Serialization with custom editor, prefab not saving (again) 1 Answer

Serializing invetory items data and InvalidOperationException exception 0 Answers

Handling inheritance with JSONUtility.ToJSON 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