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

0x001 需求

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

0x002 分析

  • 可否直接为Text组件编写编辑器扩展脚本。
    引用momo大神文章地址:Unity3D研究院编辑器之不影响原有布局拓展Inspector
    经过测试这在UGUI的某些组件中不生效,原因未知。

解决办法:我们可以为 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();
        if (text!=null && rectTransform.GetComponent()==null)
        {
            rectTransform.gameObject.AddComponent();
        }
    }
}
测试添加脚本
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();
        Test test = rectTransform.GetComponent();
        if (text!=null && test == null)
        {
            rectTransform.gameObject.AddComponent();
        }else if (text == null && test != null)
        {
            //注意这里必须是立即移除
            Object.DestroyImmediate(test);
        }

    }
}

0x004 实现效果

最终实现效果

0x005 后记

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

你可能感兴趣的:(【UGUI】组件创建时添加指定脚本)