0

In my project I'm implementing an action class and was wondering if it was possible to pass a function as a parameter like this:

public class Action : MonoBehavior {
  public int ID;
  public string Name;
  //Test variable to store a function here
}

Where later I would create a function, such as this one, and call it.

void TestFunction() {
  print("Test");
}
public Action ExampleAction;
ExampleAction.Test = TestFunction();

And then finally I could simply call "Action.Test" to run TestFunction.

I've done some research on the topic and I believe it's somewhat related to delegation but how could I do it in this scenario?

And even more, is this sort of implementation reliable or the nicest way to do it? In my project I plan on having a lot of toggleable actions, that when clicked, will continuously do a large variety of different things.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
Carcanken
  • 91
  • 6
  • 1
    You can store delegates. Define the function signature and then you can just directly assign it. Then calling it can be done by referencing the stored delegate. `public void YourDelegate(parameters);`. Then save a reference of it `private YourDelegate = null`. Then assign it with a function of the same signature (scope, return type and parameters). – TEEBQNE Sep 23 '21 at 17:48
  • 1
    In your case it would simply be [`public System.Action Test;`](https://learn.microsoft.com/dotnet/api/system.action) – derHugo Sep 23 '21 at 18:32
  • Also related btw [Pass method as parameter using c#](https://stackoverflow.com/questions/2082615/pass-method-as-parameter-using-c-sharp) -> between "pass" and "store" there is little difference ;) – derHugo Sep 24 '21 at 04:31

1 Answers1

1

To my understanding, what you are trying to do is create a parameterized delegate.

I think UnityAction fit this perfectly. UnityAction is a built-in delegate that takes no parameters and returns no value.

In your case, you would want to use a parameterized UnityAction<T1, T2>, where you would set T1 to int and T2 to string.

Here is a snippet for demonstration:

using UnityEngine;
using UnityEngine.Events;

public class UnityActionDemo
{
    UnityAction<int, string> action;
    private void Start()
    {
        action = TestMethod;
    }

    public void TestMethod(int id, string name)
    {
        Debug.Log("id is: " + id + "\t name is: " + name);
    }
}

action can then be passed around to any method that takes a UnityAction<int, string> as a parameter.

In order to invoke the method, call action.Invoke with the parameters you'd like to use:

action.Invoke(27, "A cool method name");

:)

Guy Michael
  • 134
  • 10
  • 1
    Never understood the purpose of `UnityAction` to be honest ... There already is `System.Action` which does exactly the same ... So either it does some additional stuff or is pretty much redundant – derHugo Sep 24 '21 at 04:28
  • I'm not sure about it myself. Maybe the internal implementations are more optimized to how Unity works? Just shooting in the dark. – Guy Michael Sep 28 '21 at 11:31