使用 UnityAction 传递参数

Maj*_*ajs 2 c# unity-game-engine

尝试发送 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);
Run Code Online (Sandbox Code Playgroud)

这工作正常,但现在我想将以下操作作为参数传递:

public void ActivateQuest(int questId)
{
    Debug.Log("This is the id: " + questId);
}
Run Code Online (Sandbox Code Playgroud)

但是,当我使用具有参数的操作时,它将不起作用:

dialogHolder.PopulateConversationList(stage1, "Okay", _name, 1, QuestManager.Instance().ActivateQuest(2));
Run Code Online (Sandbox Code Playgroud)

上面给出了错误:Cannot convert from void to UnityAction。如何将带有参数的 UnityAction 作为参数传递?

Action在对话中这样称呼:

dialog.OnAccept(ConvList[i].onLastPagePrompt, () =>
{
    ConvList[i].action();
    dialog.Hide();
});
Run Code Online (Sandbox Code Playgroud)

编辑:我最终采用的解决方案:

enter dialogHolder.PopulateConversationList(stage1, "Okay", _name, 1, () =>
    {
        QuestManager.Instance().ActivateQuest(0);
    });
Run Code Online (Sandbox Code Playgroud)

这样我也可以调用几个方法。

Pro*_*mer 5

问题是这样的:

public void PopulateConversationList(string[] fullConversation, string onLastPagePrompt, string npcName, int stage, UnityAction action)
Run Code Online (Sandbox Code Playgroud)

action参数不接受任何参数,但您向它传递一个需要参数的函数:

public void ActivateQuest(int questId)
{
    Debug.Log("This is the id: " + questId);
}
Run Code Online (Sandbox Code Playgroud)

和:

dialogHolder.PopulateConversationList(stage1, "Okay", _name, 1, QuestManager.Instance().ActivateQuest(2));
Run Code Online (Sandbox Code Playgroud)

注意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);
}
Run Code Online (Sandbox Code Playgroud)

笔记

如果可能,请避免UnityEvent在 Unity 中使用。使用 C# Actiondelegate因为它们更容易使用。而且,它们比 Unity 的UnityEvent.