一个自己思索很长时间的功能

  一开始做项目的时候,涉及NGUI特别多,项目中需要非常多的Button以及和它对应的事件,通常的实现方式都是下面这种情况:

 1 private void BtnClickHandler(GameObject go)
 2     {
 3         switch (go.name)
 4         {
 5             case "regist":
 6                 RegistUser();
 7                 break;
 8             case "forgetPwd":
 9                 ForGetPassWord();
10                 break;
11             case "submit":
12                 DoLogin();
13                 break;
14             case "exit":
15                 QuitApp();
16                 break;
17             case "NoRegistLogin":
18                 PublicVals.IsRegistUser = false;
19                 LoadScene("SeleMode");
20                 break;
21         }
22     }

  我吧,很不喜欢这种判断方式,当然这不代表我下面实现的功能,比这个要好或者要方便,只是单纯我个人想去这么实现而已。NGUI的Button自带了一个功能On Click,我有很多同事也用这种方式来实现按钮和事件的关联,我也比较喜欢这个功能,但是我想把所有Button放到一个脚本下管理或者说放到一个Inspector下管理( 什么样的值会被显示在Inspector面板上?已经被序列化,但是没有用HideInInspector标记的值。),去阅读一下NGUI的源代码发现所有这样的事件功能都是通过public List<EventDelegate> onSubmit = new List<EventDelegate>()这样的方式来定义的,通过下面的方法来进行调用的。

    public void Submit ()
    {
        if (NGUITools.GetActive(this))
        {
            mValue = value;

            if (current == null)
            {
                current = this;
                EventDelegate.Execute(onSubmit);
                current = null;
            }
            SaveToPlayerPrefs(mValue);
        }
    }

  方法名的获取是通过反射的方式,在EventDelegateEditor这个类中实现的,具体方法如下

  

 1 static public List<Entry> GetMethods (GameObject target)
 2     {
 3         MonoBehaviour[] comps = target.GetComponents<MonoBehaviour>();
 4 
 5         List<Entry> list = new List<Entry>();
 6 
 7         for (int i = 0, imax = comps.Length; i < imax; ++i)
 8         {
 9             MonoBehaviour mb = comps[i];
10             if (mb == null) continue;
11 
12             MethodInfo[] methods = mb.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public);
13 
14             for (int b = 0; b < methods.Length; ++b)
15             {
16                 MethodInfo mi = methods[b];
17 
18                 if (mi.ReturnType == typeof(void))
19                 {
20                     string name = mi.Name;
21                     if (name == "Invoke") continue;
22                     if (name == "InvokeRepeating") continue;
23                     if (name == "CancelInvoke") continue;
24                     if (name == "StopCoroutine") continue;
25                     if (name == "StopAllCoroutines") continue;
26                     if (name == "BroadcastMessage") continue;
27                     if (name.StartsWith("SendMessage")) continue;
28                     if (name.StartsWith("set_")) continue;
29 
30                     Entry ent = new Entry();
31                     ent.target = mb;
32                     ent.name = mi.Name;
33                     list.Add(ent);
34                 }
35             }
36         }
37         return list;
38     }

 这样我们就获得方法名了,然后通过编辑Inspector来实现想要的界面效果,具体代码如下:

public override void OnInspectorGUI()
    {
        monoscript.Update();
        EditorGUILayout.PropertyField(connectionPool);
        if (connectionPool.isExpanded)
        {
            EditorGUI.indentLevel += 1;
            EditorGUILayout.PropertyField(connectionPool.FindPropertyRelative("script"));
            ButtonEvent scripttarget = (ButtonEvent)target;
            string[] names;
            string[] tnames={"Please insert script"};
            if (scripttarget.connectionPool.script != null)
            {
                List<string> temp = GetMethods(scripttarget.connectionPool.script);
                names = temp.ToArray();
            }
            else
            {
                names = null;
            }
            SerializedProperty list = connectionPool.FindPropertyRelative("buttonConnection");
            EditorGUILayout.PropertyField(list);
            if (list.isExpanded)
            {
                EditorGUI.indentLevel += 1;
                EditorGUILayout.PropertyField(list.FindPropertyRelative("Array.size"));
                if (list.arraySize > 0)
                {
                    for (int i = 0; i < list.arraySize; i++)
                    {

                        SerializedProperty mlist = list.GetArrayElementAtIndex(i);
                        EditorGUILayout.PropertyField(mlist,new GUIContent("BE"+i));
                        if (mlist.isExpanded)
                        {
                            EditorGUI.indentLevel += 1;
                            EditorGUILayout.PropertyField(mlist.FindPropertyRelative("button"));
                            if (scripttarget.connectionPool.buttonConnection.Length >= list.arraySize)
                            {
                                if (names != null)
                                {
                                    scripttarget.connectionPool.buttonConnection[i].indexNum = EditorGUILayout.Popup("Method", scripttarget.connectionPool.buttonConnection[i].indexNum, names);
                                    scripttarget.connectionPool.buttonConnection[i].methodName = names[scripttarget.connectionPool.buttonConnection[i].indexNum];
                                }
                                else
                                {
                                    scripttarget.connectionPool.buttonConnection[i].indexNum = EditorGUILayout.Popup("Method", scripttarget.connectionPool.buttonConnection[i].indexNum, tnames);
                                    scripttarget.connectionPool.buttonConnection[i].methodName = tnames[scripttarget.connectionPool.buttonConnection[i].indexNum];                               
                                }
                            }
                            else
                            {
                                if (names != null)
                                    EditorGUILayout.Popup("Method", 0, names);
                                else
                                    EditorGUILayout.Popup("Method", 0, tnames);
                            }
                            //EditorGUILayout.PropertyField(mlist.FindPropertyRelative("methodName"));
                            EditorGUI.indentLevel -= 1;
                        }

                    }
                }
            }

        }
        monoscript.ApplyModifiedProperties();
    }

最后实现的效果如图

 

  将事件代码拖入Script,在ButtonConnection中Button拖入对应button,method里面选择方法后,点击Button调用事件。

  这个功能看起来有些本末倒置,只是在我个人强迫症的驱使下完成的,谢谢。

转载于:https://www.cnblogs.com/kyo950/p/5230949.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值