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
9
Question by absameen · Apr 28, 2012 at 10:27 AM · serialization

Does Unity Serialization Support Inheritence?

I am having trouble saving custom child classes in my editor script. Data from the child classes is being lost. The question is, does Unity serialization support inheritance? Here is an example of the problem:

 // Serialize
 [System.Serializable]
 public ParentClass()
 {
   public string someString = "a string";
 }
 [System.Serializable]
 public ChildClass() : ParentClass
 {
   public int someInt;
   public ChildClass(int _someInt)
   {
     someInt = _someInt;
   }
 }
 
 List<ParentClass> list = new List<ParentClass>();
 list.Add(new ChildClass(5));
 
 // Data is saved
 // Exit Unity
 // Data is loaded
 
 Debug.Log(list[0].someString);
 // Output: a string; Works as intended
 
 Debug.Log((list[0] as ChildClass).someInt));
 // Null Reference Exception
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

6 Replies

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

Answer by Bunny83 · Apr 28, 2012 at 08:24 PM

Unity determine the instance type via the variable type. If you store a subclass in a base class variable it gets serialized as base class.

However there is a way to use inheritance with serialization: ScriptableObject.

Your base class has to be derived from ScriptableObject. In this case Unity will remember the true type when you store a sub / child class in a base-class variable.

ScriptableObjects have to be created with ScriptableObject.CreateInstance and destroyed with Destroy.

Unity fully supports only types derived from UnityEngine.Object. A "normal" class (derived from System.Object) is not really serialized. Unity just stores the serializeable fields it can find within the class that is actually serialized (for example a MonoBehaviour that holds the reference to an instance).

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 Kryptos · Apr 30, 2012 at 07:39 AM 0
Share

@Bunny83 ScriptableObject are not meant for inheritance but rather to save (dump) a class serialization into a file (asset), as can be read in the Scripting Reference.

avatar image Bunny83 · Apr 30, 2012 at 12:49 PM 0
Share

@$$anonymous$$ryptos: Yes and no ;) A ScriptableObject is a fully supported type in Unity which get serialized as whole object, like $$anonymous$$onoBehaviour derived classes. You don't have to store a ScriptableObject in a seperate asset file. If you create an instance (for example via a custom editor) and reference this instance from a $$anonymous$$onoBehaviour in the scene, the ScriptableObject will get saved (serialized) along with the scene itself exactly like the $$anonymous$$onoBehaviour instances.

The difference between a ScriptableObject and a $$anonymous$$onoBehaviour is that a ScriptableObject doesn't need to be attached to a GameObject and it doesn't have Update / Start / ... callbacks.

The only alternative is to use $$anonymous$$onoBehaviour derived objects and attach them to a GameObject since they also support inheritance.

I've done this in my nodebased editor. I create an empty sub gameobject which works as container for my class instances. Those instances can be referenced in an array / List of the base type and will remember the actual reference.

avatar image
5

Answer by vexe · Jan 04, 2015 at 11:15 AM

I know this might be old thread, but I'd like to share my solution in case someone in the future came across this question.

In order to overcome the limitations of Unity's serialization system you need to write your own custom system. With the help of ISerializationCallbackReceiver and a custom serializer, I was able to do just that in VFW. There's support for polymorphic types (interfaces and abstract system objects), generics, auto-properties, delegates, readonly fields, static fields/auto-props and much more.

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 kornel-l-varga · Apr 22, 2021 at 11:24 AM

I have found a great answer (not the accepted one) here by @Ruzihm : https://answers.unity.com/questions/1247233/derived-class-serialization.html

Use the [SerializeReference] decorator on the fields you want to keep their derivate values and type.

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 Tseng · Apr 28, 2012 at 04:13 PM

ParentClass do not expose someInt variable, that's the reason why you can't access it. Unity (or Mono) is doing something strange there. If you want someInt to be serialized and displayed in the inspector, you have to replace List<ParentClass> list with List<ChildClass> list.

Though this won't allow you to add ParentClass objects to the list, because they do not have someInt. That's how inheritance works. With the "Parent class" as you call it, you can only access the most common denominator of all classes that are based on it.

To access the added members, you have to upcast it again

 ParentClass parent = new ChildClass();
 Debug.Log(parent.astring);

 ChildClass child = (ChildClass)parent;
 Debug.Log(child.someInt);
 // or
 Debug.Log( ((ChildClass)parent).someInt) );
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 · Apr 28, 2012 at 08:26 PM 1
Share

If you could only reference an instance with its specific type that would make inheritance quite useless ;)

avatar image
-2

Answer by bompi88 · Apr 28, 2012 at 02:58 PM

Have you tried to keep each class in its own file? Like this:

ParentClass.cs :

 using UnityEngine;
 using System.Collections;
 
 [System.Serializable]
 public class ParentClass
 {
   public string someString = "a string";
 }

ChildClass.cs :

 using UnityEngine;
 using System.Collections;
 
 [System.Serializable]
 public class ChildClass : ParentClass
 {
   public int someInt;
   public ChildClass(int _someInt)
   {
     someInt = _someInt;
   }
 }

LoadAndWrite.cs :

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class LoadAndWrite : MonoBehaviour
 {
     void Start() {
 
         List<ParentClass> list = new List<ParentClass>();
         list.Add(new ChildClass(5));
         
         // Data is saved
         // Exit Unity
         // Data is loaded
         Debug.Log(list[0].someString);
         
         Debug.Log((list[0] as ChildClass).someInt);
     }
 }

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 Tseng · Apr 28, 2012 at 04:16 PM 0
Share

That's wrong. A public class is not automatically serialized. A public class won't even show in the inspector unless it's derived from UnityeEngine.Object (which almost all of Unity base classes are).

If it's derived from UnityeEngine.Object, then it will be serialized but as "object" selector (i.e. where you can drag objects containing SomeClassName (Prefabs, GameObjects from scene)). Only if your add the serialize attribute the members of the object will be exposed and serialized in the Inspector

avatar image bompi88 · Apr 28, 2012 at 05:12 PM 0
Share

Ok, thanks for your amendment.

  • 1
  • 2
  • ›

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

prevent field json serialization in 5.3 0 Answers

JsonUtility not found / working 0 Answers

How to store references between scriptableobject assets 3 Answers

Trying to Use DataContractSerializer with 0 Answers

Unserialized private variable values from static instance persist when exiting play mode 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