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

时间:2018-07-18 08:41:02

标签: unity3d customization unity3d-editor unity-editor

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

我想要的是:

在检查器(例如,图2和图3)和ProjectView(例如,图1)中为特定的组件/脚本使用自定义图标 alt text

我到目前为止所做的事情:

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

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

,然后在Import Settigns中将TextureType设置为Editor GUI and Legacy GUI

这很好..直到现在,我是实现这一目标的唯一方法(请记住以下部分我绝对不想要的东西)。


但是

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

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

因此我的问题:
是否有更好的方法来为脚本/组件添加这些图标?

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

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


!注意!我绝对不想要的东西:

在所有附加了这些组件的GameObjects中也在场景视图中显示图标(例如,图4)。这是由于通过检查器(如图5所示,总是建议在this posthere甚至通过Unity - Assign Icons中选择此脚本的图标)或使用了{{3} }或OnDrawGizmos

DrawGizmo

更新

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

2 个答案:

答案 0 :(得分:0)

您可以使用图5设置图标,然后从gizmos下拉菜单中关闭该图标的gizmos。

编辑:结合以上步骤,您可以尝试使用源自here的脚本,该脚本使用反射来查找负责关闭小控件和图标的类。只要您的脚本重新编译以使这些图标保持关闭状态,或者在自动隐藏图标文件中添加了任何新图标,此命令便会执行。 注意: scriptClass将是一个空字符串,用于内置组件(例如,相机,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. 从Gizmos下拉菜单中隐藏图标

  3. 图标仍显示在检查器和项目视图中,但不显示在场景中

答案 1 :(得分:0)

因此,我对内置类型以及来自程序包管理器和资产商店的程序包进行了更多研究。外部(程序包管理器或资产存储库)中的任何内容(如果具有脚本和检查器的自定义图标)将始终在场景视图中具有小控件。因为它使用您的图5示例设置了图标,如调试检查器的屏幕截图所示。

另外,如果您想使用脚本设置图标或将其隐藏,则当前反射是您的 only 选项,因为这些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

我希望将其添加为您的原始问题的评论,但还没有足够的代表。