Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have custom script icons other than using "Assets/Gizmos" in Unity3D

I know this was asked a lot of times probably .. but it is very often answered wrong.

What I want is:

Use a custom icon for specific components/scripts in the Inspector (e.g. Figure 2 and Figure 3) and the ProjectView (e.g. Figure 1) alt text

What I do so far:

For each component/class that shall have the icon I have an accroding Icon file in the folder

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

and in the Import Settigns set TextureType to Editor GUI and Legacy GUI

This is working fine .. and until now the only way how I could achieve that (having in mind the below section What I definitely do NOT want).


But

However, I wondered if there is really no better way having to have a unique Icon file for each script. This makes the project/UnityPackage unnecessarily huge. Also if I rename a class I always have to rename the according icon file as well ... This imply doesn't feel right!

Most Unity build-in Behaviours and Components have a unique icon. But also external Packages coming from the new PackageManager have built-in icons and sometimes a Gizmos folder but it is not following the above naming rule ... so apparently the icon is configured somehow else for them.

Therefore my questions:
Is there any better way to have those icons for scripts/components?

Preferably scripted and reusing ONE single icon file instead of having the same icon in multiple differently named files.

And/or also Where/How are those icons defined for the scripts coming from the PackageManager?


!NOTE! What I definitely do NOT want:

Show the Icon also in the SceneView for all GameObjects having those components attached (e.g. Figure 4). This is caused by either selecting the icon for this script via the Inspector as in Figure 5 (as allways suggested e.g. in this post or here and even by Unity - Assign Icons ) or using OnDrawGizmos or DrawGizmo. This is not happening using the approach I use currently with the Gizmos folder!

alt text

Update

Because this was suggested in this answer: I also know that I could do that and turn them off via the Gizmos settings of the SceneView. But imagine I have like 25 different modules and various different icons each. I don't want to have to disable their Gizmos in the SceneView settings one by one on a per project basis! Even the provided script seems like a vast hackaround. Reflection would be the very last resort I would ever take. Also I'ld prefer to not even have those icons appear as possible Gizmos at all instead of disabling them all.

like image 466
derHugo Avatar asked Jul 18 '18 08:07

derHugo


People also ask

How do I change the script icon in unity?

Script Select Icon button To assign a custom icon to a script, select the script in the Project window, then click the Select Icon button (the C# file icon, highlighted with a red square in the image below) in the Inspector window to the left of the script's name.

What is a gizmo in unity?

Description. Gizmos are used to give visual debugging or setup aids in the Scene view. All gizmo drawing has to be done in either OnDrawGizmos or OnDrawGizmosSelected functions of the script. OnDrawGizmos is called every frame. All gizmos rendered within OnDrawGizmos are pickable.


1 Answers

You can set the icon with figure 5 and then turn the gizmos for that icon off from the gizmos drop down.

Edit: Injunction with the step above you could try this script derived from here it uses reflection to find the class responsible for turning off the the gizmos and icons. This would execute any time your scripts recompiled to keep those icons off or if you added any new icons to the autohide icon file. Note: scriptClass will be an empty string for built in components eg.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. Shown in the inspector with a gizmo

  2. Hide Icon from gizmos dropdown

  3. Icon still appears in the inspector and in the project view but not in the scene

like image 185
BrightenedLight Avatar answered Sep 20 '22 11:09

BrightenedLight