HelpAttribute - allows you to use HelpBox in the Unity inspector window

Hey guys, my first post I think.

Not sure if this has been done before or if it’s built in to Unity (if not, it should be), did some searching and nothing turned up…

I rolled a simple PropertyDrawer and PropertyAttribute script which allows you to use the HelpBox you see in various places inside the Unity IDE, to decorate your inspector properties. Using a [HelpAttribute] you can set the text content and icon image to show help text \and usage information or instructions above any property in the inspector.

I thought it might be useful to the community for use in Asset Store assets or personal projects. Unity has an awesome community and hopefully you’ll accept my first addition.

The script is open source at GitHub - johnearnshaw/unity-inspector-help: Easily add the help text info box to any Unity 3D inspector field. and MIT license so commercial use allowed.

Here’s a few screenshots:

These two screenshots show the HelpBox as it is used internally in Unity IDE.


Here is a screenshot showing [HelpAttribute] usage on inspector visible properties from within a UnityBehavior script.

See the Readme in the Github repo for full details on usage and restrictions:
https://github.com/johnearnshaw/unity-inspector-help/

Not sure if this is posted in the right place so move it, reference it or do what ever you want with it. I just hope someone finds this script useful :slight_smile:

10 Likes

Nice! What do you think of using a scrollbar in a note instead of trying to resize the notes height? I was messing with your code trying to get the help notes to resize better. Would likely take a bunch of code to get them to resize correctly which ruins the simplicity of your code.

1 Like

Yeah, I know what you’re saying but I think using a scrollbar would require a CustomEditor rather than using the unity built in EditorGUI.HelpBox. The resizing was a pain and in the end I just settled for the pre-calculated constants rather than trying to get an accurate resizing function. I just try and keep to text to a minimum and to the point, but if it gets big I throw a couple of newlines at the end of the text to expand it.

I think the more elegant way to go would be calculating the size with GUIContent but couldn’t figure it out, or should I say didn’t have time to spend on it. Something along the lines of:

GUIStyle style = GUIStyle.none;
style.CalcSize(new GUIContent(helpAttribute.help));

I think you would need to get access to the GUIStyle used by the inspector to know the font size etc… Maybe someone from Unity GUI dev team can shed some light?

There’s this:

EditorGUIUtility.GetBuiltinSkin(EditorSkin.Inspector).GetStyle("");

Which takes a string to get the GUIStyle but I haven’t tried it. Maybe when I get more time…

It could be as simple as “HelpBox”?

@ShawnFeatherly , you got me hooked on fixing this one ;). I’ve updated the HelpAttribute.cs script in the repo to do a better job of computing the height at runtime.

I also commented up the code to help peeps (who may require it) to understand what’s going on a little better. I still had to leave some pre-calculated stuff in there for the custom MultilineAttribute handling and the minimum height and margin etc… But it’s definitely a big improvement.

1 Like

You may want to look at DecoratorDrawers here Unity - Scripting API: DecoratorDrawer

You can have multiple, doesn’t conflict with other Attributes and won’t be placed above List elements. Other than that, nice work.

1 Like

FWIW, this is the DecoratorDrawer that I use, in case it’s helpful to anyone:

HelpBoxAttribute.cs

using UnityEngine;

public enum HelpBoxMessageType { None, Info, Warning, Error }

public class HelpBoxAttribute : PropertyAttribute {

    public string text;
    public HelpBoxMessageType messageType;

    public HelpBoxAttribute(string text, HelpBoxMessageType messageType = HelpBoxMessageType.None) {
        this.text = text;
        this.messageType = messageType;
    }
}

Editor/HelpBoxAttributeDrawer.cs

using UnityEngine;
using UnityEditor;

[CustomPropertyDrawer(typeof(HelpBoxAttribute))]
public class HelpBoxAttributeDrawer : DecoratorDrawer {

    public override float GetHeight() {
        var helpBoxAttribute = attribute as HelpBoxAttribute;
        if (helpBoxAttribute == null) return base.GetHeight();
        var helpBoxStyle = (GUI.skin != null) ? GUI.skin.GetStyle("helpbox") : null;
        if (helpBoxStyle == null) return base.GetHeight();
        return Mathf.Max(40f, helpBoxStyle.CalcHeight(new GUIContent(helpBoxAttribute.text), EditorGUIUtility.currentViewWidth) + 4);
    }

