Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Let us know a bit about your interests, and if you'd like to become more directly involved. Take our survey!
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

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

Discussion in 'Extensions & OnGUI' started by usergame, Mar 24, 2017.

  1. usergame

    usergame

    Joined:
    Jan 29, 2015
    Posts:
    7
    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 https://github.com/johnearnshaw/unity-inspector-help/ 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 :)
     
    ilookha, ShawnFeatherly and AdamKane like this.
  2. ShawnFeatherly

    ShawnFeatherly

    Joined:
    Feb 22, 2013
    Posts:
    29
    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.
     
  3. usergame

    usergame

    Joined:
    Jan 29, 2015
    Posts:
    7
    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:

    Code (csharp):
    1. GUIStyle style = GUIStyle.none;
    2. 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:

    Code (csharp):
    1. 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"?
     
    Last edited: Mar 27, 2017
  4. usergame

    usergame

    Joined:
    Jan 29, 2015
    Posts:
    7
    @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.
     
    ShawnFeatherly likes this.
  5. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    636
    ShawnFeatherly likes this.
  6. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    8,349
    FWIW, this is the DecoratorDrawer that I use, in case it's helpful to anyone:

    HelpBoxAttribute.cs
    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public enum HelpBoxMessageType { None, Info, Warning, Error }
    4.  
    5. public class HelpBoxAttribute : PropertyAttribute {
    6.  
    7.     public string text;
    8.     public HelpBoxMessageType messageType;
    9.  
    10.     public HelpBoxAttribute(string text, HelpBoxMessageType messageType = HelpBoxMessageType.None) {
    11.         this.text = text;
    12.         this.messageType = messageType;
    13.     }
    14. }
    Editor/HelpBoxAttributeDrawer.cs
    Code (csharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [CustomPropertyDrawer(typeof(HelpBoxAttribute))]
    5. public class HelpBoxAttributeDrawer : DecoratorDrawer {
    6.  
    7.     public override float GetHeight() {
    8.         var helpBoxAttribute = attribute as HelpBoxAttribute;
    9.         if (helpBoxAttribute == null) return base.GetHeight();
    10.         var helpBoxStyle = (GUI.skin != null) ? GUI.skin.GetStyle("helpbox") : null;
    11.         if (helpBoxStyle == null) return base.GetHeight();
    12.         return Mathf.Max(40f, helpBoxStyle.CalcHeight(new GUIContent(helpBoxAttribute.text), EditorGUIUtility.currentViewWidth) + 4);
    13.     }
    14.  
    15.     public override void OnGUI(Rect position) {
    16.         var helpBoxAttribute = attribute as HelpBoxAttribute;
    17.         if (helpBoxAttribute == null) return;
    18.         EditorGUI.HelpBox(position, helpBoxAttribute.text, GetMessageType(helpBoxAttribute.messageType));
    19.     }
    20.  
    21.     private MessageType GetMessageType(HelpBoxMessageType helpBoxMessageType) {
    22.         switch (helpBoxMessageType) {
    23.             default:
    24.             case HelpBoxMessageType.None: return MessageType.None;
    25.             case HelpBoxMessageType.Info: return MessageType.Info;
    26.            case HelpBoxMessageType.Warning: return MessageType.Warning;
    27.             case HelpBoxMessageType.Error: return MessageType.Error;
    28.         }
    29.     }
    30. }
    Example:
    Code (csharp):
    1. [HelpBox("This is some help text for Data.", HelpBoxMessageType.Info)]
    2. public string data;
     
    petey, Gametroleum, Edy and 2 others like this.
  7. inepthuman

    inepthuman

    Joined:
    Mar 31, 2014
    Posts:
    14
    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.

    Code (CSharp):
    1.  
    2. [ExecuteInEditMode]
    3. public class HelpBoxInDefaultInspector : MonoBehaviour {
    4.    
    5.     [SerializeField] [Multiline]
    6.     private string exampleHelpbox;
    7.  
    8.     [SerializeField] [Multiline]
    9.     private static string _exampleHelpbox = @"Some helpful info:
    10.    1) Some more example text.
    11.    2) Even more example text";
    12.  
    13.     private void Update() {
    14.         if (exampleHelpbox != _exampleHelpbox )
    15.             exampleHelpbox = _exampleHelpbox ;
    16.     }
    17. }
    18.  
    A property drawer / attribute is a much cleaner approach but I thought I'd share anyway.
     
    Rispat-Momit likes this.
  8. ekergraphics

    ekergraphics

    Joined:
    Feb 22, 2017
    Posts:
    251
    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.
     
    indieDoroid likes this.
  9. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    8,349
    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?
     
  10. ekergraphics

    ekergraphics

    Joined:
    Feb 22, 2017
    Posts:
    251
    After I did that, the error was replaced with this instead:

    The line is:

    Code (CSharp):
    1.     [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)]
     
  11. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    133
    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

    Code (csharp):
    1.  
    2. class myClass :monobehavior
    3. {
    4. [helpbox(words)]
    5. public int a = 0;
    6. }
     
  12. indieDoroid

    indieDoroid

    Joined:
    Jan 25, 2016
    Posts:
    88
    @usergame I can't seem to get this to work :(

    Is this correct? I'm on UNity 2018.1

    Code (CSharp):
    1.  [SerializeField]
    2.     [Help("check in here for controller bool")]
    Thanks for this tool!

     
  13. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    8,349
    If you're using John Earnshaw's script, use [Help("xxx")]. If you're using my script, use [HelpBox("xxx", HelpBoxMessageType.yyy)]:
    Code (csharp):
    1. HelpBox("This is some help text for Data.", HelpBoxMessageType.Info)]
    2. public string data;
    and make sure to put the Drawer script in an Editor folder.
     
    indieDoroid and seansteezy like this.
  14. seansteezy

    seansteezy

    Joined:
    Nov 28, 2013
    Posts:
    114
    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])...
     
  15. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    8,349
    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.
     
  16. DrMaxP

    DrMaxP

    Joined:
    Sep 18, 2018
    Posts:
    8
    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?
     
  17. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    8,349
    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:

    Code (csharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [CustomEditor(typeof(MyClass), true)]
    5. [CanEditMultipleObjects]
    6. public class MyClassEditor : Editor {
    7.     public override void OnInspectorGUI() {
    8.         EditorGUILayout.HelpBox("Class level info.", MessageType.None);
    9.         DrawDefaultInspector();
    10.     }
    11. }