分享一个消息发送及接收的框架,改编至一个叫EventManager的消息管理类(https://unity3d.com/cn/learn/tutorials/topics/scripting/events-creating-simple-messaging-system),之前在寻找消息管理框架的时候发现了这个类,感觉挺好用,逻辑也很清晰。但随着需求的增加,发现它也有些许的局限性,不能传参,只能触发事件,于是自己在上面做了些扩展。它的核心思想是通过字典来管理方法及方法触发的条件,
private Dictionary eventDictionary;
string表示存入的消息名,unityEvent存入的消息名所对应的事件,unityEvent本身是一个不带参的委托,因此导致我们调用的时候不能传参。于是我把unityEvent换成了Action,这样就可以存带参的方法了,如Action
private Dictionary > eventDictionary;
因为项目赶时间,没来得及细化,若有不足之处,欢迎指证,下面给出代码:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MSGCenter : MonoBehaviour {
private Dictionary
private static MSGCenter eventManager;
//单例
public static MSGCenter instance
{
get
{
if (!eventManager)
{
//在Unity的Hierarchy中必须有一个名为EventManager的空物体,并挂上EventManager脚本
eventManager = FindObjectOfType(typeof(MSGCenter)) as MSGCenter;
if (!eventManager)
{
Debug.LogError("There needs to be one active EventManger script on a GameObject in your scene.");
}
else
{
eventManager.Init();
}
}
return eventManager;
}
}
public void Init()
{
if (eventDictionary == null)
{
eventDictionary = new Dictionary
}
}
//在需要监听某个事件的脚本中,调用这个方法来监听这个事件
public static void StartListening(string eventName, Action
{
if (instance.eventDictionary.ContainsKey(eventName))
{
instance.eventDictionary[eventName]=action;
}
else
{
instance.eventDictionary.Add(eventName, action);
}
}
//在不需要监听的时候停止监听
public static void StopListening(string eventName)
{
if (instance.eventDictionary.ContainsKey(eventName))
{
instance.eventDictionary.Remove(eventName);
}
}
//触发某个事件
public static void TriggerEvent(string eventName, ArrayList obj)
{
if (instance.eventDictionary.ContainsKey(eventName))
{
instance.eventDictionary[eventName].Invoke(obj);
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class EventManagerTest : MonoBehaviour
{
void OnEnable()
{
Action
MSGCenter.StartListening ("hello", action);
}
void OnDisable()
{
MSGCenter.StopListening ("hello");
}
private void MoveCube(ArrayList obj)
{
print("触发了消息"+obj[0]+obj[1]);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BtnEventHandle : MonoBehaviour {
// Use this for initialization
void Start () {
}
private void Update()
{
if (Input.GetKeyUp(KeyCode.S))
{
MSGCenter.TriggerEvent("hello",new ArrayList {1,"str" });
}
}
}