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 :)
Answer by UniqueMAX · Jan 11, 2016 at 05:19 PM
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 =)
Answer by JacobGames · Feb 17, 2016 at 05:13 PM
@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.
Answer by kayb14 · Jun 21, 2016 at 07:46 AM
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!
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"}
I'm afraid this is not a good solution.
Checking every frame on Update() just to call a delayed function after 5 seconds? Why would anyone ever want to do that?
You can just call your delayed function straight away
Check file TimedObjectDestructor.cs in the official Unity Standard Assets in the Utility package.
Your answer
![](https://koobas.hobune.stream/wayback/20220612055603im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Recursive Functions with Delay 0 Answers
Unity2D I wanna use a delay time on Entering an Trigger. 0 Answers
Make my moving platforms pause at its endpoints using c# 2 Answers
How can i change the value of a variable from an IEnumerator 0 Answers
Are Coroutines the best way to delay ? If not, what is ? C# 2 Answers