Last active
January 24, 2018 12:28
-
-
Save Arakade/02d101719bc8afae680d65d6330c9c5b to your computer and use it in GitHub Desktop.
Unity3D NonNull attribute + colouring PropertyDrawer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
namespace UGS.unityutil.attributes { | |
/// <summary> | |
/// Checks non-null (and non-empty if applied to a string, non-zero if a scalar or Vector, etc) in a custom inspector. | |
/// Colours red if any problems. | |
/// </summary> | |
public sealed class NonNullAttribute : PropertyAttribute { | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEditor; | |
using UnityEngine; | |
// Place in Editor sub-directory | |
namespace UGS.unityutil.attributes { | |
[CustomPropertyDrawer(typeof (NonNullAttribute))] // n.b. will need 2nd param 'true' if wish to use for subclasses of NonNullAttribute | |
public sealed class NonNullAttributePropertyDrawer : PropertyDrawer { | |
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { | |
var oc = GUI.backgroundColor; | |
var result = isProblem(property); | |
if (result.HasValue) { | |
if (result.Value) { | |
GUI.backgroundColor = ColourBad; | |
if (string.IsNullOrEmpty(label.tooltip)) { | |
label.tooltip = (property.propertyType == SerializedPropertyType.String) ? "Must not be empty." : "Must not be null."; | |
} | |
} | |
} else { // no result = unhandled | |
GUI.backgroundColor = ColourUnhandled; | |
if (string.IsNullOrEmpty(label.tooltip)) { | |
label.tooltip = AttributeName + " cannot be applied to this type"; | |
} else { | |
label.tooltip += "\n" + AttributeName + " cannot be applied to this type"; | |
} | |
} | |
EditorGUI.PropertyField(position, property, label, true); | |
GUI.backgroundColor = oc; | |
} | |
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { | |
return EditorGUI.GetPropertyHeight(property); | |
} | |
private bool? isProblem(SerializedProperty property) { | |
switch (property.propertyType) { | |
case SerializedPropertyType.String: | |
return string.IsNullOrEmpty(property.stringValue); | |
case SerializedPropertyType.Vector2: | |
return 0f >= property.vector2Value.sqrMagnitude; | |
case SerializedPropertyType.Vector2Int: | |
return 0f >= property.vector2IntValue.sqrMagnitude; | |
case SerializedPropertyType.Vector3: | |
return 0f >= property.vector3Value.sqrMagnitude; | |
case SerializedPropertyType.Vector3Int: | |
return 0f >= property.vector3IntValue.sqrMagnitude; | |
case SerializedPropertyType.Vector4: | |
return 0f >= property.vector4Value.sqrMagnitude; | |
case SerializedPropertyType.Float: | |
return 0f == property.floatValue; | |
case SerializedPropertyType.Integer: | |
return 0 == property.intValue; | |
case SerializedPropertyType.Color: | |
return NullColour == property.colorValue; | |
case SerializedPropertyType.LayerMask: | |
return 0 == property.intValue; | |
case SerializedPropertyType.ObjectReference: | |
return null == property.objectReferenceValue; | |
} | |
return null; // indicate not handled | |
} | |
private static readonly string AttributeName = "WARNING: " + typeof (NonNullAttribute).Name; | |
private static readonly Color ColourBad = new Color(1f, 0.5f, 0.5f); | |
private static readonly Color ColourUnhandled = new Color(1f, 0f, 0.8f); | |
private static readonly Color NullColour = new Color(0f, 0f, 0f, 0f); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment