Workaround for using invoke for methods with parameters

private void fooMethod(bool foo = false)
{
Debug.Log(foo);
}

This is the code and the notification I get is

Trying to Invoke method:
BlackScreenManager.a couldn’t be
called.

So I understand invoke can’t be used with methods with parameters. But I also set a default value false if the method is being called without any parameters given. So question: How can I workaround this without creating additional methods which just call the method with the parameter?

Since you can not call Invoke with parameters you can use StartCoroutine for this.

Say your code is:

void Start()
{
    Invoke("MyFunction", 1f);
}

void MyFunction()
{
    // Do your thing.
}

Instead you can use Coroutine by passing argument like:

void Start()
{
    StartCoroutine(MyFunction(false, 1f));
}

IEnumerator MyFunction(bool status, float delayTime)
{
    yield return new WaitForSeconds(delayTime);
    // Now do your thing here
}

One other option, for the sake of completeness, could be using global variables instead of method parameters. You can set those accordingly, then invoke a method that makes use of them… depending on your needs and context, this could be feasible or not, but either way it cannot hurt to be aware of the option.

public class Foo : MonoBehaviour {

    private int x;

    void Start () {
        x = Random.Range(0, 100);
        Invoke("FooBar", 5.0f);
    }

    private void FooBar () {
        if (x == 0) {
            return;
        }

        for (int i = 0; i < x; i++) {
            Debug.Log(i);
        }
    }
}

Creating extension methods is also an option.

namespace UnityEngine
{
    public static class MonoBehaviourExtension
    {
        public static Coroutine StartCoroutine(this MonoBehaviour behaviour, System.Action action, float delay)
        {
            return behaviour.StartCoroutine(WaitAndDo(delay, action));
        }

    private static IEnumerator WaitAndDo(float time, System.Action action)
    {
        yield return new WaitForSeconds(time);
        action();
    }
}
}

You can call it like this.

this.StartCoroutine(() =>
                {
                    other.gameObject.SetActive(false);
                }, this.delay);

HarshadK Answers will work fine . However In case you don’t want to use the Coroutine then Here it is:

Say like:
You want to call the myFoo(int a); through Invoke you can do this by taking another method invoking it and then call your function inside that method.
e.g


Start() 
 {  
 Invoke("DemoFun");
 }
 
private void DemoFun() 
{  
  MyFoo(int a);//Your function that you like to call
 }

@MapuHoB we had this problem too.

To solve it we made an asset that can help you delay method with parameters in one line of code.

It’s called Super Invoke, it’s like a more powerful Invoke.

Using Super Invoke your code would be:

float delay = 1f;
SuperInvoke.Run( ()=> fooMethod(true), delay);

You can also create sequences with method and delays that can help you implement complex situations in a simple and fast way.

You can use a coroutine to WaitForSeconds, then delegates to pass arbitrary parameters to it. I use this in a static Utils class, but you could also wrap it as an extension method to insert it right into MonoBehavior.

	/// <summary>
	/// Like MonoBehavior.Invoke("FunctionName", 2f); but can include params. Usage:
	/// Utils.RunLater( ()=> FunctionName(true, Vector.one, "or whatever parameters you want"), 2f);
	/// </summary>
	public static void RunLater(System.Action method, float waitSeconds) {
		if (waitSeconds < 0 || method == null) {
			return;
		}
		[SOME_MONOBEHAVIOR].StartCoroutine(RunLaterCoroutine(method, waitSeconds));
	}
	public static IEnumerator RunLaterCoroutine(System.Action method, float waitSeconds) {
		yield return new WaitForSeconds(waitSeconds);
		method();
	}

So my solution to this is… stop suffering fighting with delegates parameters and use lambdas!

	//Call
	StartCoroutine(SuperInvokeCoroutine
		(
			()=>{
				//Whatever I want to invoke or do goes here!
				Debug.Log("Great!");
			}, 
			3f	//Seconds
		)
	);

	IEnumerator SuperInvokeCoroutine (System.Action myFunction, float seconds) {
		yield return new WaitForSeconds(seconds);

		myFunction();
	}

@sarahnorthway , @MapuHoB

/// SetTimeOut(()=>{    int i=0;	}, 1000);// 1000 = 1 sec
public void SetTimeOut(Action FUNC, int msec){StartCoroutine(RUN_AFTER(FUNC, msec/1000.0f));}
public IEnumerator RUN_AFTER(Action FUNC, float sec) {yield return new WaitForSeconds(sec); FUNC();}

easily you can make another method that calls method with parameter. and you can invoke caller method


Invoke (“CallMyMethod”, 1f);

void CallMyMethod()
{
MyMethodWithParams(10f, 5f, “lots of diffetrent params”);
}