How can I make a System.Action List that takes Methods with parameters?
So I have:
public List <System.Action> unitQueue = new List<System.Action>();
It functions how it's supposed to, It takes methods and has the script perform the methods given in the list. There's one thing I want to do, but I'm not sure how to do it, and it's to have these methods take parameters.
For example, I've tried: unitQueue.Add(ExampleTask(SelectedGameObject));
but errors come up.
Those errors are: Argument "#1" cannot convert "void" expression to type "System.Action"
and The best overloaded method match for "System.Collections.Generic.List<System.Action>.Add(System.Action)" has some invalid arguments
I'm not sure what do to here. Any help?
Answer by Stratosome · Jul 15, 2018 at 03:17 AM
Hola,
So, System.Action is a delegate. In my words, I'd say it is like declaring a variable data type for some type of function you want. Personally, I would avoid using System.Action because it seems a bit more vague and would instead create my own delegates. Alright, so here's how you could use delegates:
// A declared delegate with two string params
public delegate void MyDelegate(string str1, string str2);
public List<MyDelegate> someList = new List<MyDelegate>();
void Start() {
// --- ADDING FUNCTIONS TO THE LIST
someList.Add(Function1); // (Add existing function)
someList.Add((string s1, string s2) => { // (Add inline function)
Debug.Log("Function2: " + s1 + " " + s2);
});
// --- CALLING THE FUNCTIONS IN THE LIST
for (int i = 0; i < someList.Count; i++) {
MyDelegate d = someList[i];
// You pass in the parameters HERE (only when you call the function itself)
d("Hello", "World");
// Or you could do this:
// someList[i]("Hello", "World");
}
}
private void Function1(string s1, string s2) {
Debug.Log("Function1: " + s1 + " " + s2);
}
This code is going to add two different functions to your delegate list.
Unfortunately, you can't pass in the parameters EXACTLY like you were wanting to, but there are ways to kind of do it. Parameters can only be passed to it when the function is actually called. What you could do, is store those parameters that you want into a little struct or something and add it to the list instead. It could look like:
// A declared delegate with two string params
public delegate void MyDelegate(string str1, string str2);
public struct FunctionForLater {
public string str1;
public string str2;
public MyDelegate del;
// Constructor
public FunctionForLater(MyDelegate func, string s1, string s2) {
str1 = s1;
str2 = s2;
del = func;
}
}
public List<FunctionForLater> someList = new List<FunctionForLater>();
void Start() {
// --- Add a function with params for later
someList.Add(new FunctionForLater(Function1, "Hello", "World"));
// --- Calling the stored function
FunctionForLater func = someList[0];
func.del(func.str1, func.str2);
}
Hopefully that kind of makes sense. Let me know if it doesn't!
Thank you for the reply! I'll get back to you once I put everything in and test it :)
It's starting to work well, still adjusting everything. I have another question, how can I check if someList contains a function at someList[0], I think I'm doing something wrong.
Thank you again for replying earlier! It really helped.
AC$$anonymous$$, sorry, I didn't look back at this question to check for another response. Um, how to check to see if, for example, someList[0] has a function? Why are you trying to check for that? I mean, you could see if someList[0] == null or if someList[0].del == null. I kinda doubt that's what you mean. If you clarify that question a bit, I'd be more than happy to respond unless you've already got something figured out.
Oh! Well the response you just made actually helped me! I was being an idiot and only used "if(someList[0] == ExampleTask)", I didn't know I had to include the .del after someList[0]. I wanted to check someList[0] so when it contains the function I'm looking for, I can call some stuff. Sorry I didn't clarify well, but you helped again. Thanks lol.