目录
前言
该事件系统由C#的委托进行实现。
关于事件系统的概述和委托的使用可以看其他文章或者官方文档,这里不多说,直接上代码
EventSystem定义
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Util
{
public class EventData
{
//key:变量名字,value:变量值
public Dictionary<string, object> parms {
get; private set; }
public EventData(Dictionary<string, object> parms_in)
{
parms = parms_in;
}
}
public static class EventSystem
{
//key:事件名字,value:注册该事件的所有函数
private static Dictionary<string, Action<EventData>> event_dict = new Dictionary<string, Action<EventData>>();
public static void AddEventListener(string event_type, Action<EventData> cb)
{
if (event_dict == null)
{
throw new Exception("EventSystem.event_dict is null");
}
Action<EventData> action = null;
event_dict.TryGetValue(event_type, out action);
action += cb;
event_dict[event_type] = action;
}
public static void RemoveEventListener(string event_type, Action<EventData> cb)
{
if (event_dict == null)
{
throw new Exception("EventSystem.event_dict is null");
}
Action<EventData> action = null;
if(event_dict.TryGetValue(event_type, out action))
{
action -= cb;
event_dict[event_type] = action;
}
else
{
throw new Exception($"EventSystem.event_dict is not have key : {
event_type}, {
cb.Method}");
}
}
public static void Dispatch(string event_type, EventData event_data = null)
{
if (event_dict == null)
{
throw new Exception("EventSystem.event_dict is null");
}
Action<EventData> action = null;
if (!event_dict.TryGetValue(event_type, out action))
{
throw new Exception($"EventSystem.event_dict is not have event : {
event_type}");
}
action.Invoke(event_data);
}
}
}
应用场景
- 游戏刚开始的时候进行初始化操作。
- 现在假设玩家有多种状态,比如Win和Dead。当玩家处于不同状态的时候,需要播放指定音效,并且UI要更新。
注册事件
- PlayerState.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace State
{
public enum PlayerState
{
Win,
Dead
}
}
注
下方代码中的 Singleton 是我自己写的单例模板类
具体可以看我之前写的文章:浅谈设计模式和其Unity中的应用:一、单例模式
- AudioManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Util;
using State;
public class AudioManager : Singleton<AudioManager>
{
private void Awake()
{
EventSystem.AddEventListener("GameStart", GameStartPlayAudio);
EventSystem.AddEventListener("PlayerStateChange", PlayerStateChange);
}
private void GameStartPlayAudio(EventData ed)
{
print($"AudioManager : GameStartPlayAudio, ed = {
ed}");
}
private void PlayerStateChange(EventData ed)
{
PlayerState player_state = (PlayerState)ed.parms["PlayerCurrentState"];
switch (player_state)
{
case PlayerState.Win:
print("WinAudio");
break;
case PlayerState.Dead:
print("DeadAudio");
break;
}
}
}
- UIManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Util;
using State;
public class UIManager : Singleton<UIManager>
{
private void Awake()
{
EventSystem.AddEventListener("GameStart", GameStartPlayUI);
EventSystem.AddEventListener("PlayerStateChange", PlayerStateChange);
}
private void GameStartPlayUI(EventData ed)
{
print($"UIManager : GameStartPlayUI, ed = {
ed}");
}
private void PlayerStateChange(EventData ed)
{
PlayerState player_state = (PlayerState)ed.parms["PlayerCurrentState"];
switch (player_state)
{
case PlayerState.Win:
print("WinUI");
break;
case PlayerState.Dead:
print("DeadUI");
break;
}
}
}
抛事件
这里简单一点,在Update中按键模拟玩家状态的转换
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Util;
using State;
public class GameManager : Singleton<GameManager>
{
private void Start()
{
EventSystem.Dispatch("GameStart");
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
EventData ed = new EventData(new Dictionary<string, object>()
{
{
"PlayerCurrentState", PlayerState.Win },
});
EventSystem.Dispatch("PlayerStateChange", ed);
}
if (Input.GetKeyDown(KeyCode.S))
{
EventData ed = new EventData(new Dictionary<string, object>()
{
{
"PlayerCurrentState", PlayerState.Dead },
});
EventSystem.Dispatch("PlayerStateChange", ed);
}
}
}