diff --git a/Assets/NaughtyAttributes/Documentation~/Hex_Inspector.png b/Assets/NaughtyAttributes/Documentation~/Hex_Inspector.png new file mode 100644 index 00000000..4bf26046 Binary files /dev/null and b/Assets/NaughtyAttributes/Documentation~/Hex_Inspector.png differ diff --git a/Assets/NaughtyAttributes/Samples/DemoScene/DemoScene.unity b/Assets/NaughtyAttributes/Samples/DemoScene/DemoScene.unity index 3c134139..122b1732 100644 --- a/Assets/NaughtyAttributes/Samples/DemoScene/DemoScene.unity +++ b/Assets/NaughtyAttributes/Samples/DemoScene/DemoScene.unity @@ -38,7 +38,7 @@ RenderSettings: m_ReflectionIntensity: 1 m_CustomReflection: {fileID: 0} m_Sun: {fileID: 0} - m_IndirectSpecularColor: {r: 0.44657874, g: 0.49641258, b: 0.5748172, a: 1} + m_IndirectSpecularColor: {r: 0.18028378, g: 0.22571412, b: 0.30692285, a: 1} m_UseRadianceAmbientProbe: 0 --- !u!157 &3 LightmapSettings: @@ -297,7 +297,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 1148579784} - m_RootOrder: 9 + m_RootOrder: 10 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &155697337 MonoBehaviour: @@ -494,7 +494,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 1148579784} - m_RootOrder: 11 + m_RootOrder: 12 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &607441875 MonoBehaviour: @@ -663,7 +663,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 1148579784} - m_RootOrder: 15 + m_RootOrder: 16 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &892661556 MonoBehaviour: @@ -711,7 +711,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 1148579784} - m_RootOrder: 16 + m_RootOrder: 17 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &933563386 MonoBehaviour: @@ -763,7 +763,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 1148579784} - m_RootOrder: 12 + m_RootOrder: 13 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &948946035 MonoBehaviour: @@ -813,7 +813,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 1148579784} - m_RootOrder: 10 + m_RootOrder: 11 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &993534227 MonoBehaviour: @@ -864,7 +864,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 1148579784} - m_RootOrder: 7 + m_RootOrder: 8 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1139446981 MonoBehaviour: @@ -917,6 +917,7 @@ Transform: - {fileID: 779670087} - {fileID: 2015414598} - {fileID: 1622801696} + - {fileID: 1536277549} - {fileID: 1139446980} - {fileID: 1552114400} - {fileID: 155697336} @@ -1049,7 +1050,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 1148579784} - m_RootOrder: 18 + m_RootOrder: 19 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1194502639 MonoBehaviour: @@ -1092,7 +1093,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 1148579784} - m_RootOrder: 14 + m_RootOrder: 15 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1202167596 MonoBehaviour: @@ -1490,6 +1491,64 @@ MonoBehaviour: hideIfEnum: {x: 0.25, y: 0.75} hideIfEnumFlag: {x: 0, y: 0} hideIfEnumFlagMulti: {x: 0, y: 0} +--- !u!1 &1536277548 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1536277549} + - component: {fileID: 1536277550} + m_Layer: 0 + m_Name: Hex + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1536277549 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1536277548} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1148579784} + m_RootOrder: 7 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1536277550 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1536277548} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a3ad78e38899d42479c9d5b1d73ef9b5, type: 3} + m_Name: + m_EditorClassIdentifier: + hexHexAssign: 42405 + hexDecimalAssign: 1234 + hexShort: 4660 + hexByte: 204 + hexULong: 18446744069720004216 + hexMinimumWidth8: 0 + hexMinimumWidth4: 291 + hexMinimumWidth1: 291 + hexMinimumWidth0: 291 + hexMaximumValue: 65535 + hexCantApply: 0 + nest1: + hexNested1: 43981 + nest2: + hexNested2: 4275878552 --- !u!1 &1552114399 GameObject: m_ObjectHideFlags: 0 @@ -1519,7 +1578,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 1148579784} - m_RootOrder: 8 + m_RootOrder: 9 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1552114401 MonoBehaviour: @@ -1864,7 +1923,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 1148579784} - m_RootOrder: 13 + m_RootOrder: 14 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1747151589 MonoBehaviour: @@ -2026,7 +2085,7 @@ Transform: m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 1148579784} - m_RootOrder: 17 + m_RootOrder: 18 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &1989156460 MonoBehaviour: diff --git a/Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/HexAttribute.cs b/Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/HexAttribute.cs new file mode 100644 index 00000000..08bc5589 --- /dev/null +++ b/Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/HexAttribute.cs @@ -0,0 +1,35 @@ +using System; +using UnityEngine; + +namespace NaughtyAttributes +{ + [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)] + public class HexAttribute : DrawerAttribute + { + public int MinimumDisplayWidth { get; set; } + + public HexAttribute(int minimumDisplayWidth = -1) + { + MinimumDisplayWidth = minimumDisplayWidth; + } + + public int GetDefaultWidthForType(string propertyTypeName) + { + return propertyTypeName switch + { + "byte" => 2, + "sbyte" => 2, + "char" => 4, + "int" => 8, + "uint" => 8, + "nint" => IntPtr.Size * 2, + "nuint" => UIntPtr.Size * 2, + "long" => 16, + "ulong" => 16, + "short" => 4, + "ushort" => 4, + _ => 0, + }; + } + } +} diff --git a/Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/HexAttribute.cs.meta b/Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/HexAttribute.cs.meta new file mode 100644 index 00000000..c64e5841 --- /dev/null +++ b/Assets/NaughtyAttributes/Scripts/Core/DrawerAttributes/HexAttribute.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6535845650e51014496208a7860fa8bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NaughtyAttributes/Scripts/Editor/PropertyDrawers/HexPropertyDrawer.cs b/Assets/NaughtyAttributes/Scripts/Editor/PropertyDrawers/HexPropertyDrawer.cs new file mode 100644 index 00000000..2fa378e3 --- /dev/null +++ b/Assets/NaughtyAttributes/Scripts/Editor/PropertyDrawers/HexPropertyDrawer.cs @@ -0,0 +1,78 @@ +using System.Globalization; +using UnityEditor; +using UnityEngine; + +namespace NaughtyAttributes.Editor +{ + [CustomPropertyDrawer(typeof(HexAttribute))] + public class HexPropertyDrawer : PropertyDrawerBase + { + private const string TypeWarningMessage = "{0} must be an integer type"; + + protected override float GetPropertyHeight_Internal(SerializedProperty property, GUIContent label) + { + bool validPropertyType = property.propertyType == SerializedPropertyType.Integer; + + return validPropertyType + ? GetPropertyHeight(property) + : GetPropertyHeight(property) + GetHelpBoxHeight(); + } + + protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label) + { + HexAttribute hexAttribute = (HexAttribute)attribute; + + EditorGUI.BeginProperty(rect, label, property); + + switch (property.propertyType) + { + case SerializedPropertyType.Integer: + DrawPropertyForInt(rect, property, label, hexAttribute); + break; + default: + string message = string.Format(TypeWarningMessage, property.name); + DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning); + break; + } + + EditorGUI.EndProperty(); + } + + + private static void DrawPropertyForInt(Rect rect, SerializedProperty property, GUIContent label, HexAttribute hexAttribute) + { + int width = hexAttribute.MinimumDisplayWidth; + + if (width < 0) + { + width = hexAttribute.GetDefaultWidthForType(property.type); + } + + string stringValue = width <= 0 + ? $"0x{property.longValue:X}" + : "0x" + property.longValue.ToString($"X{width}"); + + stringValue = EditorGUI.TextField(rect, label, stringValue).ToLower(); + + if (stringValue.StartsWith("0x")) + { + // strip the 0x from the beginning, then parse as hex. + string no0X = stringValue.Remove(0, 2); + if (long.TryParse(no0X, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out long resultHex)) + { + property.longValue = resultHex; + } + } + else if (long.TryParse(stringValue, NumberStyles.Any, CultureInfo.CurrentCulture, out long resultAny)) + { + // no 0x, parse the number as decimal + property.longValue = resultAny; + } + else if (string.IsNullOrWhiteSpace(stringValue)) + { + // no value, default to zero. + property.longValue = 0; + } + } + } +} diff --git a/Assets/NaughtyAttributes/Scripts/Editor/PropertyDrawers/HexPropertyDrawer.cs.meta b/Assets/NaughtyAttributes/Scripts/Editor/PropertyDrawers/HexPropertyDrawer.cs.meta new file mode 100644 index 00000000..8c546e92 --- /dev/null +++ b/Assets/NaughtyAttributes/Scripts/Editor/PropertyDrawers/HexPropertyDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8dee9e81c946a6a4487fab6ccd5920eb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/NaughtyAttributes/Scripts/Test/HexTest.cs b/Assets/NaughtyAttributes/Scripts/Test/HexTest.cs new file mode 100644 index 00000000..56be3956 --- /dev/null +++ b/Assets/NaughtyAttributes/Scripts/Test/HexTest.cs @@ -0,0 +1,51 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace NaughtyAttributes.Test +{ + public class HexTest : MonoBehaviour + { + [Hex] + public int hexHexAssign = 0xA5A5; + [Hex] + public int hexDecimalAssign = 1234; + [Hex] + public ushort hexShort = 0x1234; + [Hex] + public byte hexByte = 0xCC; + [Hex] + public ulong hexULong = 0xFFFFFFFF_12345678; + [Hex(MinimumDisplayWidth = 8)] + public int hexMinimumWidth8; + [Hex(MinimumDisplayWidth = 4)] + public int hexMinimumWidth4 = 0x123; + [Hex(MinimumDisplayWidth = 1)] + public int hexMinimumWidth1 = 0x123; + [Hex(MinimumDisplayWidth = 0)] + public int hexMinimumWidth0 = 0x123; + [Hex, MaxValue(ushort.MaxValue)] + public int hexMaximumValue = 0x0123FFFF; + + [Hex] + public float hexCantApply; + + public HexNest1 nest1; + } + + [System.Serializable] + public class HexNest1 + { + [Hex] + public int hexNested1 = 0xABCD; + + public HexNest2 nest2; + } + + [System.Serializable] + public class HexNest2 + { + [Hex] + public uint hexNested2 = 0xFEDCBA98; + } +} \ No newline at end of file diff --git a/Assets/NaughtyAttributes/Scripts/Test/HexTest.cs.meta b/Assets/NaughtyAttributes/Scripts/Test/HexTest.cs.meta new file mode 100644 index 00000000..91e834ab --- /dev/null +++ b/Assets/NaughtyAttributes/Scripts/Test/HexTest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a3ad78e38899d42479c9d5b1d73ef9b5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/README.md b/README.md index fa85e167..a7da316e 100644 --- a/README.md +++ b/README.md @@ -190,6 +190,21 @@ public class NaughtyComponent : MonoBehaviour ![inspector](https://github.com/dbrizov/NaughtyAttributes/blob/master/Assets/NaughtyAttributes/Documentation~/Expandable_Inspector.png) +### Hex +Draws the editor field for an integer in hexadecimal. Can be modified as hex, or decimal, but will always draw as hex. + +```csharp +public class NaughtyComponent : MonoBehaviour +{ + [Hex] + public int myHexValue = 0x1234; + [Hex] + public int myIntValue = 1234; +} +``` + +![inspector](https://github.com/dbrizov/NaughtyAttributes/blob/master/Assets/NaughtyAttributes/Documentation~/Hex_Inspector.png) + ### HorizontalLine ```csharp