zoukankan      html  css  js  c++  java
  • 关于如何在 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

  • 相关阅读:
    精读大道至简01
    mysql查询语句出现sending data耗时解决
    定位线上问题
    docker命令
    .net core2学习笔记
    centos下安装色彩scrapy
    mysql中id值被重置的情况
    MySql中的SHOW INDEX 查出的结果列代表的意义
    ELK安装
    使用PowerDesigner进行面向对象分析与UML建模(转)
  • 原文地址:https://www.cnblogs.com/yaukey/p/override_unity_default_ui_menu_options.html
Copyright © 2011-2022 走看看