wordpress blod關(guān)鍵詞是網(wǎng)站seo的核心工作
前言
框架的事件系統(tǒng)主要負(fù)責(zé)高效的方法調(diào)用與數(shù)據(jù)傳遞,實(shí)現(xiàn)各功能之間的解耦,通常在調(diào)用某個(gè)實(shí)例的方法時(shí),必須先獲得這個(gè)實(shí)例的引用或者新實(shí)例化一個(gè)對(duì)象,低耦合度的框架結(jié)構(gòu)希望程序本身不去關(guān)注被調(diào)用的方法所依托的實(shí)例對(duì)象是否存在,通過事件系統(tǒng)做中轉(zhuǎn)將功能的調(diào)用封裝成事件,使用事件監(jiān)聽注冊(cè)、移除和事件觸發(fā)完成模塊間的功能調(diào)用管理。常用在UI事件、跨模塊事件上。
一、作用
訪問其它腳本時(shí),不直接訪問,而是通過發(fā)送一條類似“命令”,讓監(jiān)聽了這條“命令”的腳本自動(dòng)執(zhí)行對(duì)應(yīng)的邏輯。
二、原理
1、讓腳本向事件中心添加事件,監(jiān)聽對(duì)應(yīng)的“命令”。
2、發(fā)送“命令”,事件中心就會(huì)通知監(jiān)聽了這條“命令”的腳本,讓它們自動(dòng)執(zhí)行對(duì)應(yīng)的邏輯。
三、不使用事件管理器
新增3個(gè)測(cè)試腳本
public class Player : MonoBehaviour {public void Log(){Debug.Log("我是玩家");}
}
public class Player1 : MonoBehaviour {public void Log(){Debug.Log("我是玩家1");}
}
public class Player2 : MonoBehaviour {public void Log(){Debug.Log("我是玩家2");}
}
調(diào)用各個(gè)腳本的log方法
public class EventManagerTest: MonoBehaviour
{private void Start(){GameObject go = GameObject.Find("Player");go.GetComponent<Player>().Log(); GameObject go1 = GameObject.Find("Player1");go1.GetComponent<Player1>().Log();GameObject go2 = GameObject.Find("Player2");go2.GetComponent<Player2>().Log();}
}
效果
四、使用事件管理器
1、事件管理器
新增EventManager,事件管理器
/// <summary>
/// 事件管理器
/// </summary>
public class EventManager : Singleton<EventManager>
{Dictionary<string, UnityAction> eventsDictionary = new Dictionary<string, UnityAction>();/// <summary>/// 事件監(jiān)聽/// </summary>/// <param name="eventName">事件名稱</param>/// <param name="action">監(jiān)聽方法</param>public void AddEventListener(string eventName, UnityAction action){if (eventsDictionary.ContainsKey(eventName)){eventsDictionary[eventName] += action;}else{eventsDictionary.Add(eventName, action);}}/// <summary>/// 觸發(fā)事件/// </summary>/// <param name="eventName">事件名稱</param>public void Dispatch(string eventName){if(eventsDictionary.ContainsKey(eventName)){eventsDictionary[eventName]?.Invoke();}}
}
2、添加事件監(jiān)聽
分別在Player、Player1、Player2新增如下代碼,添加事件監(jiān)聽
private void Start() {EventManager.Instance.AddEventListener("打印日志", Log);
}
3、觸發(fā)事件
在EventManagerTest中觸發(fā)事件
public class EventManagerTest : MonoBehaviour
{private void Start(){// GameObject go = GameObject.Find("Player");// go.GetComponent<Player>().Log(); // GameObject go1 = GameObject.Find("Player1");// go1.GetComponent<Player1>().Log();// GameObject go2 = GameObject.Find("Player2");// go2.GetComponent<Player2>().Log();EventManager.Instance.Dispatch("打印日志");}
}
4、結(jié)果
五、移除事件
比如有幾個(gè)小怪,都添加了事件監(jiān)聽,殺死后會(huì)被銷毀,如果不把事件移除,直接再次執(zhí)行命令則會(huì)報(bào)錯(cuò):
MissingReferenceException:The object of type 'Capsule'has been destroyed but you are still trying to access it.
修改EventManager,添加移除事件方法
/// <summary>
/// 移除事件某個(gè)監(jiān)聽方法
/// </summary>
/// <param name="eventName">事件名稱</param>
/// <param name="action">監(jiān)聽方法</param>
public void RemoveEventListener(string eventName, UnityAction action){if(eventsDictionary.ContainsKey(eventName)){eventsDictionary[eventName] -= action;}
}/// <summary>
/// 移除整個(gè)事件
/// </summary>
/// <param name="eventName">名稱</param>
public void RemoveEvent(string eventName){if(eventsDictionary.ContainsKey(eventName)){eventsDictionary[eventName] = null;}
}
測(cè)試調(diào)用
public class EventManagerTest : MonoBehaviour
{ private void OnGUI(){if (GUI.Button(new Rect(0, 0, 150, 50), "觸發(fā)事件")){EventManager.Instance.Dispatch("打印日志");}if (GUI.Button(new Rect(0, 50, 150, 50), "移除Player事件監(jiān)聽")){GameObject go = GameObject.Find("Player");EventManager.Instance.RemoveEventListener("打印日志", go.GetComponent<Player>().Log); }if (GUI.Button(new Rect(0, 100, 150, 50), "移除整個(gè)事件")){EventManager.Instance.RemoveEvent("打印日志");}}
}
效果
六、自定義枚舉事件名稱
目前事件名稱是字符串,手打容易出錯(cuò),我們可以選擇使用枚舉的方式
/// <summary>
/// 事件名稱枚舉
/// </summary>
public enum EventNameEnum{Log, //打印AddHealth //群體回血
}
修改EventManager,新增獲取事件名稱方法
/// <summary>
/// 獲取事件名稱
/// </summary>
/// <param name="eventNameEnum">事件枚舉</param>
/// <returns>事件名稱</returns>
private string GetEnventName(object EventNameEnum){return EventNameEnum.GetType().Name + "_" + EventNameEnum.ToString();
}
修改測(cè)試調(diào)用
public class EventManagerTest : MonoBehaviour
{ private void OnGUI(){if (GUI.Button(new Rect(0, 0, 150, 50), "觸發(fā)事件")){EventManager.Instance.Dispatch(EventNameEnum.Log);}if (GUI.Button(new Rect(0, 50, 150, 50), "移除Player事件監(jiān)聽")){GameObject go = GameObject.Find("Player");EventManager.Instance.RemoveEventListener(EventNameEnum.Log, go.GetComponent<Player>().Log); }if (GUI.Button(new Rect(0, 100, 150, 50), "移除整個(gè)事件")){EventManager.Instance.RemoveEvent(EventNameEnum.Log);}}
}
結(jié)果,和之前一樣
七、傳遞帶有一個(gè)參數(shù)的事件
如果我們想要傳遞帶有一個(gè)參數(shù)的事件,可以遵循里氏替換原則(Liskov Substitution Principle),即子類可以替換父類而不會(huì)影響程序的正確性。
-
里氏替換原則
通過使用IEventInfo
接口,可以確保EventInfo<T>
和EventInfo
類可以在需要IEventInfo
的上下文中被替換而不影響程序的功能。這使得事件管理器能夠處理不同類型的事件回調(diào)。 -
單一職責(zé)原則
每個(gè)EventInfo
類都有自己的職責(zé):EventInfo<T>
處理帶參數(shù)的回調(diào),而EventInfo
處理不帶參數(shù)的回調(diào)。這增強(qiáng)了代碼的清晰性和可維護(hù)性。
這種設(shè)計(jì)提供了靈活性,使得事件管理系統(tǒng)能夠處理多種類型的事件,同時(shí)也遵循了面向?qū)ο笤O(shè)計(jì)的原則。你可以根據(jù)需要擴(kuò)展或修改 IEventInfo
和 EventInfo
類,以支持更多的事件類型和邏輯。
1、接口 IEventInfo
定義一個(gè)標(biāo)記接口 IEventInfo,用于標(biāo)識(shí)事件信息的類型。這樣可以在系統(tǒng)中使用多態(tài)性,確保遵循里氏替換原則。
public interface IEventInfo { }
2、泛型類 EventInfo
EventInfo 類實(shí)現(xiàn)了 IEventInfo 接口。這個(gè)類用于處理帶有參數(shù)的事件回調(diào)(UnityAction),允許在事件觸發(fā)時(shí)傳遞參數(shù)。action 字段用于保存事件回調(diào)。
private class EventInfo<T> : IEventInfo
{public UnityAction<T> action;public EventInfo(UnityAction<T> call){action += call; // 將傳入的回調(diào)添加到 action 上}
}
3、非泛型類 EventInfo
另一個(gè) EventInfo 類用于處理沒有參數(shù)的事件回調(diào)(UnityAction)。這種設(shè)計(jì)使得可以處理不同類型的事件。
private class EventInfo : IEventInfo
{public UnityAction action;public EventInfo(UnityAction call){action += call; // 將傳入的回調(diào)添加到 action 上}
}
4、修改EventManager
事件名稱記得修改一下,不然我們可能很難分出哪個(gè)是帶傳參的,我們可以選擇把這個(gè)參數(shù)的類型的名字也傳進(jìn)去
Dictionary<string, IEventInfo> eventsDictionary = new Dictionary<string, IEventInfo>();/// <summary>
/// 無參數(shù)的事件監(jiān)聽
/// </summary>
/// <param name="EventNameEnum">事件枚舉</param>
/// <param name="action">監(jiān)聽方法</param>
public void AddEventListener(object EventNameEnum, UnityAction call)
{string eventName = GetEnventName(EventNameEnum);if (eventsDictionary.ContainsKey(eventName)){(eventsDictionary[eventName] as EventInfo).action += call;}else{eventsDictionary.Add(eventName, new EventInfo(call));}
}/// <summary>
/// 帶1個(gè)參數(shù)的事件監(jiān)聽
/// </summary>
public void AddEventListener<T>(object EventNameEnum, UnityAction<T> call)
{string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T).Name;if (eventsDictionary.ContainsKey(eventName)){(eventsDictionary[eventName] as EventInfo<T>).action += call;}else{eventsDictionary.Add(eventName, new EventInfo<T>(call));}
}//其他類似
IEventInfo是我們?nèi)藶橹圃斐鰜淼囊粋€(gè)副接口,這樣的話就可以成功把有參數(shù)的事件和無參數(shù)的事件都存到字典里面去了
5、事件監(jiān)聽
Player、Player1、Player2都添加帶一個(gè)參數(shù)的事件監(jiān)聽
public class Player : MonoBehaviour
{private void Start(){EventManager.Instance.AddEventListener(EventNameEnum.Log, Log);EventManager.Instance.AddEventListener<int>(EventNameEnum.AddHealth, AddHealth);}public void Log(){Debug.Log("我是玩家");}public void AddHealth(int health){Debug.Log($"玩家恢復(fù)+{health + 1}血");}
}
6、觸發(fā)事件
測(cè)試觸發(fā)事件
public class EventManagerTest : MonoBehaviour
{private void OnGUI(){if (GUI.Button(new Rect(150, 0, 150, 50), "觸發(fā)帶1個(gè)參數(shù)事件")){EventManager.Instance.Dispatch<int>(EventNameEnum.AddHealth, 1);}if (GUI.Button(new Rect(150, 50, 150, 50), "移除Player帶1個(gè)參數(shù)事件監(jiān)聽")){GameObject go = GameObject.Find("Player");EventManager.Instance.RemoveEventListener<int>(EventNameEnum.AddHealth, go.GetComponent<Player>().AddHealth); }if (GUI.Button(new Rect(150, 100, 150, 50), "移除整個(gè)帶1個(gè)參數(shù)事件")){EventManager.Instance.RemoveEvent<int>(EventNameEnum.AddHealth);}}
}
7、效果
八、傳遞帶有多個(gè)參數(shù)的事件
方法一、自定義類
相當(dāng)于將多個(gè)參數(shù)合并到一個(gè)類里,在傳遞進(jìn)去
比如
public class MyInfo
{public int a;public float b;public double c;
}
調(diào)用
方法二、元組
相當(dāng)于通過元組把多個(gè)參數(shù)合并,傳遞進(jìn)去
方法三、添加帶不同數(shù)量參數(shù)的方法(推薦)
這種辦法雖然最麻煩,但是不會(huì)有性能問題,可以避免下面的問題
1、GC(垃圾回收)
創(chuàng)建元組或自定義類實(shí)例會(huì)導(dǎo)致額外的內(nèi)存分配,從而增加垃圾回收的壓力。在高頻率調(diào)用的場景下,頻繁分配和回收內(nèi)存會(huì)導(dǎo)致性能下降,影響游戲的幀率。
2、裝箱問題
對(duì)于值類型(如 int、struct 等),使用元組或?qū)ο髸r(shí)可能會(huì)導(dǎo)致裝箱和拆箱,增加內(nèi)存開銷和降低性能。這在使用泛型時(shí)尤為明顯,因?yàn)橹殿愋蜁?huì)被包裝為對(duì)象。
3、開銷和復(fù)雜性
封裝多個(gè)參數(shù)在一個(gè)元組或自定義類中,雖然提高了代碼的可讀性,但也增加了開銷,特別是在事件頻繁觸發(fā)的情況下,開銷可能會(huì)顯著。
九、最終代碼
這里我添加最多支持添加4個(gè)參數(shù)的事件,一般都?jí)蛄?#xff0c;如果覺得還是不夠,可以模仿我的方式繼續(xù)添加即可
using System.Collections.Generic;
using UnityEngine.Events;/// <summary>
/// 事件管理器,之所以這么多函數(shù),主要是出于性能考慮,避免產(chǎn)生GC、裝箱問題
/// </summary>
public class EventManager : Singleton<EventManager>
{Dictionary<string, IEventInfo> eventsDictionary = new Dictionary<string, IEventInfo>();/// <summary>/// 獲取事件名稱/// </summary>/// <param name="eventNameEnum">事件枚舉</param>/// <returns>事件名稱</returns>private string GetEnventName(object EventNameEnum){return EventNameEnum.GetType().Name + "_" + EventNameEnum.ToString();}#region 事件監(jiān)聽/// <summary>/// 無參數(shù)的事件監(jiān)聽/// </summary>/// <param name="EventNameEnum">事件枚舉</param>/// <param name="action">監(jiān)聽方法</param>public void AddEventListener(object EventNameEnum, UnityAction call){string eventName = GetEnventName(EventNameEnum);if (eventsDictionary.ContainsKey(eventName)){(eventsDictionary[eventName] as EventInfo).action += call;}else{eventsDictionary.Add(eventName, new EventInfo(call));}}/// <summary>/// 帶1個(gè)參數(shù)的事件監(jiān)聽/// </summary>public void AddEventListener<T>(object EventNameEnum, UnityAction<T> call){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T).Name;if (eventsDictionary.ContainsKey(eventName)){(eventsDictionary[eventName] as EventInfo<T>).action += call;}else{eventsDictionary.Add(eventName, new EventInfo<T>(call));}}/// <summary>/// 帶2個(gè)參數(shù)的事件監(jiān)聽/// </summary>public void AddEventListener<T0, T1>(object EventNameEnum, UnityAction<T0, T1> call){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T0).Name + "_" + typeof(T1).Name;if (eventsDictionary.ContainsKey(eventName)){(eventsDictionary[eventName] as EventInfo<T0, T1>).action += call;}else{eventsDictionary.Add(eventName, new EventInfo<T0, T1>(call));}}/// <summary>/// 帶3個(gè)參數(shù)的事件監(jiān)聽/// </summary>public void AddEventListener<T0, T1, T2>(object EventNameEnum, UnityAction<T0, T1, T2> call){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T0).Name + "_" + typeof(T1).Name + "_" + typeof(T2).Name;if (eventsDictionary.ContainsKey(eventName)){(eventsDictionary[eventName] as EventInfo<T0, T1, T2>).action += call;}else{eventsDictionary.Add(eventName, new EventInfo<T0, T1, T2>(call));}}/// <summary>/// 帶4個(gè)參數(shù)的事件監(jiān)聽/// </summary>public void AddEventListener<T0, T1, T2, T3>(object EventNameEnum, UnityAction<T0, T1, T2, T3> call){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T0).Name + "_" + typeof(T1).Name + "_" + typeof(T2).Name + "_" + typeof(T3).Name;if (eventsDictionary.ContainsKey(eventName)){(eventsDictionary[eventName] as EventInfo<T0, T1, T2, T3>).action += call;}else{eventsDictionary.Add(eventName, new EventInfo<T0, T1, T2, T3>(call));}}#endregion#region 觸發(fā)事件/// <summary>/// 觸發(fā)事件/// </summary>/// <param name="EventNameEnum">事件枚舉</param>public void Dispatch(object EventNameEnum){string eventName = GetEnventName(EventNameEnum);if (eventsDictionary.ContainsKey(eventName)){(eventsDictionary[eventName] as EventInfo).action?.Invoke();}}/// <summary>/// 觸發(fā)帶1個(gè)參數(shù)事件/// </summary>public void Dispatch<T>(object EventNameEnum, T parameter){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T).Name;//如果字典中該事件的名字存在,且該事件不為空,則執(zhí)行該事件,不存在則什么也不做。if (eventsDictionary.ContainsKey(eventName))(eventsDictionary[eventName] as EventInfo<T>).action?.Invoke(parameter);}/// <summary>/// 觸發(fā)帶2個(gè)參數(shù)事件/// </summary>public void Dispatch<T0, T1>(object EventNameEnum, T0 parameter0, T1 parameter1){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T0).Name + "_" + typeof(T1).Name;//如果字典中該事件的名字存在,且該事件不為空,則執(zhí)行該事件,不存在則什么也不做。if (eventsDictionary.ContainsKey(eventName))(eventsDictionary[eventName] as EventInfo<T0, T1>).action?.Invoke(parameter0, parameter1);}/// <summary>/// 觸發(fā)帶3個(gè)參數(shù)事件/// </summary>public void Dispatch<T0, T1, T2>(object EventNameEnum, T0 parameter0, T1 parameter1, T2 parameter2){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T0).Name + "_" + typeof(T1).Name + "_" + typeof(T2).Name;//如果字典中該事件的名字存在,且該事件不為空,則執(zhí)行該事件,不存在則什么也不做。if (eventsDictionary.ContainsKey(eventName))(eventsDictionary[eventName] as EventInfo<T0, T1, T2>).action?.Invoke(parameter0, parameter1, parameter2);}/// <summary>/// 觸發(fā)帶4個(gè)參數(shù)事件/// </summary>public void Dispatch<T0, T1, T2, T3>(object EventNameEnum, T0 parameter0, T1 parameter1, T2 parameter2, T3 parameter3){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T0).Name + "_" + typeof(T1).Name + "_" + typeof(T2).Name + "_" + typeof(T3).Name;//如果字典中該事件的名字存在,且該事件不為空,則執(zhí)行該事件,不存在則什么也不做。if (eventsDictionary.ContainsKey(eventName))(eventsDictionary[eventName] as EventInfo<T0, T1, T2, T3>).action?.Invoke(parameter0, parameter1, parameter2, parameter3);}#endregion#region 移除事件某個(gè)監(jiān)聽方法/// <summary>/// 移除無參數(shù)事件某個(gè)監(jiān)聽方法/// </summary>/// <param name="EventNameEnum">事件枚舉</param>/// <param name="call">監(jiān)聽方法</param>public void RemoveEventListener(object EventNameEnum, UnityAction call){string eventName = GetEnventName(EventNameEnum);if (eventsDictionary.ContainsKey(eventName)){(eventsDictionary[eventName] as EventInfo).action -= call;}}/// <summary>/// 移除帶1個(gè)參數(shù)事件某個(gè)監(jiān)聽方法/// </summary>public void RemoveEventListener<T>(object EventNameEnum, UnityAction<T> call){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T).Name;if (eventsDictionary.ContainsKey(eventName))(eventsDictionary[eventName] as EventInfo<T>).action -= call;}/// <summary>/// 移除帶2個(gè)參數(shù)事件某個(gè)監(jiān)聽方法/// </summary>public void RemoveEventListener<T0, T1>(object EventNameEnum, UnityAction<T0, T1> call){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T0).Name + "_" + typeof(T1).Name;if (eventsDictionary.ContainsKey(eventName))(eventsDictionary[eventName] as EventInfo<T0, T1>).action -= call;}/// <summary>/// 移除帶3個(gè)參數(shù)事件某個(gè)監(jiān)聽方法/// </summary>public void RemoveEventListener<T0, T1, T2>(object EventNameEnum, UnityAction<T0, T1, T2> call){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T0).Name + "_" + typeof(T1).Name + "_" + typeof(T2).Name;if (eventsDictionary.ContainsKey(eventName))(eventsDictionary[eventName] as EventInfo<T0, T1, T2>).action -= call;}/// <summary>/// 移除帶4個(gè)參數(shù)事件某個(gè)監(jiān)聽方法/// </summary>public void RemoveEventListener<T0, T1, T2, T3>(object EventNameEnum, UnityAction<T0, T1, T2, T3> call){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T0).Name + "_" + typeof(T1).Name + "_" + typeof(T2).Name + "_" + typeof(T3).Name;if (eventsDictionary.ContainsKey(eventName))(eventsDictionary[eventName] as EventInfo<T0, T1, T2, T3>).action -= call;}#endregion#region 移除整個(gè)事件/// <summary>/// 移除整個(gè)不帶參數(shù)的事件/// </summary>/// <param name="EventNameEnum">事件枚舉</param>public void RemoveEvent(object EventNameEnum){string eventName = GetEnventName(EventNameEnum);if (eventsDictionary.ContainsKey(eventName)){(eventsDictionary[eventName] as EventInfo).action = null;}}/// <summary>/// 移除整個(gè)帶1個(gè)參數(shù)的事件/// </summary>public void RemoveEvent<T>(object EventNameEnum){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T).Name;//如果字典中存在要移除的命令,則把這個(gè)命令的所有事件移除掉。if (eventsDictionary.ContainsKey(eventName))(eventsDictionary[eventName] as EventInfo<T>).action = null;}/// <summary>/// 移除整個(gè)帶2個(gè)參數(shù)的事件/// </summary>public void RemoveEvent<T0, T1>(object EventNameEnum){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T0).Name + "_" + typeof(T1).Name;//如果字典中存在要移除的命令,則把這個(gè)命令的所有事件移除掉。if (eventsDictionary.ContainsKey(eventName))(eventsDictionary[eventName] as EventInfo<T0, T1>).action = null;}/// <summary>/// 移除整個(gè)帶3個(gè)參數(shù)的事件/// </summary>public void RemoveEvent<T0, T1, T2>(object EventNameEnum){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T0).Name + "_" + typeof(T1).Name + "_" + typeof(T2).Name;//如果字典中存在要移除的命令,則把這個(gè)命令的所有事件移除掉。if (eventsDictionary.ContainsKey(eventName))(eventsDictionary[eventName] as EventInfo<T0, T1, T2>).action = null;}/// <summary>/// 移除整個(gè)帶4個(gè)參數(shù)的事件/// </summary>public void RemoveEvent<T0, T1, T2, T3>(object EventNameEnum){string eventName = GetEnventName(EventNameEnum) + "_" + typeof(T0).Name + "_" + typeof(T1).Name + "_" + typeof(T2).Name + "_" + typeof(T3).Name;//如果字典中存在要移除的命令,則把這個(gè)命令的所有事件移除掉。if (eventsDictionary.ContainsKey(eventName))(eventsDictionary[eventName] as EventInfo<T0, T1, T2, T3>).action = null;}#endregion/// <summary>/// 移除事件中心的所有事件。可以考慮在切換場景時(shí)調(diào)用。/// </summary>public void RemoveAllEvent(){eventsDictionary.Clear();}#region 里氏替換原則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;}}private class EventInfo<T0, T1> : IEventInfo{public UnityAction<T0, T1> action;public EventInfo(UnityAction<T0, T1> call){action += call;}}private class EventInfo<T0, T1, T2> : IEventInfo{public UnityAction<T0, T1, T2> action;public EventInfo(UnityAction<T0, T1, T2> call){action += call;}}private class EventInfo<T0, T1, T2, T3> : IEventInfo{public UnityAction<T0, T1, T2, T3> action;public EventInfo(UnityAction<T0, T1, T2, T3> call){action += call;}}#endregion
}
完結(jié)
贈(zèng)人玫瑰,手有余香!如果文章內(nèi)容對(duì)你有所幫助,請(qǐng)不要吝嗇你的點(diǎn)贊評(píng)論和關(guān)注
,你的每一次支持
都是我不斷創(chuàng)作的最大動(dòng)力。當(dāng)然如果你發(fā)現(xiàn)了文章中存在錯(cuò)誤
或者有更好的解決方法
,也歡迎評(píng)論私信告訴我哦!
好了,我是向宇
,https://xiangyu.blog.csdn.net
一位在小公司默默奮斗的開發(fā)者,閑暇之余,邊學(xué)習(xí)邊記錄分享,站在巨人的肩膀上,通過學(xué)習(xí)前輩們的經(jīng)驗(yàn)總是會(huì)給我很多幫助和啟發(fā)!如果你遇到任何問題,也歡迎你評(píng)論私信或者加群找我, 雖然有些問題我也不一定會(huì),但是我會(huì)查閱各方資料,爭取給出最好的建議,希望可以幫助更多想學(xué)編程的人,共勉~