Unity 编辑器-创建模板脚本,并自动绑定属性,添加点击事件

这篇具有很好参考价值的文章主要介绍了Unity 编辑器-创建模板脚本,并自动绑定属性,添加点击事件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

当使用框架开发时,Prefab挂载的很多脚本都有固定的格式。从Unity的基础模板创建cs文件,再修改到应有的模板,会浪费一些时间。尤其是有大量的不同界面时,每个都改一遍,浪费时间不说,还有可能遗漏或错改。写个脚本创建指定的模板代替C#基础模板。

注:当前脚本使用的NGUI,使用UGUI时替换对应的Component即可

代码
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;

public class MediatorScriptCreator
{
    private const string MenuItemText1 = "Assets/Create/模板脚本/创建Mediator模板脚本";
    private const string MenuItemText3 = "Assets/Create/模板脚本/添加Mediator模板脚本";
    [MenuItem(MenuItemText1, false, 25)]
    public static void CreateScript()
    {
        CreateScript(false);
    }
   
    
    [MenuItem(MenuItemText3, false, 25)]
    public static void AddScript()
    {
        AddComp();
    }
    
    private static List<GameObject> _nodeList;
    private static List<UISprite> _imgList;
    private static List<UIButton> _btnList;
    private static List<UILabel> _labelList;
    private static List<UISlider> _sliderList;

    private static void CreateScript(bool isPartial)
    {

        var assetPath = AssetDatabase.GetAssetPath(Selection.activeObject);
        var directoryPath = System.IO.Path.GetDirectoryName(assetPath);
        var folderName = System.IO.Path.GetFileName(directoryPath);
        var folderPath = $"Assets/Game/GameLogic/{folderName}";
        if (!Directory.Exists(folderPath))
        {
            if (directoryPath != null) Directory.CreateDirectory(folderPath);
        }

        var scriptPath = $"{folderPath}/{Selection.activeObject.name}Mediator.cs";
        if (File.Exists(scriptPath))
        {
            Debug.LogError($"The script \"{scriptPath}\" already exists.");
            return;
        }

        var myPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
        // 获取 Prefab 的所有子对象
        GetNodeData(myPrefab);

        var txt = $@"using UnityEngine;
namespace PD
{{
    public {(isPartial ? "partial" : "")} class {Selection.activeObject.name}Mediator : NGuiFormMasterLogic
    {{
        public override string FacadeName
        {{
            get {{ return HomeFacade.Name; }}//TODO:修改FacadeName
        }}

        public new const string NAME = {$"\"{Selection.activeObject.name}Mediator\""};

        public override void OnConstruct(object userData)
        {{
            base.OnConstruct(userData);
            MediatorName = NAME;
        }}
";
        var txtEnd = $@"
    }}
}}";
        for (var i = 0; i < _nodeList.Count; i++)
        {
            var name = _nodeList[i].name[2..];
            name = name[..1].ToUpper() + name[1..];
            var str = $@"
        [SerializeField] private GameObject {name};
";
            txt += str;
        }

        for (var i = 0; i < _imgList.Count; i++)
        {
            var name = _imgList[i].name[2..];
            name = name[..1].ToUpper() + name[1..];
            var str = $@"
        [SerializeField] private UISprite {name};
";
            txt += str;
        }

        for (var i = 0; i < _labelList.Count; i++)
        {
            var name = _labelList[i].name[2..];
            name = name[..1].ToUpper() + name[1..];
            var str = $@"
        [SerializeField] private UILabel {name};
";
            txt += str;
        }

        for (var i = 0; i < _btnList.Count; i++)
        {
            var name = _btnList[i].name[2..];
            name = name[..1].ToUpper() + name[1..];
            var str = $@"
        [SerializeField] private UIButton {name};
";
            txt += str;
        }

        for (var i = 0; i < _sliderList.Count; i++)
        {
            var name = _sliderList[i].name[2..];
            name = name[..1].ToUpper() + name[1..];
            var str = $@"
        [SerializeField] private UISlider {name};
";
            txt += str;
        }

        for (var i = 0; i < _btnList.Count; i++)
        {
            var name = _btnList[i].name[2..];
            name = name[..1].ToUpper() + name[1..];
            var str = $@"


        public void On{name}Click()
        {{
           
        }}

";
            txt += str;
        }


        txt += txtEnd;
        EditorPrefs.SetString("creatorPath", assetPath);
        EditorPrefs.SetString("creatorName", myPrefab.name);
        EditorPrefs.SetString("creatorScriptPath", scriptPath);
        File.WriteAllText(scriptPath, txt);
        AssetDatabase.Refresh();
    }

