How can I add a small delay between things happening in a function, after the delay it should continue with what it was doing? in C#
7 Answers
7you can Invoke a method after a delay like this
Invoke("DoSomething", 2);//this will happen after 2 seconds
"DoSomething" is the name of the function to call. This answer is exactly what I needed, so I upvoted it, even though I know it wasn't the answer the OP was looking for.
– MuskarSame as what @Muskar said – This isn't the answer the OP was looking for, but it's definitely what I was looking for!
– shaneparsonsYou can do it with coroutines in any MonoBehaviour:
IEnumerator ExecuteAfterTime(float time)
{
yield return new WaitForSeconds(time);
// Code to execute after the delay
}
You can call it with, for example, StartCoroutine(ExecuteAfterTime(10));
Note that it will execute asynchronous so put everything that has to wait for it to be done, inside the coroutine.
But, when I call it from the update fuction befor the function before doing this will it not be called multiple times?
– Jan_JuliusCall it somewhere else (like Start function). [Check the tutorial][1]. [1]: http://unity3d.com/learn/tutorials/modules/intermediate/scripting/coroutines
– Andres-FernandezBut what if it's done through there? how can I make it so it will only be executed once?
– Jan_JuliusThe start function only gets called once (at the beginning of the scene). Check the tutorial, try the code. It doesn't hurt.
– Andres-FernandezWhy it has to be so extremely complicated? Why I can't simply write a code like this: position.x = 1; transform.position = position; WaitForSeconds(2); position.x += 1; transform.position = position; I tried to move the sprite twice using StartCoroutine(ExecuteAfterTime(1)); StartCoroutine(ExecuteAfterTime(1)); but it doesn't work. It only moves the sprite once. What do I have to do? Do I have make a new function "AnotherExecuteAfterTime"? Why should the users be puzzled with sophisticated concepts like "Yield" and "Coroutine" when they only want to do a "delay(2)" ?
– zenchipWe can extend this futher by executing an Action after the delay:
IEnumerator ExecuteAfterTime(float time, Action task)
{
if (isCoroutineExecuting)
yield break;
isCoroutineExecuting = true;
yield return new WaitForSeconds(time);
task();
isCoroutineExecuting = false;
}
Then use it like this:
StartCoroutine(ExecuteAfterTime(0.5f, () =>
{
//Add somwthing here
}));
use this class :
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using UnityEngine;
using System;
namespace LateExe {
class Executer
{
object script;
MonoBehaviour mono_script;
public Executer(object script)
{
this.script = script;
this.mono_script = this.script as MonoBehaviour;
}
public InvokeId DelayExecute(float DelayInSeconds, Action<object[]> lambda, params object[] parameters)
{
return new InvokeId( mono_script.StartCoroutine(Delayed(DelayInSeconds, lambda, parameters)));
}
public InvokeId DelayExecute(float DelayInSeconds, string methodName, params object[] parameters)
{
foreach (MethodInfo method in script.GetType().GetMethods())
{
if (method.Name == methodName)
return new InvokeId(mono_script.StartCoroutine(Delayed(DelayInSeconds, method, parameters)));
}
return null;
}
public InvokeId ConditionExecute(Func<bool> condition, string methodName, params object[] parameters)
{
foreach (MethodInfo method in script.GetType().GetMethods())
{
if (method.Name == methodName)
return new InvokeId(mono_script.StartCoroutine(Delayed(condition, method, parameters)));
}
return null;
}
public InvokeId ConditionExecute(Func<bool> condition, Action<object[]> lambda, params object[] parameters)
{
return new InvokeId(mono_script.StartCoroutine(Delayed(condition, lambda, parameters)));
}
public void StopExecute(InvokeId id)
{
mono_script.StopCoroutine(id.coroutine);
}
IEnumerator Delayed(float DelayInSeconds, Action<object[]> lambda, params object[] parameters)
{
yield return new WaitForSeconds(DelayInSeconds);
lambda.Invoke(parameters);
}
IEnumerator Delayed(float DelayInSeconds, MethodInfo method, params object[] parameters)
{
yield return new WaitForSeconds(DelayInSeconds);
method.Invoke(script, parameters);
}
IEnumerator Delayed(Func<bool> condition, Action<object[]> lambda, params object[] parameters)
{
yield return new WaitUntil(condition);
lambda.Invoke(parameters);
}
IEnumerator Delayed(Func<bool> condition, MethodInfo method, params object[] parameters)
{
yield return new WaitUntil(condition);
method.Invoke(script, parameters);
}
}
class InvokeId
{
public readonly Coroutine coroutine;
public InvokeId(Coroutine coroutine)
{
this.coroutine = coroutine;
}
}
}
Examples:
execute after 2 seconds in a few ways
using LateExe;
public class Game_Script: MonoBehaviour {
void Awake {
Executer exe = new Executer(this);
exe.DelayExecute(2f , x=> Debug.Log("after 2 seconds"));
exe.DelayExecute(2f , x=> Debug.log(x[0]) , "after 2 seconds + params");
exe.DelayExecute(2f , "after2seconds");
exe.DelayExecute(2f , "afterXseconds", 2);
exe.DelayExecute(2f , "afterXY", 2, " seconds");
}
void after2seconds ()
{
Debug.Log("after 2 seconds");
}
void afterXseconds(int x) {
Debug.log("after" + x + "seconds");
}
void afterXY(int x , string y) {
Debug.log("after " + x + y);
}
}
Example stop:
var id = exe.DelayExecute(0.5f, x => Debug.Log("not gonna run"));
exe.StopExecute(id);
Example when:
exe.ConditionExecute(() => score > 100 , x => Debug.Log("you're good"));
I know this is old but its a very common thing and I hope unity will one day implement such a class into the engine. creating a coroutine every time is not a clean way of doing things.
I like this answer, but, tiny gripe --- should be Executor -- thanks for this tool btw, just finished implementing and it's very convenient and intuitive
Check Coroutines.
It is exactly what you need.
Invoke() is simpler, but if one wants to call method with parameters, coroutine is apparently a good solution.
If all other comments don’t help you, then use this. Maybe it’s not good to write like that…But I don’t care ![]()
void AddSomePassive()
{
counter++;
if (counter == 10)
{
ItemsUpdate();
count = count + dps;
counttmp = count;
}
else if (counter > 10) counter = 0;
}
Check this. That was a clue for me ![]()
it's just Invoke. that's all there is to it. there's also InvokeRepeating if you want it to happen over and over. it's absurd to dabble with coroutines for something so simple.
– Fattie