除了在Unity3D中使用“资产/ Gizmos”以外,如何具有自定义脚本图标

der*_*ugo 8 customization unity-game-engine unity3d-editor unity-editor

我知道这个问题可能被问了很多次,但是通常回答是错误的。

我想要的是:

对检查器(例如,图2和图3)和ProjectView(例如,图1)中的特定组件/脚本使用自定义图标 替代文字

到目前为止,我所做的是:

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

Assets/Gizmos/<Path>/<To>/<Namespace>/<ClassName> icon
Run Code Online (Sandbox Code Playgroud)

Import Settigns设置TextureTypeEditor GUI and Legacy GUI

这工作正常..直到现在,我是实现该目标的唯一方法(请记住以下部分,我绝对不想要)。


但是,我想知道是否真的没有更好的方法来让每个脚本具有唯一的Icon文件。这使得项目/ UnityPackage不必要地庞大。同样,如果我重命名一个类,我也总是必须重命名相应的图标文件...这意味着感觉不对!

大多数Unity内置行为和组件都有一个唯一的图标。但是来自新PackageManager的外部Packages也具有内置图标,有时还会Gizmos文件夹,但是它没有遵循上述命名规则...因此,显然,为它们配置了图标。

因此,我的问题
有没有更好的方法来为脚本/组件提供这些图标?

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

和/或还有/在哪里/如何为这些图标定义来自PackageManager的脚本?


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

对于所有GameObjects附加了这些组件的对象,也要在SceneView中显示图标(例如,图4)。这是由于通过图5中的检查器选择了该脚本的图标(如本文中此处建议的所有建议,甚至Unity都建议使用Unity-Assign Icons)或使用OnDrawGizmosDrawGizmo

替代文字

更新资料

因为这个答案是建议的:我也知道我可以做到这一点,并通过GizmosSceneView 的设置将其关闭。但是想象一下,我喜欢25个不同的模块,每个模块都有不同的图标。我不想在每个项目的基础上逐一禁用SceneView设置中的Gizmos!甚至提供的脚本似乎也很庞大。反思将是我永远不会采取的最后手段。另外,我宁愿根本不让那些图标尽可能地显示为Gizmos,而不是全部禁用它们。

Bri*_*ght 3

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

编辑:根据上面的步骤,您可以尝试从这里派生的这个脚本,它使用反射来查找负责关闭小工具和图标的类。每当您的脚本重新编译以保持这些图标关闭时,或者您向自动隐藏图标文件添加任何新图标时,都会执行此操作。注意:对于内置组件,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 });
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 在检查器中显示有一个小工具

  2. 从小工具下拉列表中隐藏图标

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