Unity Ngui 按钮事件代码自动添加

        写代码写的时间长了,会经常写一些重复的东西,这些代码枯燥,乏味,浪费时间,没什么营养。想着能不能用一些工具帮我自动生成。想了半天,终于有了自己想要的效果。

这项工程的源代码,供大家进行下载参考:

https://download.csdn.net/download/liulei199079/10745835

先看看操作

等编译完了,然后执行如下操作

看,从事件注册到字段序列化,点两下就可以自动完成。是不是很方便。另外还同时支持事件的删除。

实现思路:

1:获取相关的脚本

Type type = GetType(FindGenerateCodeScript(obj.transform));
MonoBehaviour monoBehaviour = obj.GetComponentInParent(type) as MonoBehaviour;
MonoScript monoScript = MonoScript.FromMonoBehaviour(monoBehaviour);

2:对该脚本进行格式化

static string AutoFormatCode(string orignal_code,bool is_contain_namespace)
        {
            string common_tab_char = is_contain_namespace ? "\t\t" : "\t";
            if (!orignal_code.Contains(AutoCSharpConfig.auto_generate_code_split_start))
            {
                if(!orignal_code.StartsWith("#if UNITY_EDITOR"))
                {
                    if(!orignal_code.Contains("using Newtonsoft.Json;"))
                    {
                        orignal_code = "using Newtonsoft.Json;\n"+orignal_code;
                    }
                    if(!orignal_code.Contains("using System.Reflection;"))
                    {
                        orignal_code = "using System.Reflection;\n"+orignal_code;
                    }
                    if(!orignal_code.Contains("using UnityEngine;"))
                    {
                        orignal_code = "using UnityEngine;\n" + orignal_code;
                    }
                    if(!orignal_code.Contains("using System;"))
                    {
                        orignal_code = "using System;" + orignal_code;
                    }
                    if(!orignal_code.Contains("using System.Collections.Generic;"))
                    {
                        orignal_code = "using System.Collections.Generic;" + orignal_code;
                    }
                    orignal_code = "#if UNITY_EDITOR\nusing UnityEditor;\n#endif\n"+orignal_code;
                }

                orignal_code = orignal_code.Remove(orignal_code.LastIndexOf('}'));
                if (is_contain_namespace)
                {
                    orignal_code = orignal_code.Remove(orignal_code.LastIndexOf('}'));
                }
                if(!orignal_code.Contains("void Awake()"))//注入Awake方法
                {
                    foreach(string s in AutoCSharpConfig.auto_generate_code_awake_func_codes_model)
                    {
                        orignal_code += "\n" + common_tab_char + s;
                    }
                }
                foreach (string s in AutoCSharpConfig.auto_generate_codes)
                {
                    orignal_code += "\n" + common_tab_char + s;
                }
                //orignal_code += "\n"+common_tab_char + AutoCSharpConfig.auto_generate_code_split_start + "\n"+common_tab_char + AutoCSharpConfig.auto_region_start + "\n"+common_tab_char + AutoCSharpConfig.auto_region_end + "\n"+common_tab_char + AutoCSharpConfig.auto_generate_code_split_end +"\n\t"+ "}";
                if (is_contain_namespace)
                {
                    orignal_code += "\n\t" + "}";
                }
                orignal_code += "\n}";

                if (!orignal_code.Contains(AutoCSharpConfig.auto_generate_code_register_func_start))
                {
                    orignal_code = orignal_code.Replace(AutoCSharpConfig.auto_generate_code_event_func_start, AutoCSharpConfig.auto_generate_code_event_func_start + "\n" + common_tab_char + GetRegisterCode(is_contain_namespace));
                }
                if(!orignal_code.Contains(AutoCSharpConfig.auto_generate_code_serialized_field_codes_model[0]))
                {
                    string serialzed_field_code = string.Empty;
                    foreach (string s in AutoCSharpConfig.auto_generate_code_serialized_field_codes_model)
                    {
                        //if(s == AutoCSharpConfig.auto_generate_code_serialized_field_codes_model[0])
                        //{
                        //    serialzed_field_code += s;
                        //}
                        //else
                        //{
                        serialzed_field_code += "\n" + common_tab_char + s;
                        //}
                    }
                    orignal_code = orignal_code.Replace(AutoCSharpConfig.auto_generate_code_event_func_end, AutoCSharpConfig.auto_generate_code_event_func_end + serialzed_field_code);
                }
            }
            if (!orignal_code.Contains(AutoCSharpConfig.auto_generate_code_init_awake_func_model))//往Awake注入 初始化方法
            {
                string[] split_str = orignal_code.Split(new string[] { "void Awake()" }, StringSplitOptions.RemoveEmptyEntries);
                orignal_code = split_str[0].TrimEnd() + " void Awake()" + "\n" + common_tab_char + "{\n\t" + common_tab_char + AutoCSharpConfig.auto_generate_code_init_awake_func_model + split_str[1].TrimStart().Remove(0, 1);
            }
            return orignal_code;
        }

