书接上文https://blog.csdn.net/qq_39779932/article/details/103224191,解耦也可以通过事件消息系统来做解耦。
同上一篇所述,一个简单的场景,按下1键时亮起灯1,按下2键时亮起2灯,按下3键时亮起3灯,每次亮灯时都要关闭其他的灯。
首先是一个事件消息系统,代码如下
public class MessageEvent
{
private static MessageEvent instance { set; get; }
public static MessageEvent Instance
{
get {
if (instance==null)
{
instance = new MessageEvent();
dic = new Dictionary<EventType, Action>();
}
return instance;
}
}
private static Dictionary<EventType,Action> dic { set; get; }
public void RegistEvent(EventType eventType,Action action)
{
if (action == null) return;
dic[eventType] = action;
}
public void Fire(EventType eventType)
{
if (dic[eventType]!=null)
{
dic[eventType]();
}
}
}
public enum EventType
{
none,
Close23,
Close13,
Close12
}
在这个消息事件系统中,定义了一个枚举EventType来表示事件,消息事件中RegistEvent用来注册事件,Fire执行事件。
如此灯1代码:
public class ELightController1 : MonoBehaviour
{
private Light light { set; get; }
void Awake()
{
light = GetComponent<Light>();
}
void Update()
{
if (!Input.GetKeyDown(KeyCode.Alpha1)) return;
light.enabled = true;
MessageEvent.Instance.Fire(EventType.Close23);
}
}
灯2代码:
public class ELightController2 : MonoBehaviour
{
private Light light { set; get; }
void Awake()
{
light = GetComponent<Light>();
}
void Update()
{
if (!Input.GetKeyDown(KeyCode.Alpha2)) return;
light.enabled = true;
MessageEvent.Instance.Fire(EventType.Close13);
}
}
灯3代码:
public class ELightController3 : MonoBehaviour
{
private Light light { set; get; }
void Awake()
{
light = GetComponent<Light>();
}
void Update()
{
if (!Input.GetKeyDown(KeyCode.Alpha3)) return;
light.enabled = true;
MessageEvent.Instance.Fire(EventType.Close12);
}
}
一个管理类:
public class EGameController : MonoBehaviour
{
public Light light1;
public Light light2;
public Light light3;
private void Awake()
{
MessageEvent.Instance.RegistEvent(EventType.Close23, turnOffLight23);
MessageEvent.Instance.RegistEvent(EventType.Close13, turnOffLight13);
MessageEvent.Instance.RegistEvent(EventType.Close12, turnOffLight12);
}
private void turnOffLight23()
{
light2.enabled = false;
light3.enabled = false;
}
private void turnOffLight13()
{
light1.enabled = false;
light3.enabled = false;
}
private void turnOffLight12()
{
light1.enabled = false;
light2.enabled = false;
}
}
如上所示,每个灯在需要关闭其他灯时只要执行相应的消息事件即可,根本不需要了解其他灯的情况。在EGameController终对需要注册的消息事件进行统一的注册。也可以需要EGameController,这样就要到各个对象那里去注册事件。消息事件好比一个幽灵一样,游走于各个的对象间,同时又对各个对象提供情报。
最后Unity解耦三闭包,参见https://blog.csdn.net/qq_39779932/article/details/103130990
当然肯定还有其他的方式,期待在未来能够学习到,并书以记之。