- Home /
Calling CancelInvoke() ?
Hello! I have some prefabs being instantiated and the speed at which they fall increases over time using InvokeRepeating. Calling InvokeRepeating works great but my issue is that I can't get it to stop...even when the game ends and you reload the scene, it picks up where it left off instead of resetting to start off slow and speed up again. I have been trying to use CancelInvoke but with no luck.
Here is my first attempt where I'm trying to use CancelInvoke:
using UnityEngine;
using System.Collections;
public class SpawnBox : MonoBehaviour
{
public GameObject[] boxList;
private bool gameOver;
public GameObject gameOverText;
public GameObject restartButton;
public GameObject menuButton;
void Start()
{
gameOver = false;
StartCoroutine(SpawnNewBox());
Speed();
}
void Speed()
{
InvokeRepeating ("changeGravity", 5.0f, 5.0f);
}
void changeGravity ()
{
Physics2D.gravity += new Vector2 (0, -2);
}
IEnumerator SpawnNewBox()
{
yield return new WaitForSeconds (1.75f);
while (!gameOver)
{
int i = Random.Range (0, boxList.Length);
Instantiate (boxList [i], transform.position, Quaternion.identity);
yield return new WaitForSeconds (Random.Range (2.0f, 3.1f));
}
GameObject.FindGameObjectWithTag("MainCamera").GetComponent<AudioSource>().Stop();
GameObject.FindGameObjectWithTag("Destroyer").GetComponent<AudioSource>().Play();
gameOverText.SetActive(true);
yield return new WaitForSeconds (1.5f);
restartButton.SetActive(true);
menuButton.SetActive (true);
CancelInvoke ();
}
public void GameOver()
{
gameOver = true;
}
}
I wasn't exactly sure if having InvokeRepeating and a Coroutine on the same script was causing an issue so I took out the Invokes and made a separate script here:
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class SpeedUp : MonoBehaviour {
void Start ()
{
InvokeRepeating ("changeGravity", 5.0f, 5.0f);
}
void changeGravity ()
{
Physics2D.gravity += new Vector2 (0, -2);
}
}
I tried putting CancelInvoke(); in an Update function but that did nothing as well.....I've been staring this in the face for awhile and hopefully a fresh pair of eyes can help out. Thank you in Advance!!!
Answer by Addyarb · Jun 30, 2017 at 02:27 AM
Hey there!
While I don't recommend using Physics2D.gravity to make your gameObjects move faster, I do see a potential problem. Physics2D.gravity is a global value, which simply means that it is not reset when you reload a scene. Therefore, you must reset your gravity to zero manually.
I would recommend when calling GameOver(); that you reset your gravity to its default value. I believe it starts at -9.8f, but you can double check that!
P.S. I think that you should look into pooling rather than instantiate/destroy. There are also several issues with your GameObject.Find methods that could stand some optimization - although I totally understand that while quick prototyping, it is much easier to do as you've done. Just let me know if you need any suggestions as how to be more efficient and I will be happy to oblige!
Best,
Addyarb
How would I go about resetting the gravity? I tried calling Physics2D.Gravity in the GameOver() function like so: public void GameOver() { gameOver = true; Physics2D.gravity += new vector2 (0,0); }
but with no luck..
@Addyarb Scratch that...I got it working haha I just needed to take a break and stop staring at it for so long. Here's what I ended up doing and it works exactly like I needed it to:
using UnityEngine;
using System.Collections;
public class SpawnBox : $$anonymous$$onoBehaviour
{
public GameObject[] boxList;
private bool gameOver;
public GameObject gameOverText;
public GameObject restartButton;
public GameObject menuButton;
private Vector2 StartingGravity;
void Start()
{
gameOver = false;
StartCoroutine(SpawnNewBox());
Speed();
}
void Speed()
{
InvokeRepeating ("changeGravity", 5.0f, 5.0f);
}
void changeGravity ()
{
Physics2D.gravity += new Vector2 (0, -2);
}
IEnumerator SpawnNewBox()
{
yield return new WaitForSeconds (1.75f);
StartingGravity = Physics2D.gravity;
while (!gameOver)
{
int i = Random.Range (0, boxList.Length);
Instantiate (boxList [i], transform.position, Quaternion.identity);
yield return new WaitForSeconds (Random.Range (2.6f, 2.75f));
}
GameObject.FindGameObjectWithTag("$$anonymous$$ainCamera").GetComponent<AudioSource>().Stop();
GameObject.FindGameObjectWithTag("Destroyer").GetComponent<AudioSource>().Play();
gameOverText.SetActive(true);
yield return new WaitForSeconds (1.5f);
restartButton.SetActive(true);
menuButton.SetActive (true);
CancelInvoke ();
Physics2D.gravity = StartingGravity;
}
public void GameOver()
{
gameOver = true;
}
}
I would also like to continue chatting with you about possible optimization that you spoke about earlier, you can reach me at dkitch9@gmail.com. Thank you for your help!