3:然后对该脚本代码进行修改

[MenuItem("GameObject/LazerSelect/AddPressEvent", false, 0)]
        [MenuItem("LazerSelect/CSharp/AddPressEvent")]
        static private void AddGameObjectPressEvent()
        {
            GameObject obj = Selection.gameObjects[0];
            //Debug.Log(MonoScript.FromMonoBehaviour(obj.GetComponentInParent<FatherScript>()).text);
            Type type = GetType(FindGenerateCodeScript(obj.transform));
            MonoBehaviour monoBehaviour = obj.GetComponentInParent(type) as MonoBehaviour;//obj.GetComponentInParent<FatherScript>();
            MonoScript monoScript = MonoScript.FromMonoBehaviour(monoBehaviour);
            //添加字段
            string orignal_code = monoScript.text;
            bool is_contain_namespace = orignal_code.Contains("namespace");
            string common_tab_char = is_contain_namespace ? "\t\t" : "\t";
            //添加自动生成代码区域标记
            orignal_code = AutoFormatCode(orignal_code, is_contain_namespace);
            //生成字段
            string private_field_code = string.Format(AutoCSharpConfig.auto_generate_code_filed_model, obj.name, JsonConvert.SerializeObject(new { name = "m_" + obj.name, path = GetPath(obj.transform, monoBehaviour.transform) }));
            if (!orignal_code.Contains(private_field_code))
            {
                orignal_code = orignal_code.Replace(AutoCSharpConfig.auto_generate_code_field_end, private_field_code + "\n" + common_tab_char + AutoCSharpConfig.auto_generate_code_field_end);
            }
            //生成方法
            if (!orignal_code.Contains(string.Format("private void on_{0}_button_press(GameObject obj,bool pressed)", obj.name)))
            {
                string event_func_code = GetPressFuncCode(obj.name, is_contain_namespace);
                orignal_code = orignal_code.Replace(AutoCSharpConfig.auto_generate_code_event_func_end, event_func_code + "\n" + common_tab_char + AutoCSharpConfig.auto_generate_code_event_func_end);
            }
            //注册方法
            string register_click_code = string.Format(AutoCSharpConfig.auto_generate_code_register_onpress_func_model, obj.name);
            if (!orignal_code.Contains(register_click_code))
            {
                orignal_code = orignal_code.Replace(AutoCSharpConfig.auto_generate_code_register_func_end, register_click_code + "\n\t" + common_tab_char + AutoCSharpConfig.auto_generate_code_register_func_end);
            }
            string path = AssetDatabase.GetAssetPath(monoScript);
            File.WriteAllText(System.IO.Path.GetFullPath(path), orignal_code, System.Text.Encoding.UTF8);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
            monoBehaviour = obj.GetComponentInParent(type) as MonoBehaviour;
            //UnityEditor.EditorUtility.SetDirty(monoBehaviour.gameObject);
            //monoBehaviour.GetType().InvokeMember("m_" + obj.name, BindingFlags.SetField | BindingFlags.Instance | BindingFlags.NonPublic, null, monoBehaviour, new object[] { obj }, null, null, null);
        }

这些操作本质上就是对修改的脚本进行文本编辑,目前还没有找到像vs那样提供丰富的加接口,删接口那样高度自动化的方法。

但使用这些方法已经完全可以对脚本进行无缝的编辑了。

我提供了注册该脚本的相关模板,方便大家在此基础上修改

