代码之家  ›  专栏  ›  技术社区  ›  derHugo

如何使用Unity3D中的“资源/小控件”以外的自定义脚本图标

  •  7
  • derHugo  · 技术社区  · 6 年前

    我知道有人问过很多次可能…但答案往往是错的。

    我想要的是:

    在Inspector(如图2和图3)和ProjectView(如图1)中为特定组件/脚本使用自定义图标 alt text

    我目前所做的:

    对于每个应该有图标的组件/类,我在文件夹中有一个accroding图标文件

    Assets/Gizmos/<Path>/<To>/<Namespace>/<ClassName> icon
    

    Import Settigns 设置 TextureType Editor GUI and Legacy GUI

    这很管用。到目前为止,我唯一能做到这一点的方法是(记住下面的部分 我绝对不想要的 )中。


    但是

    不过,我想知道是否真的没有更好的方法,必须有一个独特的图标文件为每个脚本。这使得项目/单元包不必要地庞大。另外,如果我重命名一个类,我总是必须重命名相应的图标文件以及…这意味着感觉不对!

    大多数统一的内置行为和组件都有一个独特的图标。但是来自新包管理器的外部包也有内置图标,有时 Gizmos 文件夹,但它不遵循上述命名规则…所以很明显这个图标是为他们配置的。

    因此,我的问题是:
    有没有更好的方法让脚本/组件具有这些图标?

    最好编写脚本并重用一个图标文件,而不是在多个不同名称的文件中使用相同的图标。

    和/或 从packagemanager为脚本定义的图标在哪里/如何定义?


    啊!注意!我绝对不想要的是:

    同时在“所有人”视图中显示图标 GameObjects 连接这些组件(如图4)。这是由通过Inspector为这个脚本选择图标引起的,如图5所示 this post here 甚至通过 Unity - Assign Icons )或使用 OnDrawGizmos DrawGizmo

    alt text

    更新

    因为这是在 this answer :我也知道我可以通过 小发明 场景视图的设置。 但是 假设我有25个不同的模块和不同的图标。我不想在每个项目的基础上一个接一个地禁用他们的小控件!即使是提供的脚本也像是一个庞大的黑客。反思是我最后的选择。另外,我更希望这些图标根本不显示为可能的小控件,而不是全部禁用它们。

    2 回复  |  直到 6 年前
        1
  •  1
  •   BrightenedLight    6 年前

    您可以使用图5设置图标,然后从Gizmo下拉列表中关闭该图标的Gizmo。

    编辑 以上步骤的禁令您可以尝试此脚本 here 它使用反射来查找负责关闭小控件和图标的类。这将在脚本重新编译以关闭这些图标或在自动隐藏图标文件中添加任何新图标时执行。 笔记 ScriptClass将是内置组件(如Camera、AudoSource)的空字符串

    using UnityEditor;
    using System;
    using System.Reflection;
    
    public class DisableAllGizmos
    {
        [UnityEditor.Callbacks.DidReloadScripts]
        private static void OnScriptsReloaded()
        {
            var Annotation = Type.GetType("UnityEditor.Annotation, UnityEditor");
            var ClassId = Annotation.GetField("classID");
            var ScriptClass = Annotation.GetField("scriptClass");
            var Flags = Annotation.GetField("flags");
            var IconEnabled = Annotation.GetField("iconEnabled");
    
            Type AnnotationUtility = Type.GetType("UnityEditor.AnnotationUtility, UnityEditor");
            var GetAnnotations = AnnotationUtility.GetMethod("GetAnnotations", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
            var SetIconEnabled = AnnotationUtility.GetMethod("SetIconEnabled", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
    
            Array annotations = (Array)GetAnnotations.Invoke(null, null);
            foreach (var a in annotations)
            {
                int classId = (int)ClassId.GetValue(a);
                string scriptClass = (string)ScriptClass.GetValue(a);
                int flags = (int)Flags.GetValue(a);
                int iconEnabled = (int)IconEnabled.GetValue(a);
    
                // this is done to ignore any built in types
                if (string.IsNullOrEmpty(scriptClass))
                {
                    continue;
                }
    
                // load a json or text file with class names
    
                const int HasIcon = 1;
                bool hasIconFlag = (flags & HasIcon) == HasIcon;
    
                // Added for refrence
                //const int HasGizmo = 2;
                //bool hasGizmoFlag = (flags & HasGizmo) == HasGizmo;
    
                if (/*Compare class names in file to scriptClass == true*/)
                {
                    if (hasIconFlag && (iconEnabled != 0))
                    {
                        UnityEngine.Debug.LogWarning(string.Format("Script:'{0}' is not ment to show its icon in the scene view and will auto hide now. " +
                            "Icon auto hide is checked on script recompile, if you'd like to change this please remove it from the config",scriptClass));
                        SetIconEnabled.Invoke(null, new object[] { classId, scriptClass, 0 });
                    }
                }
            }
        }
    }
    
    1. 显示在带有小控件的检查器中

    2. 从小控件下拉列表中隐藏图标

    3. 图标仍会出现在检查器和项目视图中,但不会出现在场景中

        2
  •  0
  •   BrightenedLight    6 年前

    因此,我对内置类型以及来自包管理器和资产存储的包做了更多的研究。任何外部的(packagemanager或assetstore)如果它有脚本和检查器的自定义图标,它将 总是 在场景视图中有一个gizmo。使用图5示例设置了它的图标,如调试检查器的屏幕截图所示。

    另外,如果要用脚本设置图标或隐藏它,当前反射是 只有 选项,因为这些api不可公开访问。

    My Script showing the debug inspector for its script

    PixelPerfect package script from the packagemanager in the debug inspector

    PixelPerfect Icon showing in the scene

    我希望把这作为你最初的问题的一个评论,但还没有足够的代表。