关于如何在 Unity 的 UI 菜单中默认创建出的控件 Raycast Target 属性默认为 false
关于如何在 Unity 的 UI 菜单中默认创建出的控件 Raycast Target 属性默认为 false
我们在 Unity 中通过 UI 菜单创建的各种控件,比如 Text, Image 等,它们的 Raycast Target 属性默认都是勾选的,这意味着他们会响应点击等时间,Unity 会将其加入到事件的响应队列,所以 UI 中这种控件数量很多时,是很影响性能的,确定不需要响应时间的都可以将改选项的勾选去掉。但是默认创建的都是全部勾选的,不过想要修改下这里面的细节又不破坏整体的使用习惯也是可行的。
UGUI 的源码打开找到 MenuOptions.cs 这里面就是实现 UI 菜单创建控件的代码。不过直接修改这部分的源码或者拷贝到项目里去修改,并且添加一系列新的 UI 菜单并不是我们希望的,我们希望直接接入原有 UI 菜单的创建过程,并且这部分源码并不是所有接口都在外部可访问,所以直接拷贝到项目也不一定可行,所以利用反射是一个好办法。
我们可以看到 UGUI 的源码中定义了各个菜单的位置,例如:[MenuItem("GameObject/UI/Text", false, 2000)]
,我们可以在自己的项目中重载此菜单的位置,也就是说如果我们在项目中定义了同样的 MenuItem,那么最终响应菜单点击事件的将是我们定义的函数。例如 我们在项目中创建 Editor
文件夹,创建一个 C# 文件,添加一个函数:
[MenuItem("GameObject/UI/Text", false, 2000)]
static public void AddText(MenuCommand menuCommand)
{
Debug.Log("This is an overrided AddText.");
}
编译完成后,点击菜单 GameObject/UI/Text
来创建一个 Text,会发现除了输出以上的 Log,什么也没创建,说明重载成功,接下来只需要利用反射,按照已有的 UGUI 源码按需求修改即可。例如如何重载创建一个 Raycast Target 为 false 的 Text 控件:
// Add by yaukey(https://github.com/yaukeywang) at 2017-10-11.
// Extend default ui menu.
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
using UnityEditor.UI;
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
using System.Reflection;
[InitializeOnLoad]
static internal class UIMenuOptionsExtend
{
// The reflected dafault methods.
private static MethodInfo m_miGetDefaultResource = null;
private static MethodInfo m_miPlaceUIElementRoot = null;
static UIMenuOptionsExtend()
{
Initialize();
}
private static void Initialize()
{
// Get all loaded assemblies.
Assembly[] allAssemblies = AppDomain.CurrentDomain.GetAssemblies();
Assembly uiEditorAssembly = null;
foreach (Assembly assembly in allAssemblies)
{
AssemblyName assemblyName = assembly.GetName();
if ("UnityEditor.UI" == assemblyName.Name)
{
uiEditorAssembly = assembly;
break;
}
}
// Check if we find ui assembly.
if (null == uiEditorAssembly)
{
Debug.LogError("Can not find assembly: UnityEditor.UI.dll");
return;
}
// Get things we need.
Type menuOptionType = uiEditorAssembly.GetType("UnityEditor.UI.MenuOptions");
m_miGetDefaultResource = menuOptionType.GetMethod("GetStandardResources", BindingFlags.NonPublic | BindingFlags.Static);
m_miPlaceUIElementRoot = menuOptionType.GetMethod("PlaceUIElementRoot", BindingFlags.NonPublic | BindingFlags.Static);
}
[MenuItem("GameObject/UI/Text", false, 2000)]
static public void AddText(MenuCommand menuCommand)
{
GameObject go = DefaultControls.CreateText((DefaultControls.Resources)m_miGetDefaultResource.Invoke(null, null));
m_miPlaceUIElementRoot.Invoke(null, new object[] { go, menuCommand });
// Remove raycast target.
Text text = go.GetComponent<Text>();
text.raycastTarget = false;
}
}
此时点击菜单 GameObject/UI/Text
创建出的 Text,属性 Raycast Target 即为 false。这样就可以几乎无缝修改引擎自定义的行为,同时保留原有的使用习惯。
以上源码完整版下载地址:http://pan.baidu.com/s/1nvA6R0H,提取码:setx