Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
1
Question by Felrahr · Feb 20, 2020 at 02:08 PM · serializationscriptableobject

Why does a ScriptableObject saves nonserialized fields?

I have the following two classes:

TestBehaviour.cs:

 using UnityEngine;
 
 public class TestBehaviour : MonoBehaviour
 {
     public TestObject TestObject;
     private bool Value = false;
 
     private void Start()
     {
         TestObject.TestFunction();
         Debug.Log("MonoBehaviour Value: " + Value);
         Value = true;
     }
 }

and TestObject.cs:

 using UnityEngine;
 
 [CreateAssetMenu]
 public class TestObject : ScriptableObject
 {
     private bool value = false;
 
     public void TestFunction()
     {
         Debug.Log("ScriptableObject Value: " + value);
         value = true;
     }
 }

When I load the project and run it the first time, both logs are false as i would expect. But in the second excecution the output of the ScriptableObject is true.

Now I would like to know, how to prevent a ScriptableObject from saving those nonserialized fields I want to use to save the state of my object.

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

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by Bunny83 · Feb 20, 2020 at 02:48 PM

The values are not serialized to disk. It's just that the object loaded in memory from your assets will of course keep the current value. Try closing the Unity editor, open it again and you will see that the value is back to false. Assets are, from the life cycle point of view, loaded once and remain in memory until your application is shut down.


Technically it is true that when entering playmode Unity does perform an assembly reload. At this point usually all non serialized data would be lost since Unity destroys the whole appdomain including all objects. However when an assembly reload happens Unity does actually save and restore even private fields it can serialize. Otherwise hotreloading wouldn't be possible at all.


If you specifically want to prevent private fields to survive hot reloading / an assembly reload you have to use the NonSerialized attribute on your field. That will prevent Unity from ever saving this field. This is actually mentioned at the very end of the script serialization documentation. To quote:


When reloading scripts, Unity restores all variables - including private variables - that fulfill the requirements for serialization, even if a variable has no SerializeField attribute. In some cases, you specifically need to prevent private variables from being restored: For example, if you want a reference to be null after reloading from scripts. In this case, use the NonSerialized attribute.

Comment
Add comment · Show 3 · 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 guneyozsan · Feb 07, 2021 at 10:40 PM 0
Share

Still, the "Play - Stop - Play" behaviour is different for $$anonymous$$onobehaviours and ScriptableObjects. ScriptableObjects remember values of private fields for sequential plays after stop, while $$anonymous$$onobehaviours do not. Then it boils down to "same code, two behaviours".

avatar image Bunny83 guneyozsan · Feb 08, 2021 at 02:23 AM 0
Share

Not really. The difference is the lifetime of the objects. $$anonymous$$onoBehaviours live in the scene. The scene is reloaded when you enter playmode. ScriptableObject assets do not live in the scene but are assets in the project.

You will actually see the exact same behaviour if you change a private non serialized field in a monobehaviour of a prefab in the project (note: I don't mean a prefab instance in the scene but the actual prefab in the project). I quickly did a test just to be sure and yes, it works exactly the same.


So I declared a private non serialized bool variable in a scriptable object and inside a monobehaviour. I attached the monobehaviour to an object and made a prefab out of that object. I delete the instance from the scene. Now I created another script from which I can set / reset the boolean values in those two objects. So I referenced both, the scriptableobject instance that is stored in the project as asset, as well as the prefab that is also stored as asset in the project. The default value of the booleans is set to false. When I set the two booleans to true and stopped the game, the private variables kept their true values. When I re-enter play mode they are both still true. However none of those true values are actually serialized. When I restart Unity, both values are back to false.


As I said a $$anonymous$$onoBehaviour instance that lives in the scene of course behaves differently as the scene is loaded / unloaded when you enter / leave playmode. So this has nothing to do with ScriptableObject or $$anonymous$$onoBehaviour but simply where they are located and when and how they are loaded in memory. Keep in $$anonymous$$d that from the engine's point of view a ScriptableObject and a $$anonymous$$onoBehaviour are represented by the exact same class on the native side which handles the serialization of those instances.

avatar image Bunny83 guneyozsan · Feb 08, 2021 at 02:40 AM 0
Share

The main reason why private variables in assets actually survive is because the editor does serialize private variables as well when it comes to assembly reloads which also happens at playmode change. It just does not serialize the value to disk. So as long as an object stays loaded, the value will survive.


If you want to ensure that your private variable are never serialized, you can use the System.NonSerialized attribute, even on private variables, to ensure they are never serialized. This is mentioned at the very end of the script serialization page as I already said in my answer.


ps: If you want a repo case, here are 3 files:

  • Test$$anonymous$$onoBehaviour.cs

  • TestScriptableObject.cs

  • editor/PrivateVarSetter.cs

Create a prefab with the Test$$anonymous$$onoBehaviour attached and also create an asset of the TestScriptableObject. So you have two assets in your project and nothing in your scene as this is all about asset serialization. Open the editor window and assign your two assets to the corresponding fields. You should now have a set and reset button for the private testBool variable in each of the two classes. You also see the current state of the boolean value at the end. Now try setting both to true and change playmode. You will notice that both will stay true.


Now uncomment the "System.NonSerialize" attribute in both files and try again. When you enter playmode both variables will turn false again due to the assembly reload that is happening. Note that setting the values to true during playmode will keep their values when you exit playmode. That's because when you exit playmode there is no assembly reload, so the values and the actual instances stay in memory. Though on next play they will be false again.


Again this is all about the lifetime of assets vs instances serialized into scenes. A scene will never stay loaded unlike assets. So the different behaviour comes from this fact and not from the fact that one is a ScriptableObject and the other a $$anonymous$$onoBehaviour. As you can see here both behave the same when serialized as asset.

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

131 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

Related Questions

ScriptableObject asset loses reference after restarting Unity 1 Answer

[Solved]How to serialize Dictionary with Unity Serialization System 6 Answers

ScriptableObject : Serialized Polymorphism Classes Can Not be Deserialize with Polymorphism 1 Answer

Serializing ScriptableObject into scene without writing to asset 1 Answer

ScriptableObject loses data after Reload 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