    public static void AddComp()
    {
        var scriptName = EditorPrefs.GetString("creatorName");
        string[] guids = AssetDatabase.FindAssets(scriptName);

        if (guids.Length > 0)
        {
            var assetPath = EditorPrefs.GetString("creatorPath");
            string path = AssetDatabase.GUIDToAssetPath(guids[0]);
            MonoScript monoScript = AssetDatabase.LoadAssetAtPath<MonoScript>(path);
            System.Type type = monoScript.GetClass();
            var prefab =
                GameObject.Instantiate(
                    AssetDatabase
                        .LoadMainAssetAtPath(
                            assetPath)) as GameObject; // PrefabUtility.LoadPrefabContents(assetPath);//
            var component = prefab.AddComponent(type);
            // 获取所有字段
            var fields = type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
            var list = prefab.GetComponentsInChildren<Transform>(true).Where(a => a.name.StartsWith("m_")).ToList();

            foreach (FieldInfo field in fields)
            {
                // 判断字段是否被序列化
                var attributes = field.GetCustomAttributes(typeof(SerializeField), false);
                if (attributes.Length > 0)
                {
                    var temp = field.Name + "";
                    var name = temp[..1].ToLower() + temp[1..];
                    var go = list.FirstOrDefault(a => a.name == $"m_{name}");
                    if (go != null)
                    {
                        list.Remove(go);
                        var btn = go.GetComponent<UIButton>();
                        var slider = go.GetComponent<UISlider>();
                        var img = go.GetComponent<UISprite>();
                        var txt = go.GetComponent<UILabel>();
                        if (btn != null)
                        {
                            var str = $"On{field.Name}Click";
                            Debug.Log(str);
                            var delegateFunc1 = new EventDelegate(component as MonoBehaviour, str);
                            btn.onClick.Add(delegateFunc1);
                            field.SetValue(component, btn);
                        }
                        else if (slider != null)
                        {
                            field.SetValue(component, slider);
                        }
                        else if (img != null)
                        {
                            field.SetValue(component, img);
                        }
                        else if (txt != null)
                        {
                            field.SetValue(component, txt);
                        }
                        else
                        {
                            field.SetValue(component, go.gameObject);
                        }
                    }
                }
            }

            // GetNodeData(prefab);
            // PrefabUtility.SaveAsPrefabAssetAndConnect(prefab, assetPath);
            PrefabUtility.SaveAsPrefabAssetAndConnect(prefab, assetPath, InteractionMode.AutomatedAction);
            Object.DestroyImmediate(prefab);
            AssetDatabase.Refresh();
        }
        else
        {
            Debug.LogError($"请先生成脚本");
        }
    }
    [MenuItem(MenuItemText1, true)]
    public static bool CreatorNormal()
    {
        if (!Selection.activeObject) return false;
        var prefabAssetType = PrefabUtility.GetPrefabAssetType(Selection.activeObject);
        return prefabAssetType != PrefabAssetType.NotAPrefab;

    }
    
    [MenuItem(MenuItemText3, true)]
    public static bool AddScript1()
    {
        if (!Selection.activeObject) return false;
        var prefabAssetType = PrefabUtility.GetPrefabAssetType(Selection.activeObject);
        return prefabAssetType != PrefabAssetType.NotAPrefab;

    }
    private static void GetNodeData(GameObject prefab)
    {
        Transform[] nodes = prefab.GetComponentsInChildren<Transform>(true);
        _nodeList = new List<GameObject>();
        _imgList = new List<UISprite>();
        _labelList = new List<UILabel>();
        _btnList = new List<UIButton>();
        _sliderList = new List<UISlider>();                                                                                              
        // 遍历所有子对象
        foreach (var node in nodes)
        {
            if (!node.gameObject.name.StartsWith("m_")) continue;
            var btn = node.GetComponent<UIButton>();
            var img = node.GetComponent<UISprite>();
            var label = node.GetComponent<UILabel>();
            var slider = node.GetComponent<UISlider>();
            if (btn != null)
            {
                _btnList.Add(btn);
            }
            else if (slider != null)
            {
                _sliderList.Add(slider);
            }
            else if (img != null)
            {
                _imgList.Add(img);
            }
            else if (label != null)
            {
                _labelList.Add(label);
            }
            else
            {
                _nodeList.Add(node.gameObject);
            }
        }
    }
}



使用方法
Unity 编辑器-创建模板脚本,并自动绑定属性,添加点击事件,unity,编辑器,游戏引擎
知识点

