Unity EventManager也支持协程

时间:2017-11-03 13:22:20

标签: c# events unity3d coroutine

我正在寻找支持协程执行的C#EventManager,如this one。换句话说,我希望能够做到这样的事情:

EventManager.StartListening("AString", ACoroutine);

我知道我可以在一个函数中包装我的协同程序并使用当前版本的代码,但如果代码本身支持它以避免脏代码会更好。

1 个答案:

答案 0 :(得分:1)

您可以使用普通方法包装协程,以便使用现有代码:

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

public class EventManager : MonoBehaviour
{
    private Dictionary<string, List<Func<IEnumerator>>> 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, List<Func<IEnumerator>>>();
        }
    }
    public void StartListening(string eventName, Func<IEnumerator> listener)
    {
        List<Func<IEnumerator>> thisEvent;
        if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
        {
            thisEvent.Add(listener);
        }
        else
        {
            instance.eventDictionary.Add(eventName, new List<Func<IEnumerator>>() { listener });
        }
    }

    public void StopListening(string eventName, Func<IEnumerator> listener)
    {
        if (eventManager == null) return;
        List<Func<IEnumerator>> thisEvent;
        if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
        {
            thisEvent.Remove(listener);
        }
    }

    public void TriggerEvent(string eventName)
    {

        List<Func<IEnumerator>> thisEvent = null;
        if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
        {
            for (int i = thisEvent.Count -1 ; i >= 0; i--)
            {
                if(thisEvent[i] == null)
                { 
                     thisEvent.RemoveAt(i);
                     continue; 
                }
                StartCoroutine(thisEvent[i]());
            }
        }
    }
}

编辑: 这是支持协同程序的系统。它必须采用一个稍微不同的过程(或者至少我没有深入研究它),所以不是调用类型的事件,而是创建一个类型的列表。这是因为您的StartCoroutine无法调用多个委托并需要迭代。

 <configuration>
    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true" />