- Home /
How can I have a static class I can access from any place in my game?
If I have the following code:
static class SceneData
{
static int width=100;
static int score;
static GameObject soundManager;
}
Can I use this to keep score that's available in all my scenes? If so then do I have to make an empty gameobject in each scene and then just attach the script to that or is there more I have to do?
Answer by dscroggi · Sep 26, 2012 at 10:56 AM
Sure! I am using the same methods in my own project right now.
First let me say that a guy named Petey has a youtube channel called BurgZergArcade that has some really awesome Unity3d C# programming videos!
That channel is here: http://www.youtube.com/user/BurgZergArcade
Anyway what I usually do that I learned from Petey is make a new empty gameobject and name it GameMaster, then make a C# script named GameMaster.cs.
There's at least two ways to do this. Here's the first way:
using UnityEngine;
public class GameMaster : MonoBehaviour
{
public static int score;
void Awake()
{
DontDestroyOnLoad(this);
}
}
This is the quick and easy way to access variables like 'score' from any class. To do this just call GameMaster.score from anywhere. The problem with this method is that it only works well for simple data types like int. Most of the time we want to drag and drop in Assets via the inspector, and this isn't allowed with static variables.
In this case we create what's called a singleton. This is something Leepo from M2H uses in his multiplayer tutorials. We create a regular class and then make one single static instance of the whole class. This is the second way:
using UnityEngine;
public class GameMaster : MonoBehaviour
{
public static GameMaster GM;
public GameObject soundManager;
public int score;
void Awake()
{
if(GM != null)
GameObject.Destroy(GM);
else
GM = this;
DontDestroyOnLoad(this);
}
}
The beauty of using the singleton is that it can use the inspector to assign public assets and can still be used anywhere like a static class, even the functions will work from anywhere. We'd call the score for example by using GameMaster.GM.score
Of course there are many other ways to accomplish this, but this is how I like to do it. Hope that helps!
You deserve more thumbs and at least one comment saying this is correct. Oh, and it should be marked as correct, obviously.
I learned this technique in an official Unity Tutorial Video: see this link, video @ 13.30...
so I'm pretty sure this is the right way to go.
I HAVE ONE THING TO ADD: he should make a prefab of that Game$$anonymous$$aster-object.
I also wanted to thank you for your answer and the link to that Youtube channel. I came across this thread looking for help regarding extension methods. It's funny that the youtuber had just created this video two days ago which explains it very well: https://www.youtube.com/watch?v=$$anonymous$$UckjRhEDsQ
Use OnValidate () ins$$anonymous$$d of Awake () if you need the singleton in the editor.
thank you, great explanation, and avoided the "make it look cool and unclear"
Wouldn't it make more sense to reverse the Awake method? Like this:
void Awake()
{
if(GM == null)
GM = this;
else
GameObject.Destroy(this)
}
That way you aren't deleting the exiting GameManager, and only deleting any that try to instantiate afterwards?
If not, thanks for any clarification
Answer by SilentSin · Jul 27, 2014 at 02:03 AM
Yes you can do this, but you need to specify everything as public.
public static class SceneData
{
public static int width = 100;
public static int score;
public static GameObject soundManager;
}
Otherwise they default to private and your class will be useless.
Now you'll be able to use SceneData.width anywhere.
The other answers offer ways of having a class that inherits from MonoBehaviour which you can access from anywhere, but it doesn't look like you actually want any MonoBehaviour functionality, so a simple static class will work better.
Answer by fafase · Sep 26, 2012 at 06:56 AM
The way I do it is that I have a normal variable (I call it temp) that I use in the scene and a static variable (static) that I use for the whole game.
The reason is, if you use the static var for your point and the guy loses, when he starts again, he still has the point from previous run.
You could use temp and if the guy wins the level then
static += temp;
If the guy loses
temp= 0;
Temp is lost when the new level is loaded, static remains. You can attach the static var to your player object. The static var will have a lifetime of the whole game and you can access it anywhere with ClassName.staticVar.
In case you would not know much about static yet, it has been subject for a lot of controversy as beginners tend to think that the easiness of access is a good feature. Beware of that.
http://answers.unity3d.com/questions/318376/static-non-static.html
$$anonymous$$y game is a bit different in that it does not have a player object as such. Could I create a gameObject called StaticData in each scene and attach a static class to that. If I did that would it still have the same values from scene to scene?
The game Object would be a new one but the data would be the same ones. It would be a new object linked to the same data.
@fafase - What about the script thing that dscroggi is suggesting. Have you needed that before?
Answer by dscroggi · Sep 26, 2012 at 07:34 AM
Throw this utility script on any game object and it will not get destroyed when scenes change. Make sure that game object has your static data on it. Btw as far as I'm concerned, static data is faster to access than instanced data, so you're on the right track.
using UnityEngine;
public class KeepOnLoad : MonoBehaviour
{
void Awake () {
DontDestroyOnLoad(this);
}
}
@dscroggi - Can you explain a bit more? It's a method called DontDestroyOnLoad(this)?
when you start a new scene, all objects from the previous scene are destroyed. This function tells to keep the variable when loading a new scene. Could be a solution. $$anonymous$$y issue is that if for some reason the object gets destroyed within the game, you would lose the data. The function keeps on load but I do not know if it preserves from Destroy. http://docs.unity3d.com/Documentation/ScriptReference/Object.DontDestroyOnLoad.html
@dscroggi - Can you show me how the class would look that I would need to hold the static data. All I need to do is to hold one integer for score? Thanks
Answer by Garrom · Mar 26, 2017 at 07:03 PM
just declerate public static class and keep it in asset folder. public static class may look like this
public static class TheStaticClass
{
public static int uselessNumber = 33
}
you can acess uselessNumber from any place in any code by
TheStaticClass.uselessNumber
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Initialising List array for use in a custom Editor 1 Answer
Illuminating a 3D object's edges OnMouseOver (script in c#)? 1 Answer
Flip over an object (smooth transition) 3 Answers