機能: 他のスクリプトにアクセスする場合、直接アクセスするのではなく、「コマンド」を送信し、その「コマンド」をリッスンしたスクリプトが対応するロジックを自動的に実行します。
原則:
1. スクリプトにイベントをイベント センターに追加させ、対応する「コマンド」をリッスンさせます。
2. 「コマンド」を送信すると、イベント センターはこの「コマンド」をリッスンしているスクリプトに通知し、対応するロジックを自動的に実行させます。
Event Center Manager: イベントの追加、コマンドの送信
従業員クラスがメソッドをイベント センター マネージャーに登録します
public class Cube : MonoBehaviour
{
private void Awake()
{
EventCenterManager.Instance.AddListener("开工", Write);
}
public void Write()
{
transform.position += Vector3.right;
Debug.Log("我是策划,我在写策划案");
}
}
イベント管理センタークラス
public class EventCenterManager : SingletonPatternBase<EventCenterManager>
{
//键表示命令的名字
//值表示命令具体要执行的逻辑
Dictionary<string, UnityAction> eventsDictionary = new Dictionary<string, UnityAction>();
public void AddListener(string key,UnityAction call)
{
if (eventsDictionary.ContainsKey(key))
{
eventsDictionary[key] += call;
}
else
eventsDictionary.Add(key, call);
}
/// <summary>
/// 取消监听的命令
/// </summary>
public void RemoveListener(string key,UnityAction call)
{
if (eventsDictionary.ContainsKey(key))
{
eventsDictionary[key] -= call;
}
}
//发送命令
public void DisPatch(string key)
{
if (eventsDictionary.ContainsKey(key))
{
eventsDictionary[key]?.Invoke();
}
}
メソッドを呼び出したい場合は、DIsPatch コマンド名を直接呼び出してください。
ストップウォッチクラスのテストパフォーマンス
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
using UnityEngine.Events;
/// <summary>
/// Stopwatch类的工具类,用于计算运行一段代码所用的时间
/// </summary>
public class StopwatchUtility
{
/// <summary>
/// 获取执行一段代码所需要的时间
/// </summary>
/// <param name="call"></param>
/// <returns></returns>
public static TimeSpan GetTime(UnityAction call)
{
//声明一个计数器
Stopwatch timer = Stopwatch.StartNew();
//开启计时器
timer.Start();
//要测试什么代码就将代码放在这里
call?.Invoke();
//停止计时器
timer.Stop();
//返回时间信息
return timer.Elapsed;
}
public void PrintTime(UnityAction call)
{
UnityEngine.Debug.Log(GetTime(call));
}
}
リヒター置換原理の使用方法
2 つのクラスを自分で作成して 2 つの異なる UnityAction をラップし、それらを同じインターフェースから継承させると、Liskov 置換原則を実装できます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class EventCenterManager : SingletonPatternBase<EventCenterManager>
{
//键表示命令的名字
//值表示命令具体要执行的逻辑
Dictionary<string, IEventInfo> eventsDictionary = new Dictionary<string, IEventInfo>();
public void AddListener(object command,UnityAction call)
{
string key = command.GetType().Name + "_" + command.ToString();
if (eventsDictionary.ContainsKey(key))
{
(eventsDictionary[key] as EventInfo).action += call;
}
else
eventsDictionary.Add(key,new EventInfo(call));
}
//传递带参数的委托
public void AddListener<T>(object command,UnityAction<T> call)
{
string key = command.GetType().Name + "_" + command.ToString() + "_" + typeof(T).Name;
if (eventsDictionary.ContainsKey(key))
{
(eventsDictionary[key] as EventInfo<T>).action += call;
}
else
eventsDictionary.Add(key, new EventInfo<T>(call));
}
/// <summary>
/// 取消监听的命令
/// </summary>
public void RemoveListener(object command,UnityAction call)
{
string key = command.GetType().Name + "_" + command.ToString();
if (eventsDictionary.ContainsKey(key))
{
(eventsDictionary[key] as EventInfo).action -= call;
}
}
//取消带有参数的监听事件
public void RemoveListener<T>(object command,UnityAction<T> call)
{
string key = command.GetType().Name + "_" + command.ToString() + "_" + typeof(T).Name;
if (eventsDictionary.ContainsKey(key))
{
(eventsDictionary[key] as EventInfo<T>).action -= call;
}
}
//移除一条命令所对应的全部委托
public void RemoveListeners(object command)
{
string key = command.GetType().Name + "_" + command.ToString();
if (eventsDictionary.ContainsKey(key))
{
(eventsDictionary[key] as EventInfo).action = null;
}
}
//带有参数的移除一条命令中所有委托
public void RemoveListeners<T>(object command)
{
string key = command.GetType().Name + "_" + command.ToString() + "_" + typeof(T).Name;
if (eventsDictionary.ContainsKey(key))
{
(eventsDictionary[key] as EventInfo<T>).action = null;
}
}
//发送命令
public void DisPatch(object command)
{
string key = command.GetType().Name + "_" + command.ToString();
if (eventsDictionary.ContainsKey(key))
{
(eventsDictionary[key] as EventInfo).action?.Invoke();
}
}
//给带参数的事件写的重载
public void DisPatch<T>(object command,T parameter)
{
string key = command.GetType().Name + "_" + command.ToString() + "_" + typeof(T).Name;
if (eventsDictionary.ContainsKey(key))
{
(eventsDictionary[key] as EventInfo<T>).action?.Invoke(parameter);
}
}
/// <summary>
/// 移除所有带或者不带参数的监听事件,切换场景可以考虑使用
/// </summary>
public void RemoveAllListeners()
{
eventsDictionary.Clear();
}
private interface IEventInfo { } //仅用于里氏替换原则
private class EventInfo:IEventInfo
{
public UnityAction action;
public EventInfo(UnityAction call)
{
action += call;
}
}
private class EventInfo<T> :IEventInfo
{
public UnityAction<T> action;
public EventInfo(UnityAction<T> call)
{
action += call;
}
}
}
複数のパラメーターを渡すデリゲート イベント:
- 複数の情報を格納する情報クラスを作成し、この情報クラスをイベントで渡すことができます。これはまだパラメータです
- または、2 つのパラメーター、3 つまたは 4 つのパラメーターを使用して追加のメソッドを作成します (実行可能ですが、手間がかかります)。
- タプル (ただし、これが何なのかはわかりません)