Unity脚本C#参数互相传递方法整理 可变参数传递 发送消息
今天有人问参数传递的问题。这里就把几个传递参数的方式整理一下。
静态调用传递
顾名思义。这个应该最简单了。就是定义静态变量。静态方法。然后直接 类名.参数 就可以调用。
发送消息
内容Component.SendMessage来实现跨脚本发送消息传递参数。下面发一个整理好的发消息脚本:
代码很简单。大家应该看一下就懂了。
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class NotificationCenter : MonoBehaviour { private static NotificationCenter mInstance; private Hashtable mHashtable; //单例 public static NotificationCenter GetInstance() { if (mInstance == null) { GameObject go = new GameObject("NotificationCenter"); mInstance = go.AddComponent<NotificationCenter>(); } return mInstance; } private NotificationCenter() { mHashtable = new Hashtable(); } public void AddSceneMessage(object observer, string name, object sender) { if (string.IsNullOrEmpty(name)) { Debug.LogError("传入名称错误"); return; } if (mHashtable[name] == null) { mHashtable[name] = new List<object>(); } List<object> listNotify = (List<object>)mHashtable[name]; if (listNotify.Contains(observer) == false) { listNotify.Add(observer); } } public void PostNotification(object aSender, string aName, object aData) { NotificationData ev = new NotificationData(aSender, aName, aData); if (string.IsNullOrEmpty(ev.name)) { return; } List<object> listNotify = (List<object>)mHashtable[ev.name]; if (listNotify != null) { List<object> listRemoveObserver = new List<object>(); for (int i = 0; i < listNotify.Count; i++) { object ob = listNotify[i]; MonoBehaviour observer = (MonoBehaviour)ob; if (!observer) { listRemoveObserver.Add(ob); } else { observer.SendMessage(ev.name, ev, SendMessageOptions.DontRequireReceiver); } } for (int i = 0; i < listRemoveObserver.Count; i++) { object ob = listRemoveObserver[i]; listNotify.Remove(ob); } } } } public class NotificationData { public object sender; public string name; public object data; public NotificationData(object aSender, string aName, object aData) { sender = aSender; name = aName; data = aData; } }
用时。先注册下要发送到那个脚本,示例如下:
using UnityEngine; using System.Collections; public class N2 : MonoBehaviour { void Start () { Debug.Log("n2 Start"); //注册消息 NotificationCenter.GetInstance().AddSceneMessage(this, "N2Test", null); //发送消息 NotificationCenter.GetInstance().PostNotification(this, "N21Test", "是N2调用的"); } void N2Test(NotificationData ev) { Debug.Log("调用了N2---"+(int)ev.data); } }
using UnityEngine; using System.Collections; public class N21 : MonoBehaviour { // Use this for initialization void Start () { NotificationCenter.GetInstance().AddSceneMessage(this, "N21Test", null); } void N21Test(NotificationData ev) { Debug.Log("调用了N21---内容:"+(string)ev.data); NotificationCenter.GetInstance().PostNotification(this, "N2Test", 111); } }
如上两个测试脚本。互相传递参数。有N2发消息到N21。然后N21在次发送到N2。 由于传递的是object。所以。可以发送任意类型的参数。
结果图:
委托
用delegate回调。如下。
using UnityEngine; using System.Collections; public class N3 : MonoBehaviour { void Start () { Debug.Log("N3 start"); N31.GetInstance().onPostData = N3Test; N31.GetInstance().N31Test(); } void N3Test(object data) { Debug.Log("N3 回调内容:" + (string)data); } }
using UnityEngine; using System.Collections; public class N31 : MonoBehaviour { private static N31 mInstance; //单例 public static N31 GetInstance() { if (mInstance == null) { GameObject go = new GameObject("N31"); mInstance = go.AddComponent<N31>(); } return mInstance; } public delegate void OnPostData(object data); public OnPostData onPostData; public void N31Test() { Debug.Log("N31"); this.onPostData("222"); } }
结果: