Pass parameters with UnityAction
Here is the problem:
public void PopulateConversationList(string[] fullConversation, string onLastPagePrompt, string npcName, int stage, UnityAction action)
The action
argument does not accept any parameter but you are passing it a function that requires a parameter:
public void ActivateQuest(int questId)
{
Debug.Log("This is the id: " + questId);
}
with:
dialogHolder.PopulateConversationList(stage1, "Okay", _name, 1, QuestManager.Instance().ActivateQuest(2));
Notice the 2
passed to the ActivateQuest
function.
Passing parameter to UnityEvent
is not really that simple as one would expect. You must derive from UnityEvent
and also provide the type of parameter. In this case you want to pass int. You must create a class that derives from UnityEvent with int
as generic.
public class IntUnityEvent : UnityEvent<int>{}
The IntUnityEvent action
variable can then be passed around as parameter in your functions instead of UnityAction action
.
Below is a simplified and generic solution provided so that it will be helpful to others too. Just add your other parameters to the PopulateConversationList
function and you should be good to go. It's well commented.
[System.Serializable]
public class IntUnityEvent : UnityEvent<int>
{
public int intParam;
}
public IntUnityEvent uIntEvent;
void Start()
{
//Create the parameter to pass to the function
if (uIntEvent == null)
uIntEvent = new IntUnityEvent();
//Add the function to call
uIntEvent.AddListener(ActivateQuest);
//Set the parameter value to use
uIntEvent.intParam = 2;
//Pass the IntUnityEvent/UnityAction to a function
PopulateConversationList(uIntEvent);
}
public void PopulateConversationList(IntUnityEvent action)
{
//Test/Call the function
action.Invoke(action.intParam);
}
//The function to call
public void ActivateQuest(int questId)
{
Debug.Log("This is the id: " + questId);
}
Note:
If possible, avoid using UnityEvent
in Unity. Use use C# Action
and delegate
since they are more easier to use. Also, they are much more faster than Unity's UnityEvent
.
Majs
Updated on June 13, 2022Comments
-
Majs almost 2 years
Trying to send an UnityAction as a parameter for one of my methods, like so:
public void PopulateConversationList(string [] fullConversation, string onLastPagePrompt, string npcName, int stage, UnityAction action) { conversations.Add(new Conversation(fullConversation, onLastPagePrompt, npcName, stage, action)); } dialogHolder.PopulateConversationList(stage1, "Okay", _name, 1, QuestManager.Instance().ActivateQuest);
this works fine, but now I want to pass the following Action as a parameter:
public void ActivateQuest(int questId) { Debug.Log("This is the id: " + questId); }
However, it will not work when I use an action that has a parameter:
dialogHolder.PopulateConversationList(stage1, "Okay", _name, 1, QuestManager.Instance().ActivateQuest(2));
The above gives error:
Cannot convert from void to UnityAction
. How can I pass a UnityAction with a parameter, as a parameter?I call the
Action
in the conversation like this:dialog.OnAccept(ConvList[i].onLastPagePrompt, () => { ConvList[i].action(); dialog.Hide(); });
EDIT: The solution I ended up going with:
enter dialogHolder.PopulateConversationList(stage1, "Okay", _name, 1, () => { QuestManager.Instance().ActivateQuest(0); });
This way I can call several methods as well.
-
Majs almost 7 yearsThanks, Accepted cus it answers my question :) I ended up finding my own way, which also allows me to call several methods, which I need.
-
Selim Yildiz about 4 yearsIt could be better if you provide explanation how your solution works.
-
Display name about 2 yearsThis is a question about Unity c#, not general c#. There is a subtle but huge difference there. In Unity, you should not use Action, you should use UnityAction. Also, without the Register method, this answer is incomplete.