Unity 编辑器-监听创建控件,prefab创建或添加组件的自动处理⭐

拓展控件

需求

比如我想在添加Text时,自动添加一个脚本,用于处理多语言。在添加图片时,自动去掉raycast的勾选以节约性能损耗

解决方案

方案

ObjectFactory.componentWasAdded 用于监听组件的添加事件

csharp 复制代码
using TMPro;
using UnityEngine;
using UnityEditor;
using UnityEngine.UI;
using UnityEngine.EventSystems;
/// <summary>
/// Inspector面板添加组件回调
/// </summary>
[InitializeOnLoad]
public class InspectorAddComponent
{
    static InspectorAddComponent()
    {
        //监听组件添加事件
        ObjectFactory.componentWasAdded += ComponentWasAdded;
       
    }
    
    private static void ComponentWasAdded(Component com)
    {
        switch (com.GetType().ToString())
        {
            case "UnityEngine.UI.Image":
                ComponentOptimizing.OptimizingImage(com as Image);
                break;
            case "UnityEngine.UI.Text":
                ComponentOptimizing.OptimizingText(com as Text);
                break;
            case "UnityEngine.UI.Button":
                ComponentOptimizing.OptimizingButton(com as Button);
                break;
            case "UnityEngine.UI.Mask":
                ComponentOptimizing.OptimizingMask(com as Mask);
                break;
            case "TMPro.TextMeshProUGUI":
                ComponentOptimizing.OptimizingTmp(com as TextMeshProUGUI);
                break;
        }
    }
}
csharp 复制代码
using TMPro;
using Unity.VisualScripting;
using UnityEditor;
using UnityEditor.Events;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;

/// <summary>
/// 组件优化设置
/// </summary>
public class ComponentOptimizing
{
    #region Image

    public static void OptimizingImage(Image image)
    {
        //如果当前图片不是按钮,取消勾选RaycastTarget
        if (image.gameObject.GetComponent<Button>() == null)
        {
            image.raycastTarget = false;
        }
    }

    #endregion

    #region TextMeshProUGUI

    public static void OptimizingTmp(TextMeshProUGUI tmp)
    {
        if (tmp.gameObject.GetComponent<MaskableGraphic>() == null )
        {
            tmp.raycastTarget = false;
        }
        
        if (tmp.GetComponent<DictionaryText>() == null)
        {
            tmp.AddComponent<DictionaryText>();
        }
    }

    #endregion
    #region Text

    public static void OptimizingText(Text text)
    {
        if (text.gameObject.GetComponent<MaskableGraphic>() == null)
        {
            text.raycastTarget = false;
        }

        //是否支持富文字框架,默认不支持,有需求再手动勾选
        text.supportRichText = false;
        
        if (text.GetComponent<DictionaryText>() == null)
        {
            text.AddComponent<DictionaryText>();
        }
    }

    #endregion

    #region Button

    public static void OptimizingButton(Button button)
    {
        //判断需要添加button组件的物体是否有继承自MaskableGraphic的组件,有的话就勾选RaycastTarget
        if (button.gameObject.GetComponent<MaskableGraphic>() != null)
        {
            button.gameObject.GetComponent<MaskableGraphic>().raycastTarget = true;
        }

        if (button.GetComponent<ClickSound>() == null)
        {
            var btnE = button.AddComponent<ClickSound>();
            button.onClick.AddListener(btnE.OnPlaySound);
            AddListener(button, btnE.OnPlaySound);
        }
    }

    private static void AddListener(Button button, UnityAction e)
    {
        // 获取或创建自定义序列化对象和属性
        SerializedObject serializedButton = new SerializedObject(button);
        // 将新创建的 UnityEvent 添加到 Button 的 OnClick 事件中
        UnityEventTools.AddVoidPersistentListener(button.onClick, e);
        // 应用所有更改并重新绘制 Inspector 视图
        serializedButton.ApplyModifiedProperties();
    }

    #endregion

    #region Mask

    public static void OptimizingMask(Mask mask)
    {
        //判断需要添加mask组件的物体是否有继承自MaskableGraphic的组件,有的话就勾选RaycastTarget
        if (mask.gameObject.GetComponent<MaskableGraphic>() != null)
        {
            mask.gameObject.GetComponent<MaskableGraphic>().raycastTarget = true;
        }
    }

    #endregion
}

如图,inspector 面板和场景中创建的所有控件,几乎都能触发这个回调。

或者说所有使用到ObjectFactory.AddComponent 方法添加脚本的都能触发这个回调。

值得注意的是TextmeshoPro.。测试发现TextMeshProUGU 部分控件不能触发事件

查看源码可发现,text - TextMeshPro控件使用的是ObjectFactory.AddComponent ,而Button - TextMeshPro 使用的是GameObject.AddComponent

如果需要修改,可以把TMP的package包从PackageManager中挪出来,改为本地Package

相关推荐
魔士于安5 天前
unity 丑陋哥布林 哥布林有humannoid 动画没 带动画
unity·游戏引擎·材质·贴图·模型
weixin_464078075 天前
ppt转为draw.io方法
编辑器
小贺儿开发6 天前
Unity 家居视频遥控(细节优化)
科技·unity·程序员·udp·视频·工具·通信
淡海水6 天前
13-04-面试-源码级深度追问链
数据结构·unity·面试·c#·游戏引擎·源码·il2cpp
小小数媒成员6 天前
UGUI 性能优化(详细,全,深入)
开发语言·unity·游戏引擎
林川~017 天前
Unity新输入系统使用笔记
unity·input system
小贺儿开发7 天前
Unity 结合百度AI开放平台 手写文字识别
人工智能·科技·学习·unity·云服务·文字识别·手写文字
一木 之林7 天前
手搓家庭服务器:二手装机、Docker部署、端口映射与frp内网穿透
服务器·人工智能·git·编辑器
goujunwe7 天前
GEO 评估方法:如何自测你的内容,会不会被 AI 引用
搜索引擎·网络安全·游戏引擎·全文检索·中文分词
林川~018 天前
Unity 万能物理检测工具:射线检测 / 范围检测 / 层级过滤 / 编辑器可视化(可直接拿去用)
游戏·unity·c#·射线检测·通用工具