- Home /
Access a Variable of an Object from a previous Scene
So I'm making a game and what I'd like to do is as follows: If you've collected all the items, you are being forwarded to an end screen, in which your total score is shown. However there is a problem. Since the variable score (which is used to keep track of the score) is part of an object in my game scene, I can't acces the score variable in my end_screen scene.
Player Object code: enter code hereusing UnityEngine; using UnityEngine.UI; using System.Collections;
public class PacMan_Controller : MonoBehaviour {
public float speed;
public float gravity = 20.0f;
public bool play = false;
public int score;
private Vector3 moveDirection = Vector3.zero;
private int count;
private int totalPickupCount;
public Text scoreText;
// Use this for initialization
void Start ()
{
DontDestroyOnLoad (transform.gameObject);
count = 0;
score = 0;
totalPickupCount = GameObject.FindGameObjectsWithTag ("PickUp").Length;
GetComponent<MeshRenderer> ().enabled = false;
}
// Update is called once per frame
void FixedUpdate ()
{
if (play)
{
float moveH = Input.GetAxis ("Horizontal");
float moveV = Input.GetAxis ("Vertical");
//Vector3 movement = new Vector3 (moveH, 0.0f, moveV);
//rigidbody.AddForce (movement * speed * Time.deltaTime);
CharacterController controller = GetComponent<CharacterController>();
if (controller.isGrounded) {
//transform.Rotate(0, moveH, 0);
moveDirection = new Vector3(moveH, 0, moveV);
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
}
moveDirection.y -= gravity * Time.deltaTime;
controller.Move (moveDirection * Time.deltaTime);
}
}
void OnTriggerEnter(Collider other)
{
if (play)
{
if (other.gameObject.tag == "PickUp")
{
other.gameObject.SetActive(false);
count = count + 1;
score = score + 10;
scoreText.text = "Score: " + score;
if (count >= totalPickupCount)
{
play = false;
Application.LoadLevel("Score");
}
}
}
}
}
My End_screen code (Which i'm trying to make it work):
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class End_Screen : MonoBehaviour {
public Text endText;
// Use this for initialization
void Start ()
{
endText.gameObject.SetActive (true);
int total = GameObject.Find("PacMan").GetComponent<PacMan_Controller>().score;
endText.text = "Total Score: " + total;
}
// Update is called once per frame
void Update () {
}
}
I've tried the DontDestroyOnLoad() function, but I prefer not to do this. Also, it doesn't even work with this function :P
The error message I receive is: "NullReferenceException: Object reference not set to an instance of an object".
I hope you can help me with this!
If you would prefer not to use DontDestroyOnLoad(), then you are going to have to come up with some other mechanism to save that information between scenes. PlayerPrefs would work.
What exactly is PlayerPrefs, if I may ask? (almost bedtime and stuf :()
Answer by Chris_Dlala · Oct 05, 2014 at 08:57 PM
Hi, in your example all you want is the score from the game? If that's the case then maybe something like PlayerPrefs (as suggested by @robertbu) could work. However, I would use DontDestroyOnLoad
for a manager class or have a static variable to store the score.
In your example, does the gamObject called "PacMan" exist in the hierarchy in the second scene? I think that gameObjects will still be destroyed if their parent is destroyed. To fix this you could set PacMan object's transform parent to null at the end of the game before changing scenes.
As another alternative:
public class PacMan_Controller : MonoBehaviour
{
// Global variable accessible from anywhere - only one
public static int EndScore = 0;
// Object member variable - each component object has one
public int Score = 0;
// Stores the current objects score in the static score
public void StoreEndScore()
{
EndScore = Score;
}
// all your code below...
}
In the above example (not tested), the EndScore
should be able to be accessed from anywhere using the call PacMan_Controller.EndScore
. And, calling StoreEndScore will populate the static saved score (only stored at runtime not persistent), shown below:
PacMan_Controller myPacMan = GameObject.Find("PacMan").GetComponent<PacMan_Controller>();
myPacMan.StoreEndScore();
I hope that helps =)
I might try that out. Thanks for helping me out. I've tried to save the score in an empty object, and then use DontDestroyOnLoad on that empty object. Do you think this will work just as fine?
I've tried your last option. How do I acces the variable EndScore after StoreEndScore()? Because I can't access it with GameObject.Find("Pac$$anonymous$$an).GetComponent().EndScore. I really need EndScore to display it on the GUIText.
Ah, so EndScore is not on a component or object, it is global. So you use: Pac$$anonymous$$an_Controller.EndScore
to access it.
Oh, stupid of me :( Thanks a lot, this solved it. I will approve your answer as the answer on my question. Thanks a lot!
Answer by alap soni · Oct 07, 2014 at 08:53 AM
My suggestion would be to make the class singleton. This will maintain one instance of the class and all variables will persist the values for single session of game .
Answer by Kiwasi · Oct 07, 2014 at 09:12 AM
Check out the saving and persistence tutorial.
Choose the method that works for you. In order from simplest to most powerful
Static
Singleton
Playerprefs
Sterilization to file
Web server (I don't think the video covers this option)
You probably want a static variable or a singleton. The others are probably overkill.
Thanks for answering. I initially tried it with a Static variable (Chris_Diala proposed this) but there was an error, so I decided against it. He fixed the error, so I indeed use a static variable. Thanks for your thorough answer though! :)