如何在Unity中从另一个实例调度的实例中订阅C#中的事件?

时间:2016-12-15 07:56:14

标签: c# events unity3d

我们假设我有一个继承自MonoBehavior的类,如下所示:

public interface IApplication
{
    void run();
}

public class Application : IApplication
{
    public static IServiceManager serviceManager;
    public delegate void ApplicationStartedEvent(object source, EventArgs args);
    public event ApplicationStartedEvent applicationStartedEvent;

    public void run()
    {

    }

    protected virtual void OnApplicationStarted()
    {
        if (applicationStartedEvent != null)
        {
            applicationStartedEvent(this, EventArgs.Empty);
        }
    }
}

Unity控制器是一个像这样的MonoBehavior:

public class LoginController : MonoBehaviour 
{
    void Start()
    {
        Hide();
    }

    public void OnApplicationStarted(object source, EventArgs e)
    {
        Show();
    }

    public virtual void Show()
    {
        gameObject.SetActive(true);
    }

    public virtual void Hide()
    {
        gameObject.SetActive(false);
    }
}

如何连接这两个?

假设我有以下Bootstrap代码:

public class Setup : MonoBehaviour
{
    Application application;

    void Awake()
    {
        application = new Application();
        application.run();
    }
}

如何在调用LoginController OnApplicationStarted方法时运行Application run方法,或者调度ApplicationStartedEvent的事件。

我如何看待EventManager的示例:

addEventListener(string eventName, Callback callback)

dispatchEvent(Event event)

以下是如何在LoginController中使用它:

EventManager.addEventListener("ApplicationStarted", this.OnApplicationStarted)

以下是在应用程序中使用它的方法:

public void run()
{
    EventManager.dispatchEvent(new ApplicationStartedEvent());
}

显然,这只是一个想法,而不必是相同的语法。

编辑: 我想我找到的东西几乎与我想要的东西相似: http://wiki.unity3d.com/index.php/Advanced_CSharp_Messenger

1 个答案:

答案 0 :(得分:2)

  

如何在运行时运行LoginController OnApplicationStarted方法   正在调用应用程序运行方法或调度一个事件   ApplicationStartedEvent。

创建一个可以注册和取消注册事件的EventManager脚本。此函数应将ApplicationStartedEvent作为参数。再添加一个可用于调用附加事件的函数。

然后,您可以从其他脚本(例如LoginController脚本)获取事件。订阅应在OnEnableOnDisable函数中完成。

然后可以从应用程序脚本中的run()函数调用事件。

非常重要

请将您的Application脚本重命名为Application2或其他内容。有一个名为Application的Unity API,如果您使用此类中的函数,则会遇到编译时错误。

我将在此解决方案中使用Application2代替Application

EventManager.cs

请将此附加到Empty GameObject

public class EventManager : MonoBehaviour
{
    private static EventManager localInstance;
    public static EventManager Instance { get { return localInstance; } }

    private void Awake()
    {
        if (localInstance != null && localInstance != this)
        {
            Destroy(this.gameObject);
        }
        else
        {
            localInstance = this;
        }
    }

    public delegate void ApplicationStartedEvent(object source, EventArgs args);
    private event ApplicationStartedEvent applicationStartedEvent;


    public void dispatchEvent(object source, EventArgs args)
    {
        foreach (ApplicationStartedEvent runEvent in applicationStartedEvent.GetInvocationList())
        {
            try
            {
                runEvent.Invoke(source, args);
            }
            catch (Exception e)
            {
                Debug.LogError(string.Format("Exception while invoking" + runEvent.Method.Name + e.Message));
            }
        }
    }

    public void registerEvent(ApplicationStartedEvent callBackFunc)
    {
        applicationStartedEvent += callBackFunc;
    }

    public void unRegisterEvent(ApplicationStartedEvent callBackFunc)
    {
        applicationStartedEvent -= callBackFunc;
    }
}

Application2.cs

public class Application2 : IApplication
{
    public void run()
    {
        OnApplicationStarted();
    }

    protected virtual void OnApplicationStarted()
    {
        EventManager.Instance.dispatchEvent(this, EventArgs.Empty);
    }
}

LoginController.cs

public class LoginController : MonoBehaviour
{

    void Start()
    {
        Hide();
    }

    public void OnApplicationStarted(object source, EventArgs e)
    {
        Show();
    }

    public virtual void Show()
    {
        gameObject.SetActive(true);
    }

    public virtual void Hide()
    {
        gameObject.SetActive(false);
    }

    void OnEnable()
    {
        //Subscribe to event
        EventManager.Instance.registerEvent(OnApplicationStarted);
    }

    void OnDisable()
    {
        //Un-Subscribe to event
        EventManager.Instance.unRegisterEvent(OnApplicationStarted);
    }
}