1.字符串使用@前缀,可以不使用\n换行。和$搭配使用时,字符串中如果有 { 需要用 {{ 两个大括号表示,第一个为转义。 字符串中有 ” 时,需要使用反斜杠 " 转义
2.判断物体是不是Prefab,PrefabUtility.GetPrefabAssetType(Selection.activeObject) != PrefabAssetType.NotAPrefab;
3.[MenuItem(MenuItemText2, true)] 第二个参数 bool值表示是否显示本扩展方法
4.获取指定脚本所有的Pulbic[SerializeField]的属性: type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)文章来源地址https://www.toymoban.com/news/detail-545607.html

到了这里,关于Unity 编辑器-创建模板脚本,并自动绑定属性,添加点击事件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Unity3D】Unity 脚本 ② ( Visual Studio 2019 中的 Unity 编译环境配置 | Unity 编辑器关联外部 C# 脚本编辑器 Visual Studio )

    在上一篇博客 【Unity3D】Unity 脚本 ① ( 创建 C# 脚本 | Visual Studio 2019 中打开 C# 脚本 | 编译 C# 脚本 | 挂载 C# 脚本到游戏物体 | 运行脚本 ) 中 , 双击 Unity 编辑器中的 Project 窗口中的 C# 脚本 , 进入到 Visual Studio 中出现下图样式 , 这是因为没有配置 Unity 编译环境 ; 参考如下两个博

    2023年04月08日
    浏览(42)
  • 编辑器脚本:Unity中如何查找哪些物体上有missing的脚本

    编辑器中选中物体,判断这些物体及子物体上是否有丢失的脚本 1、编辑器选中n个物体 2、获取这n个物体及其它们的子物体,数据集记为A 3、A中全部物体判断他们是否有null的脚本(MonoBehaviour) 4、判断一个物体(obj)是否有空脚本的关键语句: obj.GetComponentsMonoBehaviour().Any(mon

    2024年02月14日
    浏览(32)
  • Unity快手上手【熟悉unity编辑器,C#脚本控制组件一些属性之类的】

    首先了解unity相关概述,快速认识unity编辑器,然后抓住重点的学:游戏对象、组件|C#脚本、预制体、UI ☺ 学习过程你会发现,其实Unity中主要是用c#进行开发。 因为在这个过程中,无非就是,对游戏对象通过挂载的C#脚本,修改一下组件的一些属性,控制一下激活之类的操作

    2023年04月13日
    浏览(44)
  • Unity编辑器扩展-第六集-创建窗口/批量填图

    第五集链接:Unity编辑器扩展-第五集-撤回操作/禁止操作/加快捷键_菌菌巧乐兹的博客-CSDN博客 一、本节目标+效果展示 1.创建窗口 2.图片批量赋值到物体上 二、创建窗口  这个功能其实也很好理解,我们之前学了点击选择,但 我们难免会遇见需要选不同位置,不同种类的很多

    2024年02月10日
    浏览(30)
  • 【Unity编辑器】使用AssetDatabase创建、删、改、加载资源

    AssetDatabase是Unity编辑器环境下的一种API,主要用于在代码中对项目中的资源进行管理和操作。注意:AssetDatabase的这些方法只能在Unity编辑器环境下运行,不能在构建后的游戏中使用。在游戏运行时,你需要使用其他资源加载方法,如Resources.Load、AssetBundle加载或者Addressables等。

    2024年01月21日
    浏览(35)
  • 【Unity编辑器扩展】语言国际化工具,生成多语言Excel自动翻译并导出多语言表

     多语言是个非常简单且常用的功能。但是重复工作量大,程序手动把多语言Key配置到多语言表经常会出现错漏,或者几经改版,有些Key已经不用却没有剔除,久而久之造成冗余。这中简单且重复的工作必须让工具来完成。 多语言通过Key,Value的形式保存,通过多语言API GF.

    2024年02月11日
    浏览(44)
  • Unity 制作旋转门 推拉门 柜门 抽屉 点击自动开门效果 开关门自动播放音效 (附带编辑器扩展代码)

    对于一个新手来说,这个工具是最好的选择 上一篇关于开关门的文章相对于复杂,感兴趣的可以查看上篇开关门制作 优点 挂载就能使用 控制面板一看就懂(全是中文) 简单的调试就能获得自己想要的效果 易懂且易修改的代码 面板 参数 锁:勾选后不能对门进行操作 声音:激活时自

    2023年04月24日
    浏览(69)
  • cocos creator 如何绑定参数到编辑器

    很多cocos creator同学不知道如何绑定组件属性到编辑器上,今天我们来教大家如何绑定 1: 基本数据属性绑定到编辑器    这个非常简单,模板是属性名字: 默认的值; Is_debug: false, speed: 100, 2: 系统组件类型与节点绑定到编辑器 属性名字: {    type: 组件类型(cc.Sprite, cc.Label,

    2024年01月23日
    浏览(37)
  • EMR电子病历系统 SaaS电子病历编辑器源码 电子病历模板编辑器

    EMR(Electronic Medical Record)指的是电子病历。它是一种基于电子文档的个人医疗记录,可以包括病人的病史、诊断、治疗方案、药物处方、检查报告和护理计划等信息。EMR采用计算机化的方式来存储、管理和共享这些信息,以便医生和医疗团队更快速、准确地了解病人的病情,

    2024年02月11日
    浏览(31)
  • Vue + 富文本编辑器:打印模板设计

    前言: 有的项目需要用到打印,如果只有少数的地方需要用到打印,一般只需要固定模板进行打印就行了,但是我们的项目总是与众不同,明明只要固定模板就可以完成需求的,非要添加一个灵活的打印模板,而且还涉及到拖拉填充文本,真是脑细胞不知道死掉了多少! ! !

    2024年02月09日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包