Unity plugin that adds some useful attributes. Most of them will work with any editor. For those few who use custom one, you need to explicitly make the class use HoneyEditor inheritor.
Download unitypackage: https://github.com/Biegus/HoneyAttributes/releases/tag/releasev1.1
Requires unity version that supports full C# 8.0
Honey - all you need if you just want to use attributes
however for more sophisticated things, mostly custom drawers use Honey.Core and Honey.Editor
Types of attributes are shown by their prefixes
- Name -> doesn't require anything
- HName -> requires HoneyRun or EHoneyRun attribute to be added as well
- EName -> requires the editor to be the HoneyEditor
- EHName -> requires EHoneyRun attribute and the editor to be the HoneyEditor
To enable context in which attributes with "E" prefix work add:
#if UNITY_EDITOR
[UnityEditor.CustomEditor(typeof($ClassName$))]
[UnityEditor.CanEditMultipleObjects]
public class $ClassName$Editor : Honey.Editor.HoneyEditor
#endif
If you just want the custom editor to work for every mono behaviour script, use [UnityEditor.CustomEditor(typeof(MonoBehaviour),true]
(not recommended)
Restricts whether a field can be shown/editable. Name can point to a static/instance method/field/property or to a simple BoolExpression
public bool showX;
[HoneyRun]
[HShowIf(nameof(showX))]
public int x;
public int a;
public int b;
[HoneyRun]
[HShowIf("CheckSum(a,b)")]
public float secretField=42;
public bool allowToEditY;
[HoneyRun] [HShowIf(nameof(allowToEditY),HoneyPropertyState.Disabled)]
public string y="abcd";
private bool CheckSum(int x,int y)
{
return x + y == 5;
}
Blocks editing the variable
Headers with greater capabilities than unity headers.
[DefineStyleOverride("big_right_header",Alignment = TextAnchor.MiddleRight,
ColorExpression = "red",FontSize = 30)]
[DefineStyleOverride("small_left_header",Alignment = TextAnchor.MiddleLeft,
ColorExpression = "RGB(51,184,100)",FontSize = 15, FontStyle = FontStyle.Italic )]
public class HeaderDemo: MonoBehaviour
{
[HHeader("Simple header")]
[HHeader("Big right bold text", style: "big_right_header")]
[HHeader("small left italic text", style: "small_left_header")]
[HoneyRun]
public int someValue;
}
Forces field to have bigger indent
[HIndentBefore(5)][HoneyRun]
public int indentation = 3;
Draws line in color of Color Expression
[ColorSeparator("white")]
public int a;
[ColorSeparator("RGB(51,184,100)")]
public int b;
Makes prefix as short as possible
Hides prefix
Changes the label
Defines the label dynamically. Method should be of the exact structure as in the example. string METHOD(string name, object value)
[HDynamicContent(nameof(GetAlphabetElement))] [HoneyRun]
public List<int> differentIndexNames = new List<int>() {42, 123,55};
public string GetAlphabetElement(string name, object value)
{
return ((char)(int.Parse(name.Replace("Element", "")) + 'a')).ToString();
}
Draws simple helpbox
[HelpBox("Hello how are u?")]
public int someValue;
More powerful version of helpbox. Reference Value Expression by &. Space or "," marks the end of reference.
[HoneyRun]
[HHelpBox("x=&x y=&y when you add them up you get &x+y")]
public int x = 3;
public int y = 5;
instead of Element 0, Element 1 will display 0,1,2,..
Draws progress bar. It doesn't have to be added to variable that it uses.
[HJustProgressBar("hp","0","maxHp" ,style: ProgressBarStyle.Red, Name = "HP",Size = 2)]
[HJustProgressBar("mana","0","maxMana",style: ProgressBarStyle.Blue, Name = "Mana", Size = 2)]
[HoneyRun]
public string someVariable;
Additional button that allows for selection of predefined values. Works only with primitive types.
[HDropdownButton(1,2,3)][HoneyRun]
public int fastAccessTo123;
Makes dropdown with predefined values the only way of changing value of the field.
Additional button that allows for selection of dynamic values.
[HoneyRun]
[HDynamicDropdownButton(nameof(GetGuids))]
public string fastAccessToRandomGuids;
private IEnumerable<string> GetGuids()
{
yield return GUID.Generate().ToString();
yield return GUID.Generate().ToString();
}
Makes dropdown with dynamic values the only way of changing value of the field.
Allows to select type for serialize references. Type can be restricted by namespace
[SerializeReference] [SerializeReferenceHelper]
public Animal animal = null;
[SerializeReference] [SerializeReferenceHelper("UnityEngine")]
public object unityNamespaceObject = null;
Draws preview for a sprite
[ESpritePreview][EHoneyRun]
public Sprite someSprite;
todo: add gif
Draws editor for a field
[EHoneyRun]
[EHPreview]
public Transform withPreview;
Adds a button that allows for reseting the value. Value has to be a primitive.
[HoneyRun]
[HResetValue(42)]
public int resetable=42;
Draws dropdown to select unity tag
Draws dropdown to select unity layer
Replaces enum dropdown with searchable window
Similar to Unity's [Range], but allows for dynamic limits and alternative appearance.
public float maxHp;
public float maxMana;
[Slider("0","maxHp")]
public float hp = 0;
[Slider("0","maxMana",SliderMode.ProgressBar)]
public float mana = 0;
Allows for easier way to set component field
[HoneRun]
[HGetComponentButtonAttribute]
public SpriteRenderer renderer;
[HoneRun]
[HGetComponentButton(ComponentBFlags.AddAutomaticallyIfNotPresent)]
public SpriteRenderer rendererGetOrAdd;
Flags:
-
IncludeChildren -> allows for grabbing from children
-
AddAutomaticallyIfNotPresent -> If cannot grab, it adds the component
-
Aggressive -> Button presses itself on its own
Defines min and max value for number field. May be dynamic.
(There is already unity attributes min, there's no max though)
Makes the array size constant and draws array expanded
[EHoneyRun]
[EHConstSizeAttribute(3)]
public string[] someElements= new string[3];
Restricts curve range
[CurveBound(0, 1, 0, 1)] public AnimationCurve curve01;
Soft restrain that marks field in red if requirements are not met.
Works with methods returning bool, bool fields and properties and simple Bool expressions
Doesn't support lists/arrays
[HoneyRun]
[HValidate("itself!=3")] public int not3;
[HoneyRun]
[HValidate("Do(itself)!=2")]public int some;
private int Do(int v)
{
return v / 5;
}
Soft restrain that marks field in red if field is null
All groups require HoneyEditor. Groups can be nested (use "/")
[EGroup] marks field as belonging to the group [EDefVerticalGroup],[EDefHorizontalGroup], [EDefTabGroup]-define the type of a group
[EDefVerticalGroup("BasicFolders",BaseGroupAppearance.Empty,true)]
[EDefVerticalGroup("BasicFolders/a",BaseGroupAppearance.Empty,true)]
[EDefVerticalGroup("GroupBox",BaseGroupAppearance.BoxGroup,false)]
[EDefVerticalGroup("GroupBox/a",BaseGroupAppearance.BoxGroup,false)]
public class GroupDemo : MonoBehaviour
{
[EGroup("BasicFolders")] public string x;
[EGroup("BasicFolders")] public string o;
[EGroup("BasicFolders/a")] public string y;
[EGroup("BasicFolders/a")] public string n;
[EGroup("BasicFolders/a")] public string s;
[Space]
[EGroup("GroupBox")] public string d;
[EGroup("GroupBox")] public string g;
[EGroup("GroupBox/a")] public string k;
[EGroup("GroupBox/a")] public string a;
}
You can also use [EBeginGroup]
i [EEndGroup]
note: (added in v.1.2)
[EDefVerticalGroup("BasicFolders",BaseGroupAppearance.Empty,true)]
[EDefVerticalGroup("BasicFolders/a",BaseGroupAppearance.Empty,true)]
[EDefVerticalGroup("GroupBox",BaseGroupAppearance.BoxGroup,false)]
[EDefVerticalGroup("GroupBox/a",BaseGroupAppearance.BoxGroup,false)]
public class GroupDemo : MonoBehaviour
{
[EBeginGroup("BasicFolders")]
public string x;
public string o;
[EEndGroup]
[EBeginGroup("BasicFolders/a")]
public string y;
public string n;
public string s;
[EEndGroup()]
[EBeginGroup("GroupBox")]
public string d;
public string g;
[EEndGroup]
[EBeginGroup("GroupBox/a")]
public string k;
public string a;
[EEndGroup]
}
Defines groups that consists of 2 or more tabs. In the example below group name is empty string(master group) which forces every element to be in that group.
[EDefTabGroup("","Main","Other")]
public class TabDemo : MonoBehaviour
{
[ETabElement("Main")] public int a;
[ETabElement("Main")] public string b;
[ETabElement("Other")] public string x;
[ETabElement("Other")] public string y;
[ETabElement("Other")] public string z;
}
In order to assign tab to group use [EAssignGroupToTab] on the class.
Allows to position elements in horizontal manner. Remember that you can always use [HShortPrefix] or [HHidePrefix]
[Serializable]
public struct HorizontalDemoElement
{
public string Descr;
public int Value;
}
[EDefHorizontalGroup("container",BaseGroupAppearance.Empty)]
[EDefVerticalGroup("container/left",BaseGroupAppearance.Box)]
[EDefVerticalGroup("container/right",BaseGroupAppearance.Box)]
[EDefHorizontalGroup("a",BaseGroupAppearance.Empty,ShowLabel = HorizontalLabelMode.Hide)]
public class HorizontalDemo : MonoBehaviour
{
[EGroup("container/left")] public int a;
[EGroup("container/left")] public int b;
[EGroup("container/left")] public int c;
[EGroup("container/left")] public int d;
[EGroup("container/right")] public int x;
[EGroup("container/right")] public int y;
[EGroup("container/right")] public int z;
[EGroup("container/right")] public HorizontalDemoElement someStruct;
[EGroup("a")][HShortPrefix][HoneyRun]public int i;
[EGroup("a")][HShortPrefix][HoneyRun] public int j;
- They can be grouped just like fields.
Draws button that runs parameterless method.
[EMethodButton(ButtonSize:2)]
public void ClickMe()=>Debug.Log("thx");
Shows any property, non serialized field, or parameterless method as a string from .ToString()
[EShowAsString]
private int secret = 2152;
[EShowAsString]
public float TheTime => Time.time;