How to delay a function?

I am making a Pong clone right now and I’m making the score ATM. What’s supposed to happen is when the ball hits the left or right wall, it gives the player a point (just like the real game).

I want a delay before I reset the level but I can’t figure out how to do it. I’m using 2 scripts, here’s the first:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class GameManager : MonoBehaviour {

public Text rScore;
public Text lScore;
public Text roundWinner;

public GameObject ball;
public GameObject ballSpawn;

public int countR;
public int countL;

void Start () 
{
	countR = 0;
	countL = 0;
	roundWinner.text = "";
	SetCountText ();
	Reset ();
}

public void SetCountText()
{
	rScore.text = "" + countR.ToString ();
	lScore.text = "" + countL.ToString ();
}

public void Reset()
{
	Instantiate (ball, ballSpawn.transform.position, Quaternion.identity);
	roundWinner.text = "";
}

}

Here’s the second:

using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {
public float speed = 30;

public GameManager gm;

void Start () 
{
	GetComponent<Rigidbody2D> ().velocity = Vector2.right * speed;
	gm = GameObject.Find ("GM").GetComponent<GameManager> ();
}

void OnCollisionEnter2D (Collision2D col)
{
	if(col.gameObject.name == "RacketLeft")
	{
		float y = hitFactor(transform.position, col.transform.position, col.collider.bounds.size.y);

		Vector2 dir = new Vector2 (1, y).normalized;

		GetComponent<Rigidbody2D>().velocity = dir * speed;
	}

	if (col.gameObject.name == "RacketRight") 
	{
		float y = hitFactor(transform.position, col.transform.position, col.collider.bounds.size.y);

		Vector2 dir = new Vector2 (-1, y).normalized;
		
		GetComponent<Rigidbody2D>().velocity = dir * speed;
	}
}

float hitFactor(Vector2 ballPos, Vector2 racketPos, float racketHeight)
{
	return(ballPos.y - racketPos.y) / racketHeight;
}

void OnTriggerEnter2D (Collider2D other)
{
	if(other.gameObject.CompareTag("WallR"))
	{
		gm.roundWinner.text = "Round Winner: Left";
		gm.countL += 1;
		gm.SetCountText();
		Destroy(gameObject, 1);
		//I want to call the Reset function here
	}

	if(other.gameObject.CompareTag("WallL"))
	{
		gm.roundWinner.text = "Round Winner: Right";
		gm.countR += 1;
		gm.SetCountText();
		Destroy(gameObject, 1);
		//I want to call the Reset function here
	}
}

}

Thanks in advance :slight_smile:

Use Coroutine. (add it anywhere like another void)

IEnumerator Reset(float Count){
yield return new WaitForSeconds(Count); //Count is the amount of time in seconds that you want to wait.
//And here goes your method of resetting the game...
yield return null;
}

Add a public variable that would allow you to modify the time it takes before resetting the game without editing script.

public float WaitTime=1.0f;

And finally, add this to places where you want to call the Reset function

StartCoroutine("Reset", WaitTime);

I hope it helps, I think it’s a nice and simple way of doing it =)

@SquirrelCoder there’s a recently released asset that can help you delay anything in one line of cod. No need to use multiple lines of code as with coroutines.

It’s called Super Invoke, it’s like a more powerful version of the standard Invoke function of MonoBehavior.

You can also create sequences with methods and delays which will actually be useful in your case.

Your code using Super Invoke would be:

if(other.gameObject.CompareTag("WallL"))
 {
     gm.roundWinner.text = "Round Winner: Right";
     gm.countR += 1;
     gm.SetCountText();
     
     SuperInvoke.CreateSequence()
                .AddMethod( ()=> Destroy(gameObject), 1)
                .AddMethod( ()=> gm.Reset())
                .Run();
 }

The Reset function will be called after Destroy.

I am tired of coding delay functions everywhere I need to!

So I wrote a solution to delay ANYTHING!!!

If you have some space in your performance, because it’s very dirty!

  1. create a cube outside of the map/player sight and remove its mesh-renderer and collider!
    should work with an empty object as well…

public GameObject timedelay;
D&D the aforementioned cube in here

2 . Create a "destroy "script that destroys that cube after a delay (in this case 5seconds)

bool destroyed = false;

public void DestroyObject ()
{destroyed=true;}

update()
{
if(destroyed==true)
{Destroy(gameObject,5);}
}

3 . run the script where you want to put the reset

if ("YOURCONDITIONS"&&timedelay!=null){timedelay.transform.GetComponent<destroy>(DestroyObject)}

4 . Check if the cube is destroyed & trigger RESET()

 else if ("YOURCONDITIONS"&&timedelay == null){"TRIGGER-RESET-FUNCTION"}