美文网首页unityunity3D技术分享Unity乱七八糟技巧
【UGUI】组件创建时添加指定脚本

【UGUI】组件创建时添加指定脚本

作者: 技术宅_志远 | 来源:发表于2018-10-30 01:37 被阅读116次

    0x001 需求

    当UGUI的某些组件 如:Text Button 创建的时候,自动为该组件添加指定的脚本。

    0x002 分析

    解决办法:我们可以为 RectTransform 编写编辑器扩展,因为只要是UGUI组件肯定会有 RectTransform 的。

    0x003 实现步骤

    1. 实现编辑器脚本 AutoAddScript.cs

    第一想到的是我能不能直接集成RectTransformEditor ----- 答案是不能的(访问级别问题)。
    其次想到可不可以直接集成Editor ----- 答案是可以,但是会破坏原有的Inspector样式。
    那么结合上文分析我给出最佳实现方案,套用momo大神文章在不影响原有布局的前提下。

    • 首先我们要去文章处把DecoratorEditor这个类copy回来。
    • 然后新建一个AutoAddScript类继承自DecoratorEditor
    • 实现空构造函数并且base("RectTransformEditor")
    • 书写OnEnable方法 在方法内部实现我们的监控
    using UnityEditor;
    [CustomEditor(typeof(RectTransform))]
    public class AutoAddScript : DecoratorEditor
    {
        public AutoAddScript() : base("RectTransformEditor") { }
        public void OnEnable()
        {
            //这里的target 是在Editor中的变量 也就是当前对象 要里式转换一下
            Debug.Log(target as RectTransform);     
        }
    }
    
    我们把这个代码连同DecoratorEditor.cs一起放到Editor目录下,然后我们创建几个UI测试一下输出。 测试输出
    2. 实现自动添加脚本
    • 我们随便编写一个继承于MonoBehaviour的脚本,我暂且命名为Test
    • 在AutoAddScript 编辑器扩展中的OnEnable方法里判断是添加了什么UI
    • 如果是我们想要的UI组件,那么就添加Test脚本
    • 如果已经有了脚本就不要再次添加了
    using UnityEditor;
    using UnityEngine.UI;
    
    [CustomEditor(typeof(RectTransform))]
    public class AutoAddScript : DecoratorEditor
    {
        public AutoAddScript() : base("RectTransformEditor") { }
        public void OnEnable()
        {
            //这里的target 是在Editor中的变量 也就是当前对象 要里式转换一下
            RectTransform rectTransform = target as RectTransform;
            //这里要引用UnityEngine.UI
            Text text = rectTransform.GetComponent<Text>();
            if (text!=null && rectTransform.GetComponent<Test>()==null)
            {
                rectTransform.gameObject.AddComponent<Test>();
            }
        }
    }
    
    测试添加脚本
    3. 实现当Text被移除的时候Test也要被移除
    • 因为我们是用的OnEnable生命周期,他在编译器中的话每次状态改变都会调用一下
    • 所以移除Text的时候也会调用一次,那么我们可以直接在里面编写
    • 判断当前Text是否存在,不存在的话也要移除Test
    • 注意这里的移除组件必须为立即移除 也就是说Object.Destroy在这里是不能用的
    • 因为Object.Destroy是下一帧移除,我们可以用Object.DestroyImmediate这个方法立即移除组件
    using UnityEditor;
    using UnityEngine.UI;
    
    [CustomEditor(typeof(RectTransform))]
    public class AutoAddScript : DecoratorEditor
    {
        public AutoAddScript() : base("RectTransformEditor") { }
        public void OnEnable()
        {
            //这里的target 是在Editor中的变量 也就是当前对象 要里式转换一下
            RectTransform rectTransform = target as RectTransform;
            //这里要引用UnityEngine.UI
            Text text = rectTransform.GetComponent<Text>();
            Test test = rectTransform.GetComponent<Test>();
            if (text!=null && test == null)
            {
                rectTransform.gameObject.AddComponent<Test>();
            }else if (text == null && test != null)
            {
                //注意这里必须是立即移除
                Object.DestroyImmediate(test);
            }
    
        }
    }
    

    0x004 实现效果

    最终实现效果

    0x005 后记

    那么你要问了,这个可以拿来做什么 我能想到的就是框架的约束了,防止少挂在脚本,做全自动本地化相关等。

    相关文章

      网友评论

      本文标题:【UGUI】组件创建时添加指定脚本

      本文链接:https://www.haomeiwen.com/subject/imkwtqtx.html