Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 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 g-s-100 · Jul 17, 2019 at 02:56 PM · buildnot workingstatic class

Static class not working properly on game build

I'm making a rpg-like game and I'm using a static class to carry the payer's basic information between scenes. Before loading a new scene my GameManager class saves the inventory and the player's HP on the static class, then on the new scene on it's Start function it loads the inventory and the HP. If I try it on the editor everything works fine, but when I build the game and try it out only the inventory is saved between the scenes, wich is weird because they are both handled by the same function.

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

3 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by kala-hari · Jul 17, 2019 at 05:26 PM

I don't know if it is defined how static members behave in the Editor. If the class is not unloaded when leaving Play mode, the assigned values might survive when switching from Edit to Play mode again.


An alternative you could check out is to keep the player information in a script attached to a game object that is shared between scenes.

The Object.DontDestroyOnLoad() method allows you to keep the (game) object when loading new scenes.

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 Zarenityx · Jul 17, 2019 at 05:40 PM 2
Share

This is not the case. Upon entering/leaving play mode, static fields are reset. If I understand correctly, scripts in play mode run in a separate application domain (almost as if they were a separate program entirely), and so static constructors are always called first in play mode (and thus static fields are reset).

That being said, your advice around using DontDestroyOnLoad() is still sound advice. Persistent data between scenes is best done with a persistent object, while data that is being shared across all scripts during the same point in time is a better candidate for static classes. This is because static classes can get reset for a number of reasons, since if that class is unloaded from the program for any reason (say, nothing else references it for a while), it can get reset. If your inventory is an array or class, but your HP is a float, this might mean that the inventory survives because it is referenced by something else, while the float gets reset. There's a lot of confusing stuff that can happen behind the scenes here and I am in no way an expert on how .NET runtime or Unity work at that deep a level.

The part that can also get tricky is editor serialization. Static variables are not serialized, and so the editor doesn't save/load them. Instance variables are serialized by the editor. The same cannot be said in build, where these variables are initialized from a serialized representation but then are left alone- there's no editor to mess with them any more. This is most easily noticed when using a slider on a float. In the editor, that float is clamped to a certain range, while in build it isn't, making it easy to forget to clamp the float yourself if needed.

avatar image g-s-100 · Jul 17, 2019 at 09:28 PM 0
Share

I created a singleton class with don't destroy on load, but the problem remains. It works fine on the unity player, the data is saved between scenes and the singleton isn't destroyed on load but when I build the game only the inventory is saved between the scenes, the HP reset to the default value. I don't know if it's important but, the inventory is an Item array (Item being a custom class) and the hp is a float array .

avatar image g-s-100 g-s-100 · Jul 17, 2019 at 09:30 PM 0
Share

Should I create a Class for the hp or is there a more elegant solution?

avatar image
0

Answer by Cornelis-de-Jager · Jul 17, 2019 at 09:44 PM

Hi g-s-100, Static classes in Unity work a bit differently than they would in C# normally. The reason why is complicated, but should you want to define a propper static class this is how you do it in Unity.

 public class GameManager : MonoBehaviour
 {
     //Static instance of GameManager which allows it to be accessed by any other script.
     public static GameManager instance = null;              
     
     /* Safe player info here */
     public int score;
     public string playerName;
     public int level;
     ...
     
     //Awake is always called before any Start functions
     void Awake()
     {
         //Check if instance already exists
         if (instance == null)
             
             //if not, set instance to this
             instance = this;
         
         //If instance already exists and it's not this:
         else if (instance != this)
             
             //Then destroy this. This enforces our singleton pattern, 
             // meaning there can only ever be one instance of a GameManager.
             Destroy(gameObject);    
         
         //Sets this to not be destroyed when reloading scene / Switching scenes
         DontDestroyOnLoad(gameObject); // VERY IMPORTANT
         
     }        
 }

Now the most important part. This class needs to actually exist in game. It needs to be attached to an in-game object. Not having this will result in your class not working as Static.

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 Zarenityx · Aug 23, 2019 at 06:09 PM 2
Share

This is entirely false. You need to have a script attached to a gameobject ONLY if you are using Awake(), Update(), or other $$anonymous$$onoBehaviour things. It is perfectly sensible to use a static class in many other contexts, especially for things like helper methods and short-term persistent state storage. What you have described is called a singleton, and is useful when you want static functionality and instance functionality at the same time. Singletons and static classes have similarities but are definitely NOT the same.

Static classes DO work just fine in Unity, as do non-monobehaviour instance classes. C# is C#, and all of its features will work the same in Unity as anywhere else. Unity does add a bit of magic with its AppDomain reload and the bizzare not-really-reflection that goes on around Update() and the like, but none of that really changes the behaviour of C#, it's just a behaviour that most non-Unity C# projects don't have.

avatar image
0

Answer by g-s-100 · Jul 17, 2019 at 11:38 PM

Thanks for your help, but actually the issue was somewhere else. After Loading the scene I couldn't acess the player's change health function (where i get the value from the static class). I fixed it with a coroutine so the function would execute properly on the next frame. I'm not sur if it's the best method to fix this but it seems to work properly now.

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 Cornelis-de-Jager · Jul 18, 2019 at 05:26 AM 0
Share

glad you found a solution

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

120 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

Related Questions

Distribute terrain in zones 3 Answers

Game works great, then i build and run, it no longer works. 1 Answer

Some objects not showing up in final build 2 Answers

Particlesystem only emitting once 1 Answer

Depth of field is not working when i build the game (HDRP) 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