- Home /
Accessing variables on a script on a DontDestroyOnLoad GameObject
Hi all,
So I have a GameObject on my first scene that I keep for all of my other scenes using DontDestroyOnLoad. That GameObject has a script on it with a variable that I need to read/write. Every time I load my levelselect scene, I need to read that variable to check which levels have been unlocked, and assign that value to another script's variable I have read through multiple posts and problems that other users are having, such as:
http://answers.unity3d.com/questions/512966/how-to-access-gameobject-variable-script.html
http://answers.unity3d.com/questions/295996/unable-to-modify-a-variable-in-another-script.html
http://answers.unity3d.com/questions/42843/referencing-non-static-variables-from-another-scri.html
but I can't seem to be able to find a solution. Here are my scripts:
LevelController on my DontDestroyOnLoad GameObject named LevelTracker
#pragma strict
public var unlocked : int = 1;
function Awake ()
{
DontDestroyOnLoad (transform.gameObject);
}
UnlockedController which is the script that needs to access the variable
#pragma strict
var gameobject : GameObject;
var scriptComponent : Component;
var unlocked : int;
function Start ()
{
gameobject = GameObject.Find("LevelTracker");
scriptComponent = gameobject.GetComponent.<LevelController>();
unlocked = scriptComponent.Unlocked;
}
What happens is that i get an error saying 'Unlocked' is not a member of UnityEngine.Component on
unlocked = scriptComponent.Unlocked;
Any idea how to fix this? Anybody ever done something like this?
Thanks :)
Answer by Addyarb · Sep 27, 2015 at 10:45 PM
Make it a public static script, and then be sure and apply the singleton approach (if that's what you're going for) by putting in a function that looks something like this:
(Warning, C# not JS - but should be easily translatable)
public class GameManager : MonoBehaviour {
public static GameManager GM;
void Awake () {
MakeThisTheOnlyGameManager ();
}
void MakeThisTheOnlyGameManager(){
if(GM == null){
DontDestroyOnLoad(gameObject);
GM = this;
}
else{
if(GM != this){
Destroy (gameObject);
}
}
}
That should let you access the script from anywhere in any scene just by typing (in this instance) GameManager.GM.(your variable here).
Thanks for your reply!
First off, I have my project set up where the DontDestroyOnLoad GameObject is in the very first scene, and once I leave that scene I never go back. Do I still need to use the Singleton approach for this? Because in the hierarchy it only shows one instance of the GameObject in the other scenes.
Also, I changed the variable to a public static, and still get the error. Not sure where to go from here :(
A singleton is not required, but the static reference is a valid way to access manager type objects.
I have added some debug logging and found that the GameObject and the script are being found, but it just can't find the Variable on the script.
Could you please post your code as far as what you've modified? You don't necessarily have to use the singleton approach - however I assumed since your GameObject's name was "LevelTracker" that you'd be needing to get back to it eventually. If that's not the case, you can go about this a few different ways. Both of them will include serialization.
PlayerPrefs : If you haven't heard of this - it's a pretty simple concept. You can save data on the harddrive of the device you are running the game on (be it mobile or PC) and go back and access it any time you want. It will persist after the player closes the game. The syntax is really easy too. To save a variable, you would type: (in JS and C#):
PlayerPrefs.SetInt("Player Score", 10);
In this reference - you would create a whole new variable called "Player Score" and set it to 10. You can later alter this variable by writing over it. For instance:
PlayerPrefs.SetInt("Player Score", 11);
That doesn't make it so you have two "Player Score" variables, it just changes your current variable to a different value.
There is a big disadvantage here, in that the player him/herself can access this fairly easily and edit it to their whim. For multiplayer rankings, scores, and stats - this creates an easy way for players to cheat currency and scores with no consequences since you can't validate it. However, if this is just a PC game that has no multiplayer - it's your call as to whether security is worth it.
Database integration.
This will be more than I can explain here, but essentially it will include using PHP/X$$anonymous$$L/Some variation of SQL to store information on an online server and then interfacing with it to trade information.
So with PlayerPrefs, is the variable accessible from anywhere? That would be perfect. Also, would I need my GameObejct that is not destroyed anymore?
I have heard of this approach before, I just wasn't sure if it would be the best method. But since my game is not going to be multiplayer, I will try this. I'll let you know how it goes.
This works perfectly! After a little playing around (and Google), I figured out how to work them. It is ideal for my project. Thank you!
@Hotsaucehater I'm really glad this worked for you! I use PlayerPrefs to store usernames, audio settings, preferred UI layouts, etc. However, if you're going for more of a database approach - I would highly recommend you get a visual representation of the PlayerPrefs rather than remembering them all and having to Debug.Log their values.
Additionally - it's a good idea to encrypt your PlayerPrefs so it doesn't make them that easy to read/write if you're a player.
Here is a good free asset to encrypt.
I myself use this asset, but it's $10. You can probably find a cheaper one - but the code for this one seems well written and - well - I got it 50% off on a 24 hour sale :) You can also spend some time learning editor scripting if you'd like to represent them in-editor yourself - that's just at the bottom of my list.
Anyway, feel free to message me if you have any problems. Always happy to help.
Answer by Arycama · Sep 28, 2015 at 06:24 AM
Check your capitalisation. In your second script (line 11) you're writing unlocked with a capital U, which is different to the name you gave your variable which only had a lower-case 'u'.
Punctuation is very important when programming!
Answer by Kiwasi · Sep 28, 2015 at 01:04 AM
You need to type your ScriptComponent as a LevelTracker. And fix the variable capitalisation. This should work for you.
#pragma strict
var gameobject : GameObject;
var scriptComponet : LevelTracker;
var unlocked : int;
function Start ()
{
gameobject = GameObject.Find("LevelTracker");
scriptComponet = gameobject.GetComponent.<LevelController>();
unlocked = scriptComponet.unlocked;
}
As an aside you should also use descriptive names. scriptComponent is not very helpful to read, consider calling it levelController ins$$anonymous$$d. And so forth.
I can't set my scriptComponent variable as a LevelTracker, as this is not C#
Yes you can. The exact details of doing this vary. But JS runs on the same framework as C#, and for all intents and purposes is the same language. Pretty much everything that can be done in C# can be done in JS once you find the right syntax.
Your answer

Follow this Question
Related Questions
how to pass boolean variable into another scene without destroy it properties 1 Answer
Help! Can't not access the variable linearVelocity of TwistPublisher.cs from another script in Unity 1 Answer
Cant access variable with GetComponent<>(); 1 Answer
Help with my code?(NullReferenceException)[CLOSED] 2 Answers
Instantianig a teleporter prefabs with destination variables 1 Answer