- Home /
If Statement Not Preventing Function Call
Hey everyone,
Here's some code I have to check if my player touches a kill box with this script on it. When the player enters the trigger it should call the GameOver() function. It does, however I only ever want this to happen once! I keep getting the problem that its calling GameOver() multiple times despite my boolean in place which is meant to prevent this. What am i doing wrong?
using UnityEngine;
using System.Collections;
public class Remover : MonoBehaviour {
public GameObject player;
public GameObject mainCamera;
public CameraShake shake;
public Spawner spawner;
public GameObject gameoverText;
public GameObject restartButton;
public PlayerControl playerCont;
private CameraFollow camFollow;
private Vector3 camPos;
public bool over = false;
//===================================================================================================================
void Start (){
camFollow = mainCamera.GetComponent<CameraFollow>();
}
//===================================================================================================================
void FixedUpdate (){
print ("over = " + over);
}
//===================================================================================================================
void OnTriggerEnter2D(Collider2D col){
if (col.gameObject.tag == "piece") {
Destroy (col.transform);
}
if (col.gameObject == player && !over) {
GameOver();
over = true;
}
}
//===================================================================================================================
void GameOver(){
if (!over) {
over = true;
camFollow.StopFollowing ();
playerCont.DisableControl();
spawner.stopSpawning();
var gameOverPosX = mainCamera.transform.position.x;
var gameOverPosY = mainCamera.transform.position.y + 1.5f;
var gameOverPos = new Vector3 (gameOverPosX, gameOverPosY, 1);
var btnPosX = mainCamera.transform.position.x;
var btnPosY = mainCamera.transform.position.y;
var btnPos = new Vector3 (btnPosX, btnPosY, 1);
var camRot = mainCamera.transform.rotation;
CameraFade.StartAlphaFade (Color.white, false, 0.1f, 0f);
CameraFade.StartAlphaFade (Color.white, true, 0.1f, 0f);
Instantiate (gameoverText, gameOverPos, camRot);
Instantiate (restartButton, btnPos, camRot);
shake.DoShake ();
}
}
}
//===================================================================================================================
I see nothing obvious causing your problems:
'over' is public. Does any other component try to access it? If so, look for a bad equality test.
Any chance you unintentionally have this component attached more than once?
Answer by Kumo-Kairo · May 01, 2014 at 06:33 AM
It seems that you can possibly have several Removers, which of them can call their "copy" of GameOver(). Every remover object has it's own over param, so it won't save you from running GameOver() two or more times. (You can even have multiple Remover components on the same object)
The easiest solution will be to make your over field static, so every Remover will share the same variable. Some people might say that static variables are bad, sou you can use another solution - centralized game controller. There will be only one game controller on your scene, so you will have only one over variable. Your Removers will call some TryGameOver() method of your game controller (you can automatically find your game controller on the scene at the start of the game). So multiply method calls will rely on one variable, and it won't be possible to call GameOver() more than once. But of course, you still can stick with a static variable, it will also work
You guys are absolutely right! I do have multiple removers and it just looks like in some situations my player object was able to touch multiple ones.
$$anonymous$$y solution was to just destroy all the object to prevent any overlap. Though i hear destroying is pretty inefficient, are static variables better? Would you just declare the variable like:
static bool over = false;
What are the disadvantages of doing things this way? The centralized game controller looks like a fair solution as well. Thanks for the help!
Though i hear destroying is pretty inefficient, are static variables better?
Static variables are definitely better, removing only happens after the end of the frame, you can't be sure that your player won't touch any other remover
What are the disadvantages of doing things this way?
The only disadvantage is that your code readability suffers a bit, some programmers just don't like to use static variables in such cases. But anyway, if it's too hard for you to make a game controller, feel free to use static variables, private static bool over = false; But access it via Remover.over = true, not just over = true, so it will be more clear that your variable is static
If you find my answer helpful - please mark it as accepted