    public override void OnGUI(Rect position) {
        var helpBoxAttribute = attribute as HelpBoxAttribute;
        if (helpBoxAttribute == null) return;
        EditorGUI.HelpBox(position, helpBoxAttribute.text, GetMessageType(helpBoxAttribute.messageType));
    }

    private MessageType GetMessageType(HelpBoxMessageType helpBoxMessageType) {
        switch (helpBoxMessageType) {
            default:
            case HelpBoxMessageType.None: return MessageType.None;
            case HelpBoxMessageType.Info: return MessageType.Info;
           case HelpBoxMessageType.Warning: return MessageType.Warning;
            case HelpBoxMessageType.Error: return MessageType.Error;
        }
    }
}

Example:

[HelpBox("This is some help text for Data.", HelpBoxMessageType.Info)]
public string data;
23 Likes

Hi all, this post is very cool & thank you to the OP for taking the time to make it.

Here is a somewhat simple hack I use. If anyone is interested.
It’s also handy want to display read only variables.

[ExecuteInEditMode]
public class HelpBoxInDefaultInspector : MonoBehaviour {
    
    [SerializeField] [Multiline]
    private string exampleHelpbox;

    [SerializeField] [Multiline]
    private static string _exampleHelpbox = @"Some helpful info:
    1) Some more example text.
    2) Even more example text";

    private void Update() {
        if (exampleHelpbox != _exampleHelpbox )
            exampleHelpbox = _exampleHelpbox ;
    }
}

A property drawer / attribute is a much cleaner approach but I thought I’d share anyway.

3 Likes

This seems nice, but when I tried this I got the following error:

I tried with both HelpBox and HelpBoxAttribute but it gave me the same error. I bet I’m missing something obvious.

1 Like

Did you put HelpBoxAttribute.cs in a non-Editor folder and HelpBoxAttributeDrawer.cs in an Editor folder?

Can you post how you’re using it in MaterialReplacer.cs?

1 Like

After I did that, the error was replaced with this instead:

The line is:

    [HelpBox("NOTE! If your new material is on other objects already, you will NOT be able to change back without also affecting those other objects.", HelpBoxMessageType.Info)]
1 Like

you’re trying to put the attribute on a class, you can only do that if the attribute class is tagged with
[AttributeUsage(AttributeTargets.Class)]

however, decoration drawers do not draw for classes (?).

you have to put the attribute on a field within the class

I…e

class myClass :monobehavior
{
[helpbox(words)]
public int a = 0;
}
1 Like

@reblGreen I can’t seem to get this to work :frowning:

Is this correct? I’m on UNity 2018.1

 [SerializeField]
    [Help("check in here for controller bool")]

Thanks for this tool!

1 Like

If you’re using John Earnshaw’s script, use [Help(“xxx”)]. If you’re using my script , use [HelpBox(“xxx”, HelpBoxMessageType.yyy)]:

HelpBox("This is some help text for Data.", HelpBoxMessageType.Info)]
public string data;

and make sure to put the Drawer script in an Editor folder.

3 Likes

Thanks for the great scripts, perfect timing too! Do you know how I would go about hiding the variable in the inspector, or is it even possible? Everything I do hides the message if the variable isn’t visible (setting static, using [HideInInspector])…

1 Like

It depends on a visible variable. If you need a help box without any variables visible in the inspector, I think you’ll need to write a custom inspector instead.

1 Like

Is there anything built in that lets me add a class level description to a class that is visible in the inspector - i.e not at the property level but at the class level?

1 Like

This is a hack, but you could add the HelpBox attribute to the first serialized property in your class so it appears at the top of the inspector, and put your class level description in it.

Otherwise I think you’ll need to write a custom inspector. A short one would do. Something like:

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(MyClass), true)]
[CanEditMultipleObjects]
public class MyClassEditor : Editor {
    public override void OnInspectorGUI() {
        EditorGUILayout.HelpBox("Class level info.", MessageType.None);
        DrawDefaultInspector();
    }
}
1 Like

I have done something similar but using editor:
https://github.com/ALanMAttano/UnityInspectorInfoTextNote

Nice, you could add a button with a question mark that opens and closes the help

1 Like

Such a nice script. Loved it. simple and easy.

1 Like