拓展控件
需求
比如我想在添加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