尝试将UnityAction作为我的一个方法的参数发送,如下所示:
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);
这很好用,但现在我想将以下Action作为参数传递:
public void ActivateQuest(int questId)
{
Debug.Log("This is the id: " + questId);
}
但是,当我使用具有参数的操作时,它将无法工作:
dialogHolder.PopulateConversationList(stage1, "Okay", _name, 1, QuestManager.Instance().ActivateQuest(2));
上面给出了错误:Cannot convert from void to UnityAction
。
如何将带参数的UnityAction作为参数传递?
我在对话中调用Action
,如下所示:
dialog.OnAccept(ConvList[i].onLastPagePrompt, () =>
{
ConvList[i].action();
dialog.Hide();
});
编辑:我最终采用的解决方案:
enter dialogHolder.PopulateConversationList(stage1, "Okay", _name, 1, () =>
{
QuestManager.Instance().ActivateQuest(0);
});
这样我也可以调用几种方法。
答案 0 :(得分:2)
问题在于:
public void PopulateConversationList(string[] fullConversation, string onLastPagePrompt, string npcName, int stage, UnityAction action)
action
参数不接受任何参数,但您传递的是需要参数的函数:
public void ActivateQuest(int questId)
{
Debug.Log("This is the id: " + questId);
}
with:
dialogHolder.PopulateConversationList(stage1, "Okay", _name, 1, QuestManager.Instance().ActivateQuest(2));
注意2
传递给ActivateQuest
函数。
将参数传递给UnityEvent
并不像人们期望的那么简单。您必须从UnityEvent
派生,并提供参数类型。在这种情况下,您想传递int。您必须创建一个派生自UnityEvent且int
为通用的类。
public class IntUnityEvent : UnityEvent<int>{}
IntUnityEvent action
变量可以作为函数中的参数而不是UnityAction action
传递。
以下是一个简化的通用解决方案,以便它对其他人也有帮助。只需将您的其他参数添加到PopulateConversationList
函数中,您就应该好了。评论很好。
[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);
}
注意强>:
如果可能,请避免在Unity中使用UnityEvent
。使用C#Action
和delegate
,因为它们更容易使用。而且,它们比Unity的UnityEvent
快得多。
答案 1 :(得分:0)
您可以使用类似的东西
public void RegisterEvent<T, U, V>(object eventName, Action<T, U, V> handler)
{
Register(eventName, handler);
}
答案 2 :(得分:0)
这应该有效
private void Awake()
{
UnityAction unityAction = null;
unityAction += () => Jamen1("UnityAction Jamen1");
unityAction += Jamen2;
unityAction += () =>
{
print("UnityAction Jamen3");
};
Jamen3(unityAction)
}
void Jamen1(string text)
{
print(text);
}
void Jamen2()
{
print("UnityAction Jamen2");
}
void Jamen3(UnityAction unityAction)
{
unityAction?.Invoke();
}
注意:?是空检查。
// Null Check
unityAction?.Invoke();
// Don't Null Check
unityAction.Invoke();
答案 3 :(得分:0)
我用 lambda 表达式来解决这个问题
dialogHolder.PopulateConversationList(stage1, "Okay", _name, 1, () => {
QuestManager.Instance().ActivateQuest(2);
});