将参数传递给UnityEvent

Ale*_*öln 5 c# unity-game-engine

好吧,我有点困惑。我UnityEvent通过教程学习了消息系统。但是我有一个问题,我无法理解。如何将参数传递给调用函数?

例如(我EventManager在教程中喜欢):

void OnEnable() {
        EventManager.StartListening ("OnPlayerTeleport", TeleportPlayer);
    }

    void OnDisable() {
        EventManager.StopListening ("OnPlayerTeleport", TeleportPlayer);
    }

    void TeleportPlayer () {
        float yPos = transform.position.y;
        yPos += 20.0f;
        transform.position = new Vector3 (transform.position.x, yPos, transform.position.z);
    }
Run Code Online (Sandbox Code Playgroud)

我有触发器:

void Update () {
    if (Input.GetButtonDown ("Teleport")) {
        EventManager.TriggerEvent ("OnPlayerTeleport");
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我想将“ height”值传递给函数“ TeleportPlayer”,该怎么办:

void TeleportPlayer (float h) {
    float yPos = transform.position.y;
    yPos += h;
    transform.position = new Vector3 (transform.position.x, yPos, transform.position.z);
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

Pro*_*mer 2

使用 C# delegate/Action 而不是 Unity 的UnityEvent. 它比Unity的事件要快。我前几天移植的。您只需要稍微修改一下即可获得您想要的内容。

1 .Make Actiontakefloat通过将所有Action声明更改为Action<float>这意味着它将允许带float参数的函数。

2.现在,让TriggerEvent函数接受一个float参数。通过改变

public static void TriggerEvent(string eventName)
Run Code Online (Sandbox Code Playgroud)

public static void TriggerEvent(string eventName, float h)
Run Code Online (Sandbox Code Playgroud)

这是新EventManager脚本。

using UnityEngine;
using System.Collections.Generic;
using System;

public class EventManager : MonoBehaviour
{

    private Dictionary<string, Action<float>> eventDictionary;

    private static EventManager eventManager;

    public static EventManager instance
    {
        get
        {
            if (!eventManager)
            {
                eventManager = FindObjectOfType(typeof(EventManager)) as EventManager;

                if (!eventManager)
                {
                    Debug.LogError("There needs to be one active EventManger script on a GameObject in your scene.");
                }
                else
                {
                    eventManager.Init();
                }
            }

            return eventManager;
        }
    }

    void Init()
    {
        if (eventDictionary == null)
        {
            eventDictionary = new Dictionary<string, Action<float>>();
        }
    }

    public static void StartListening(string eventName, Action<float> listener)
    {

        Action<float> thisEvent;
        if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
        {
            thisEvent += listener;
        }
        else
        {
            thisEvent += listener;
            instance.eventDictionary.Add(eventName, thisEvent);
        }
    }

    public static void StopListening(string eventName, Action<float> listener)
    {
        if (eventManager == null) return;
        Action<float> thisEvent;
        if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
        {
            thisEvent -= listener;
        }
    }

    public static void TriggerEvent(string eventName, float h)
    {
        Action<float> thisEvent = null;
        if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
        {
            thisEvent.Invoke(h);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

测试:

public class Test : MonoBehaviour
{

    void OnEnable()
    {
        EventManager.StartListening("OnPlayerTeleport", TeleportPlayer);
    }

    void OnDisable()
    {
        EventManager.StopListening("OnPlayerTeleport", TeleportPlayer);
    }

    void Update()
    {
        if (Input.GetButtonDown("Teleport"))
        {
            EventManager.TriggerEvent("OnPlayerTeleport", 5);
        }
    }

    void TeleportPlayer(float h)
    {
        float yPos = transform.position.y;
        yPos += h;
        transform.position = new Vector3(transform.position.x, yPos, transform.position.z);
    }
}
Run Code Online (Sandbox Code Playgroud)