代码之家  ›  专栏  ›  技术社区  ›  Jacob Cohen

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

  •  3
  • Jacob Cohen  · 技术社区  · 9 年前

    假设我有一个类 不 继承自如下所示的单行为:

    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);
            }
        }
    }
    

    和一个单一行为的统一控制器,如下所示:

    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);
        }
    }
    

    如何连接这两者?

    假设我有以下引导代码:

    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 回复  |  直到 9 年前
        1
  •  2
  •   Programmer    9 年前

    如何使应用程序启动方法上的LoginController在以下情况下运行: 正在调用应用程序运行方法,或分派事件 应用程序启动事件。

    EventManager 可以注册和取消注册事件的脚本。这些功能应该 ApplicationStartedEvent 作为参数。再添加一个可用于调用已订阅事件的函数。

    然后,您可以订阅其他脚本中的事件,例如 LoginController 剧本订阅应在 OnEnable 和 OnDisable 作用

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

    非常重要 :

    请重命名您的 Application 脚本 Application2 或者别的什么。有一个名为 Application 如果您使用此类中的函数,则会遇到编译时错误。

    我将使用 而不是 应用 在该解决方案中。

    EventManager.cs :

    请将此附加到空游戏对象

    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;
        }
    }
    

    :

    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);
        }
    }