- Home /
Passing a bool between scripts
I am trying to cancel invoke using a bool from another script. My first scripts called Player which is where is set the bool. The second script called generate is:
using UnityEngine;
using System.Collections;
public class Generate : MonoBehaviour
{
public GameObject rocks;
public GameObject bullets;
public AudioClip beepSound;
int newScore = -3;
public Player script;
void Start()
{
script = GetComponent <Player>();
//In this script, we use the InvokeRepeating method. This will call a specific function once every several seconds.
//The first parameter "Createobstacle" is a string with the name of the method to call. The second is the number of seconds to delay
//these repeated calls. And the third parameter is the number of seconds between method calls.
InvokeRepeating("CreateObstacle", 1f, 1.5f);
InvokeRepeating("CreateBullet", 5f, 1.1f);
}
// Update is called once per frame
void OnGUI ()
{
if (newScore < 1)
{
GUI.color = Color.black;
GUILayout.Label (" Score: 0 " );
}
else
{
GUI.color = Color.black;
GUILayout.Label (" Score: " + newScore.ToString ());
}
int oldHighscore = PlayerPrefs.GetInt ("newHighscore", 0);
if (newScore > oldHighscore)
{
GUI.color = Color.black;
GUILayout.Label (" High Score: " + newScore.ToString ());
}
else
{
GUI.color = Color.black;
GUILayout.Label (" High Score: " + PlayerPrefs.GetInt("newHighscore").ToString ());
}
//PlayerPrefs.DeleteAll ();
}
void Update()
{
int oldHighscore = PlayerPrefs.GetInt ("newHighscore", 0);
if (newScore > oldHighscore)
PlayerPrefs.SetInt ("newHighscore", newScore);
PlayerPrefs.Save ();
if (Input.GetKey("escape"))
Application.Quit();
**if (script.gameOver)
CancelInvoke();**
}
void CreateObstacle()
{
Instantiate(rocks);
newScore ++;
if (newScore > 0)
audio.PlayOneShot (beepSound);
}
void CreateBullet()
{
Instantiate (bullets);
}
}
I am getting a null reference exception: Object reference not set to an instance of an object Generate.Update () (at Assets/Scripts/Generate.cs:64
This is my first project in Unity and in c#. The end result is that I am trying to stop the game and post the high score and give player the choice to restart the game. I figure if I can stop the invoke repeating and destroy the player it will appear like the game has stopped.
Answer by robertbu · Aug 03, 2014 at 10:30 PM
I suspect that the Player script and this script are on different game objects. My guess is that you want something like this for line 15:
script = GameObject.Find("Player").GetComponent <Player>();
Substitute for 'Player' name of the game object with the 'Player' component. Note since you are assigning 'script' in Start(), you might as well make it private rather than public.
Answer by Splatakus · Aug 08, 2014 at 03:47 PM
Finally scratched out some time to get back to this. I really appreciate your answer. It still does not stop the invoke repeating command. i.e the game over text comes up but the two objects, a rock and a bullet, keep scrolling across the game screen. What I am trying to do is stop the game and show the game over text but only the game over text appears. What I thought I could do was share the state of the bool "gameOver" which is called out in my Player script to my Generate scripts which spawns the rock and the bullet and have it stop spawning. Can I do that?
In your suggestion I can't find or use my lower case "player" game object. It does not let use the lower case "player" game object. It says "Expression donates a 'type', where a 'variable', 'value' or 'method' was expected.
Let me try to describe the problem a little more. I have two scripts.
1) One script is called Player. The Player script code is listed below. In the Inspector when I select the player script it says Player - None(GameObject)on the top - see attached.![alt text][1] However I have a player game object called player which uses a 2D sprite of a plane and assigned to the player script i.e. that sprite which I think is the game object has a component called "Player" script. I am new to this so I don't understand if the Player script is using a game object called player. It seems like it should be in the attachment below it says game object none. ![alt text][1]
Is this code in my Generate Script correct?
if (script.gameOver) CancelInvoke();
Is this code in my Generate Script correct?
public Player script;
void Start() { script = GetComponent ();
InvokeRepeating("CreateObstacle", 1f, 1.5f);
InvokeRepeating("CreateBullet", 5f, 1.1f);
}
The complete Generate Script is using UnityEngine; using System.Collections;
public class Generate : MonoBehaviour { public GameObject rocks; public GameObject bullets; public AudioClip beepSound; int newScore = -3; public Player script;
// Use this for initialization. The Start method runs once, when the GameObject is created.
void Start()
{
script = GetComponent <Player>();
//In this script, we use the InvokeRepeating method. This will call a specific function once every several seconds.
//The first parameter "Createobstacle" is a string with the name of the method to call. The second is the number of seconds to delay
//these repeated calls. And the third parameter is the number of seconds between method calls.
InvokeRepeating("CreateObstacle", 1f, 1.5f);
InvokeRepeating("CreateBullet", 5f, 1.1f);
}
// Update is called once per frame
void OnGUI ()
{
if (newScore < 1)
{
GUI.color = Color.black;
GUILayout.Label (" Score: 0 " );
}
else
{
GUI.color = Color.black;
GUILayout.Label (" Score: " + newScore.ToString ());
}
int oldHighscore = PlayerPrefs.GetInt ("newHighscore", 0);
if (newScore > oldHighscore)
{
GUI.color = Color.black;
GUILayout.Label (" High Score: " + newScore.ToString ());
}
else
{
GUI.color = Color.black;
GUILayout.Label (" High Score: " + PlayerPrefs.GetInt("newHighscore").ToString ());
}
//PlayerPrefs.DeleteAll ();
}
void Update()
{
int oldHighscore = PlayerPrefs.GetInt ("newHighscore", 0);
if (newScore > oldHighscore)
PlayerPrefs.SetInt ("newHighscore", newScore);
PlayerPrefs.Save ();
if (Input.GetKey("escape"))
Application.Quit();
if (script.gameOver)
CancelInvoke();
}
void CreateObstacle()
{
Instantiate(rocks);
newScore ++;
if (newScore > 0)
audio.PlayOneShot (beepSound);
}
void CreateBullet()
{
Instantiate (bullets);
}
}
Any help is most appreciated.
Line 4 should be:
script = GameObject.Find("player").GetComponent <Player>();
Note the quotes are necessary. Alternately you could use the code I originally posted, and change the name of the game object to 'Player'.
And since you are assigning the value in Start, you should declare 'script' as private:
private Player script;
There is nothing wrong with what you are attempting to do. You just need to get the recipe right. People often think about 'getting a variable in another script'. When in fact what you want to do is 'get a variable in a particular instance of a script attached to some specific game object. So it is a two step process. First find the game object, then get the component. So this:
GameObject.Find("player")
...finds a specific game object. The string must match exactly including case.
and then this:
.GetComponent <Player>();
...finds the Player script on the found game object. If you don't specify a game object (i.e. use it like you originally had it), it finds it on the current game object.
Your answer