public class AutoCSharpConfig
{
    public static readonly List<string> auto_generate_codes = new List<string>()
        {
            "/*************************auto generate code start***********************/",
            "#region auto generate code",
            "/*************************auto generate code field start***********************/",
            "/*************************auto generate code field end***********************/",
            auto_generate_code_event_func_start,
            auto_generate_code_event_func_end,
            "#endregion",
            "/*************************auto generate code end***********************/",
        };
    //自动生成代码起始
    public const string auto_generate_code_split_start = "/*************************auto generate code start***********************/";
    public const string auto_region_start = "#region auto generate code";
    public const string auto_generate_code_field_start = "/*************************auto generate code field start***********************/";
    public const string auto_generate_code_field_end = "/*************************auto generate code field end***********************/";
    public const string auto_generate_code_event_func_start = "/*************************auto generate code event func start***********************/";
    public const string auto_generate_code_event_func_end = "/*************************auto generate code event func end***********************/";
    public const string auto_generate_code_register_func_start = "/*************************auto generate code register func start***********************/";
    public const string auto_generate_code_register_func_end = "/*************************auto generate code register func end***********************/";
    public const string auto_region_end = "#endregion";
    //public const string auto_generate_code_serialized_field_config_json_start = "/*************************auto generate code serialized field config json start***********************/";
    //public const string auto_generate_code_serialized_field_config_json_end = "/*************************auto generate code serialized field config json end***********************/";
    //自动生成代码结束
    public const string auto_generate_code_split_end = "/*************************auto generate code end***********************/";
    public const string auto_generate_code_filed_model = "[SerializeField] private GameObject m_{0};//{1}[-]";
    public const string auto_generate_code_register_onclick_func_model = "UIEventListener.Get(m_{0}).onClick = on_{0}_button_click;";
    public const string auto_generate_code_register_onpress_func_model = "UIEventListener.Get(m_{0}).onPress = on_{0}_button_press;";
    public const string auto_generate_code_click_func_flag_start_model = "//---------------------function :{0} click func start---------------";
    public const string auto_generate_code_click_func_flag_end_model = "//---------------------function :{0} click func end---------------";
    public const string auto_generate_code_press_func_flag_start_model = "//---------------------function :{0} press func start---------------";
    public const string auto_generate_code_press_func_flag_end_model = "//---------------------function :{0} press func end---------------";
    public const string auto_generate_code_init_awake_func_model = "RegisterButtonEvent();";
    public static List<string> auto_generate_code_awake_func_codes_model = new List<string>()
    {
        "//此方法不能删掉",
        "private void Awake()",
        "{",
        "\t"+auto_generate_code_init_awake_func_model,
        "}",
    };
    public static List<string> auto_generate_code_serialized_field_codes_model = new List<string>(){
"/*************************auto generate code serialized field start***********************/",
"#if UNITY_EDITOR",
        "[ContextMenu(\"序列化字段\")]",
        "private void AutoSerializedField()",
        "{",
            "\tEditorUtility.SetDirty(this);",
            "\tMonoBehaviour monoBehaviour = this;",
            "\tMonoScript monoScript = MonoScript.FromMonoBehaviour(monoBehaviour);",
            "\tstring orignal_code = monoScript.text.Split(new string[] { AutoCSharpConfig.auto_generate_code_field_start, AutoCSharpConfig.auto_generate_code_field_end }, StringSplitOptions.RemoveEmptyEntries)[1];",
            "\tstring[] codes = orignal_code.Split(new string[] { \"//\", \"[-]\" }, StringSplitOptions.RemoveEmptyEntries);",
            "\tfor (int i = 0; i < codes.Length; i++)",
            "\t{",
                "\t\tif (codes[i].Contains(\"\\\"path\\\":\"))",
                "\t\t{",
                    "\t\t\tDictionary<string, string> dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(codes[i]);",
                    "\t\t\tmonoBehaviour.GetType().InvokeMember(dict[\"name\"], BindingFlags.SetField | BindingFlags.Instance | BindingFlags.NonPublic, null, monoBehaviour, new object[] { monoBehaviour.transform.Find(dict[\"path\"]).gameObject }, null, null, null);",
                "\t\t}",
            "\t}",
            "\tEditorUtility.SetDirty(this);",
        "}",
"#endif",
"/*************************auto generate code serialized field end***********************/",
        };
}

猜你喜欢

转载自blog.csdn.net/liulei199079/article/details/83412555