Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 11 Next capture
2021 2022 2023
1 capture
11 Jun 22 - 11 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 AhrenM · Jul 25, 2015 at 03:42 PM · c#classnested

Instantiating a nested class ScriptableObject

Hi there, I'm having an issue creating an instance of a ScriptableObject where the class definition is nested within another class. The scenario is that I have "worker" classes that derive from ScriptableObject. Theses class have an internal data representation that for serialization reasons also needs to derive from ScriptableObject. The internal classes are public so are visible as types to the runtime, but ScriptableObject.Create() returns null.

Some repo code:

 using UnityEditor;
 using UnityEngine;
 
 //Worker class
 public class WorkingClass : ScriptableObject
 {
     //Internal data representation
     public class InternalData : ScriptableObject
     {
         public string InternalDataSet = "DATA";
     }
     //End internal data class
 
 
 
     private InternalData _internalData;
     
     //An accessor to the internal data
     public string DataAccess
     {
         get
         {
             return _internalData.InternalDataSet;
         }
     }
 
     //Worker class constructor
     public WorkingClass()
     {
         //This returns null :-(
         _internalData = (InternalData)ScriptableObject.CreateInstance(typeof(WorkingClass.InternalData));
     }
 
 }
 
 //Test harness
 public class TestWindow : EditorWindow
 {
     //Menu option to open the window
     [MenuItem("Window/Debug/Show Test Window")]
     public static void OpenWindow()
     {
         EditorWindow.GetWindow<TestWindow>();
     }
 
     //Worker class instance
     private WorkingClass _workingClass;
 
     //Test harness constructor
     public TestWindow()
     {
         this._workingClass = (WorkingClass)ScriptableObject.CreateInstance(typeof(WorkingClass));
         string shouldEqual_DATA = _workingClass.DataAccess; //Returns null :-(
     }
 }

Obviously this example is greatly simplified. The actual implementation has multiple instances of the InternalData records.

If I move the InternalData out of the WorkingClass, the Create requests work fine, but these classes have no business being in the public namespace and really shouldn't be there as they are not relevant outside of their parent Worker.

Does anyone know how to get this working?

Kind regards,

A.

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 syscrusher · Apr 14, 2016 at 03:07 PM 0
Share

I can't tell you how to fix it, but I can tell you that I replicated the problem in Unity 5.3.4.

I "solved" {ahem} the problem by breaking out the nested class into its own file as a main class.

avatar image Whatever560 · Feb 22, 2019 at 11:03 AM 0
Share

I'm aslo looking for a solution, though I believe Unity works with only first scope classes which name correspond to the filename. Its the same for all special objects ( behaviours, components, scriptableObject). I'm not sure there is a solution there. Did you found any workaround ?

avatar image Bonfire-Boy · Feb 22, 2019 at 04:32 PM 0
Share

Have you checked if your constructor is getting called? I wouldn't have expected it to (since ScriptableObjects are creats using ScriptableObject.CreateInstance rather than with new).

You could try something like this (untested)....

 public class WorkingClass : ScriptableObject
 {
     // your stuff plus....

     static public WorkingClass CreateInstance()
     {
         WorkingClass instance = ScriptableObject.CreateInstance<WorkingClass>();
         instance._internalData = ScriptableObject.CreateInstance<WorkingClass.InternalData>();
         return instance;
     }
 }

and then create them using WorkingClass.CreateInstance() ins$$anonymous$$d of ScriptableObject.CreateInstance();

avatar image Bonfire-Boy Bonfire-Boy · Feb 22, 2019 at 05:35 PM 0
Share

I just tested this and it solves your test case, so long as you use OnEnable() in TestWindow rather than its constructor. Like RobAnthem though, I am sceptical about whether or not ScriptableObjects is the right way to go with all this.

avatar image RobAnthem · Feb 22, 2019 at 04:38 PM 0
Share

The problem is that ScriptableObjects are more like containers, your nested class should not ALSO be a scriptable object, just a normal class object with [System.Serializable] tag to tell Unity to serialize it, then it will appear in editor when used as a field in the main object. I do this all the time and it works fine.

  using UnityEditor;
  using UnityEngine;
  
  //Worker class
  public class WorkingClass : ScriptableObject
  {
      [System.Serializable]
      public class InternalData
      {
          public string InternalDataSet = "DATA";
      }
      //End internal data class
  
  
  
      private InternalData _internalData;
      
      //An accessor to the internal data
      public string DataAccess
      {
          get
          {
              return _internalData.InternalDataSet;
          }
      }
  
      //Worker class constructor
      public WorkingClass()
      {
          //This returns null :-(
          _internalData = new _internalData();
      }
  
  }
  
  //Test harness
  public class TestWindow : EditorWindow
  {
      //$$anonymous$$enu option to open the window
      [$$anonymous$$enuItem("Window/Debug/Show Test Window")]
      public static void OpenWindow()
      {
          EditorWindow.GetWindow<TestWindow>();
      }
  
      //Worker class instance
      private WorkingClass _workingClass;
  
      //Test harness constructor
      public TestWindow()
      {
          this._workingClass = (WorkingClass)ScriptableObject.CreateInstance(typeof(WorkingClass));
          string shouldEqual_DATA = _workingClass.DataAccess; //Returns null :-(
      }
  }


As a side note, while you can't serialize Unity Objects with a Binary Formatter, you can still create serializable object fields in nested classes that contain unity objects, like this.

 public class SomeScriptableObject : ScriptableObject
 {
     [System.Serializable]
     public class ExtendedObjectInfo
     {
         public GameObject obj;
         public ObjectType objectType;
         public ObjectSubtype objectSubType;
     }
 }

Be aware though, that you can't change the data of a scriptable object at run time, it's for gameplay data and back-end usage, not localized storage. However BE AWARE any calls to change a scriptable object in editor, even in play mode, will change the scriptable object in the file system and retain the changes outside of play mode.

0 Replies

· Add your reply
  • Sort: 

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

6 People are following this question.

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

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

How to get PropertyAttribute or SerializedProperty owner class instance if it's nested? 1 Answer

Return a value from a custom class 3 Answers

Getting NullReferenceException when creating class instance using List 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