diff --git a/Editor/ObjectEditor.cs b/Editor/ObjectEditor.cs index 681a290..ef9932a 100644 --- a/Editor/ObjectEditor.cs +++ b/Editor/ObjectEditor.cs @@ -1,5 +1,4 @@ -using System.Reflection; -using Module.Inspector.Editor.Utilities; +using Module.Inspector.Editor.Utilities; using UnityEditor; using UnityEngine; @@ -21,25 +20,20 @@ namespace Module.Inspector.Editor if (!IsValidTarget()) return; - FieldInfo[] fields = EditorHiddenFieldUtility.Query(target); + EditorHiddenFieldUtility.EditableFieldInfo[] fields = EditorHiddenFieldUtility.Query(target); if (fields.Length == 0) return; float totalHeight = EditorHiddenFieldUtility.CalculateHeight(fields) + EditorGUIUtility.singleLineHeight * 2; GUILayout.Space(totalHeight); - - var position = new Rect(0, 0, 1, 1); - - if (Event.current.type == EventType.Repaint) - { - position = GUILayoutUtility.GetLastRect(); - position.y -= totalHeight; - #if UNITY_2020_1_OR_NEWER - position.width = EditorGUIUtility.currentViewWidth - 22.0f; - #endif - } + Rect position = GUILayoutUtility.GetLastRect(); + position.y -= totalHeight; + + #if UNITY_2020_1_OR_NEWER + position.width = EditorGUIUtility.currentViewWidth - 22.0f; + #endif position.y = position.yMax + EditorGUIUtility.singleLineHeight; position.height = EditorGUIUtility.singleLineHeight; diff --git a/Editor/Utilities/EditorHiddenFieldUtility.cs b/Editor/Utilities/EditorHiddenFieldUtility.cs index 109b95d..fc5cf9b 100644 --- a/Editor/Utilities/EditorHiddenFieldUtility.cs +++ b/Editor/Utilities/EditorHiddenFieldUtility.cs @@ -9,20 +9,20 @@ namespace Module.Inspector.Editor.Utilities { internal static class EditorHiddenFieldUtility { - private static Dictionary CACHED_TYPE_TO_PRIMARIES; + private static Dictionary CACHED_TYPE_TO_PRIMARIES; - public static FieldInfo[] Query(Object target) + public static EditableFieldInfo[] Query(Object target) { Type type = target.GetType(); var att = type.GetCustomAttribute(); if (att == null) - return new FieldInfo[0]; + return new EditableFieldInfo[0]; if (CACHED_TYPE_TO_PRIMARIES == null) - CACHED_TYPE_TO_PRIMARIES = new Dictionary(); + CACHED_TYPE_TO_PRIMARIES = new Dictionary(); - if (CACHED_TYPE_TO_PRIMARIES.TryGetValue(type, out FieldInfo[] fields)) + if (CACHED_TYPE_TO_PRIMARIES.TryGetValue(type, out EditableFieldInfo[] fields)) return fields; fields = InternalFetch(type, att.UseFieldProperty); @@ -30,39 +30,66 @@ namespace Module.Inspector.Editor.Utilities return fields; } - public static float CalculateHeight(FieldInfo[] fields) + public static float CalculateHeight(EditableFieldInfo[] fields) { return EditorGUIUtility.singleLineHeight * fields.Length; } - public static void Draw(Rect rect, FieldInfo field, Object target) + public static void Draw(Rect rect, EditableFieldInfo field, Object target) { bool prevEnabled = GUI.enabled; - GUI.enabled = false; + GUI.enabled = field.editable; string nicifiedName = ObjectNames.NicifyVariableName(field.Name); - if (field.FieldType == typeof(float)) - EditorGUI.FloatField(rect, nicifiedName, (float)field.GetValue(target)); - else if (field.FieldType == typeof(int)) - EditorGUI.IntField(rect, nicifiedName, (int)field.GetValue(target)); - else if (field.FieldType == typeof(double)) - EditorGUI.DoubleField(rect, nicifiedName, (double)field.GetValue(target)); - else if (field.FieldType == typeof(string)) - EditorGUI.TextField(rect, nicifiedName, (string)field.GetValue(target)); - else if (typeof(Object).IsAssignableFrom(field.FieldType)) - EditorGUI.ObjectField(rect, nicifiedName, (Object)field.GetValue(target), typeof(Object), true); + if (field.IsType()) + { + float temp = EditorGUI.FloatField(rect, nicifiedName, field.GetValue(target)); + + if (field.editable) + field.SetValue(target, temp); + } + else if (field.IsType()) + { + int temp = EditorGUI.IntField(rect, nicifiedName, field.GetValue(target)); + + if (field.editable) + field.SetValue(target, temp); + } + else if (field.IsType()) + { + double temp = EditorGUI.DoubleField(rect, nicifiedName, field.GetValue(target)); + + if (field.editable) + field.SetValue(target, temp); + } + else if (field.IsType()) + { + string temp = EditorGUI.TextField(rect, nicifiedName, field.GetValue(target)); + + if (field.editable) + field.SetValue(target, temp); + } + else if (field.IsAssignableFrom()) + { + Object temp = EditorGUI.ObjectField(rect, nicifiedName, field.GetValue(target), typeof(Object), true); + + if (field.editable) + field.SetValue(target, temp); + } else + { EditorGUI.LabelField(rect, ObjectNames.NicifyVariableName(field.Name), "Unsupported type"); + } GUI.enabled = prevEnabled; } - private static FieldInfo[] InternalFetch(Type type, bool useFieldProperty) + private static EditableFieldInfo[] InternalFetch(Type type, bool useFieldProperty) { const BindingFlags FLAGS = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo[] fields = type.GetFields(FLAGS); - var list = new List(fields.Length); + var list = new List(fields.Length); for (var i = 0; i < fields.Length; i++) { @@ -70,11 +97,48 @@ namespace Module.Inspector.Editor.Utilities if (fi.GetCustomAttribute() == null && fi.GetCustomAttribute() == null) continue; - if (!useFieldProperty || fi.GetCustomAttribute() != null) - list.Add(fi); + + var att = fi.GetCustomAttribute(); + + if (!useFieldProperty || att != null) + list.Add(new EditableFieldInfo(fi, att != null && att.editable)); } return list.ToArray(); } + + public sealed class EditableFieldInfo + { + public readonly FieldInfo fieldInfo; + public readonly bool editable; + + public string Name => fieldInfo.Name; + + public EditableFieldInfo(FieldInfo fieldInfo, bool editable) + { + this.fieldInfo = fieldInfo; + this.editable = editable; + } + + public T GetValue(object target) + { + return (T)fieldInfo.GetValue(target); + } + + public void SetValue(object target, T value) + { + fieldInfo.SetValue(target, value); + } + + public bool IsType() + { + return fieldInfo.FieldType == typeof(T); + } + + public bool IsAssignableFrom() + { + return typeof(T).IsAssignableFrom(fieldInfo.FieldType); + } + } } } \ No newline at end of file diff --git a/Editor/ValueModifiers/AssetsOnlyAttributeDrawer.cs b/Editor/ValueModifiers/AssetsOnlyAttributeDrawer.cs new file mode 100644 index 0000000..5961bbd --- /dev/null +++ b/Editor/ValueModifiers/AssetsOnlyAttributeDrawer.cs @@ -0,0 +1,25 @@ +using UnityEditor; +using UnityEngine; + +namespace Module.Inspector.Editor +{ + [CustomPropertyDrawer(typeof(AssetsOnlyAttribute))] + internal sealed class AssetsOnlyAttributeDrawer : ValueModifierPropertyDrawer + { + public override void Modify(ValueModifierPropertyAttribute attribute, SerializedProperty property) + { + if (property.propertyType != SerializedPropertyType.ObjectReference) + return; + + Object obj = property.objectReferenceValue; + + if (obj != null && !IsValid(obj)) + property.objectReferenceValue = null; + } + + private static bool IsValid(Object obj) + { + return AssetDatabase.Contains(obj); + } + } +} \ No newline at end of file diff --git a/Editor/ValueModifiers/AssetsOnlyAttributeDrawer.cs.meta b/Editor/ValueModifiers/AssetsOnlyAttributeDrawer.cs.meta new file mode 100644 index 0000000..f6501a4 --- /dev/null +++ b/Editor/ValueModifiers/AssetsOnlyAttributeDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 84b797e92aa740e4866d71c9afaa6ff2 +timeCreated: 1660250173 \ No newline at end of file diff --git a/Editor/ValueModifiers/AssignAssetIfNullAttributeDrawer.cs b/Editor/ValueModifiers/AssignAssetIfNullAttributeDrawer.cs new file mode 100644 index 0000000..1de9cc2 --- /dev/null +++ b/Editor/ValueModifiers/AssignAssetIfNullAttributeDrawer.cs @@ -0,0 +1,43 @@ +using System; +using UnityEditor; +using Object = UnityEngine.Object; + +namespace Module.Inspector.Editor +{ + [CustomPropertyDrawer(typeof(AssignAssetIfNullAttribute))] + internal sealed class AssignAssetIfNullAttributeDrawer : ValueModifierPropertyDrawer + { + public override void Modify(ValueModifierPropertyAttribute attribute, SerializedProperty property) + { + if (property.propertyType != SerializedPropertyType.ObjectReference) + return; + if (property.objectReferenceValue != null) + return; + + var att = (AssignAssetIfNullAttribute)attribute; + Type type = att.useType ? att.type : property.GetValueType(); + property.objectReferenceValue = AssignAsset(type, att.filter, att.searchFolders); + } + + private static Object AssignAsset(Type type, string filter, string[] folders) + { + string[] guids; + + if (folders != null && folders.Length != 0) + guids = AssetDatabase.FindAssets($"{type.Name} {filter}", folders); + else + guids = AssetDatabase.FindAssets($"{type.Name} {filter}"); + + for (var i = 0; i < guids.Length; i++) + { + string path = AssetDatabase.GUIDToAssetPath(guids[i]); + Object obj = AssetDatabase.LoadAssetAtPath(path, type); + + if (obj != null) + return obj; + } + + return null; + } + } +} \ No newline at end of file diff --git a/Editor/ValueModifiers/AssignAssetIfNullAttributeDrawer.cs.meta b/Editor/ValueModifiers/AssignAssetIfNullAttributeDrawer.cs.meta new file mode 100644 index 0000000..1e088e6 --- /dev/null +++ b/Editor/ValueModifiers/AssignAssetIfNullAttributeDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 68325a7d22ed40e2aae8e00fad5f05dc +timeCreated: 1661599398 \ No newline at end of file diff --git a/Editor/ValueModifiers/AssignIfNullAttributeDrawer.cs b/Editor/ValueModifiers/AssignComponentIfNullAttributeDrawer.cs similarity index 83% rename from Editor/ValueModifiers/AssignIfNullAttributeDrawer.cs rename to Editor/ValueModifiers/AssignComponentIfNullAttributeDrawer.cs index 021544b..3ae5e73 100644 --- a/Editor/ValueModifiers/AssignIfNullAttributeDrawer.cs +++ b/Editor/ValueModifiers/AssignComponentIfNullAttributeDrawer.cs @@ -5,8 +5,8 @@ using Object = UnityEngine.Object; namespace Module.Inspector.Editor { - [CustomPropertyDrawer(typeof(AssignIfNullAttribute))] - internal sealed class AssignIfNullAttributeDrawer : ValueModifierPropertyDrawer + [CustomPropertyDrawer(typeof(AssignComponentIfNullAttribute))] + internal sealed class AssignComponentIfNullAttributeDrawer : ValueModifierPropertyDrawer { public override void Modify(ValueModifierPropertyAttribute attribute, SerializedProperty property) { @@ -15,7 +15,7 @@ namespace Module.Inspector.Editor if (property.objectReferenceValue != null) return; - var att = (AssignIfNullAttribute)attribute; + var att = (AssignComponentIfNullAttribute)attribute; Type type = att.useType ? att.type : property.GetValueType(); if (!typeof(Component).IsAssignableFrom(type)) diff --git a/Editor/ValueModifiers/AssignComponentIfNullAttributeDrawer.cs.meta b/Editor/ValueModifiers/AssignComponentIfNullAttributeDrawer.cs.meta new file mode 100644 index 0000000..b2598d9 --- /dev/null +++ b/Editor/ValueModifiers/AssignComponentIfNullAttributeDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 38c05c2014ac40c0915f6e36df16c7e4 +timeCreated: 1661600081 \ No newline at end of file diff --git a/Editor/ValueModifiers/AssignIfNullAttributeDrawer.cs.meta b/Editor/ValueModifiers/AssignIfNullAttributeDrawer.cs.meta deleted file mode 100644 index fd1013c..0000000 --- a/Editor/ValueModifiers/AssignIfNullAttributeDrawer.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: e029b0d7c1384ab2b961e74a2bf23fe0 -timeCreated: 1638695373 \ No newline at end of file diff --git a/Editor/ValueModifiers/SceneObjectsOnlyAttributeDrawer.cs b/Editor/ValueModifiers/SceneObjectsOnlyAttributeDrawer.cs new file mode 100644 index 0000000..22a920c --- /dev/null +++ b/Editor/ValueModifiers/SceneObjectsOnlyAttributeDrawer.cs @@ -0,0 +1,25 @@ +using UnityEditor; +using UnityEngine; + +namespace Module.Inspector.Editor +{ + [CustomPropertyDrawer(typeof(SceneObjectsOnlyAttribute))] + internal sealed class SceneObjectsOnlyAttributeDrawer : ValueModifierPropertyDrawer + { + public override void Modify(ValueModifierPropertyAttribute attribute, SerializedProperty property) + { + if (property.propertyType != SerializedPropertyType.ObjectReference) + return; + + Object obj = property.objectReferenceValue; + + if (obj != null && !IsValid(obj)) + property.objectReferenceValue = null; + } + + private static bool IsValid(Object obj) + { + return !AssetDatabase.Contains(obj); + } + } +} \ No newline at end of file diff --git a/Editor/ValueModifiers/SceneObjectsOnlyAttributeDrawer.cs.meta b/Editor/ValueModifiers/SceneObjectsOnlyAttributeDrawer.cs.meta new file mode 100644 index 0000000..b19f291 --- /dev/null +++ b/Editor/ValueModifiers/SceneObjectsOnlyAttributeDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 48dbd634fecb45699637d9dfff17f8e9 +timeCreated: 1660250619 \ No newline at end of file diff --git a/README.md b/README.md index 0f627be..dc309b5 100644 --- a/README.md +++ b/README.md @@ -127,14 +127,20 @@ List of all value attributes: * `ArrayIndex` * Clamps value between other fields array size `[0;size[` -* `AssignIfNull` +* `AssetsOnly` + * If value is not an asset it will be set to null +* `AssignAssetIfNull` + * If value is null will assign first asset found using AssetDatabase.FindAssets +* `AssignComponentIfNull` * If value is null will either use field or custom type to get from self or children * `LargerThanField` * If value is greater than other fields value, then set value to other fields value * `MaxValue` * If value is greater than max value, then set value to max value * `MinValue` - * If value is less than min value, then set value to min value + * If value is less than min value, then set value to min value +* `SceneObjectsOnly` + * If value is an asset it will be set to null * `SmallerThanField` * If value is less than other fields value, then set value to other fields value diff --git a/Runtime/HiddenFields/ShowHiddenFieldAttribute.cs b/Runtime/HiddenFields/ShowHiddenFieldAttribute.cs index 65fe610..df8ce77 100644 --- a/Runtime/HiddenFields/ShowHiddenFieldAttribute.cs +++ b/Runtime/HiddenFields/ShowHiddenFieldAttribute.cs @@ -6,5 +6,11 @@ namespace Module.Inspector [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)] public sealed class ShowHiddenFieldAttribute : PropertyAttribute { + public readonly bool editable; + + public ShowHiddenFieldAttribute(bool editable = false) + { + this.editable = editable; + } } } \ No newline at end of file diff --git a/Runtime/ValueModifiers/AssetsOnlyAttribute.cs b/Runtime/ValueModifiers/AssetsOnlyAttribute.cs new file mode 100644 index 0000000..f66df47 --- /dev/null +++ b/Runtime/ValueModifiers/AssetsOnlyAttribute.cs @@ -0,0 +1,14 @@ +using System; +using UnityEngine.Scripting; + +namespace Module.Inspector +{ + [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)] + public sealed class AssetsOnlyAttribute : ValueModifierPropertyAttribute + { + [Preserve] + public AssetsOnlyAttribute() + { + } + } +} \ No newline at end of file diff --git a/Runtime/ValueModifiers/AssetsOnlyAttribute.cs.meta b/Runtime/ValueModifiers/AssetsOnlyAttribute.cs.meta new file mode 100644 index 0000000..c8d77e4 --- /dev/null +++ b/Runtime/ValueModifiers/AssetsOnlyAttribute.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: dd2c5463415149c39cafdfb013ffd252 +timeCreated: 1660247975 \ No newline at end of file diff --git a/Runtime/ValueModifiers/AssignAssetIfNullAttribute.cs b/Runtime/ValueModifiers/AssignAssetIfNullAttribute.cs new file mode 100644 index 0000000..e2883d5 --- /dev/null +++ b/Runtime/ValueModifiers/AssignAssetIfNullAttribute.cs @@ -0,0 +1,39 @@ +using System; + +namespace Module.Inspector +{ + [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)] + public sealed class AssignAssetIfNullAttribute : ValueModifierPropertyAttribute + { + public readonly bool useType; + public readonly Type type; + public readonly string filter; + public readonly string[] searchFolders; + + public AssignAssetIfNullAttribute(string[] searchFolders = null) + { + this.searchFolders = searchFolders; + } + + public AssignAssetIfNullAttribute(string filter, string[] searchFolders = null) + { + this.filter = filter; + this.searchFolders = searchFolders; + } + + public AssignAssetIfNullAttribute(Type type, string[] searchFolders = null) + { + this.type = type; + this.searchFolders = searchFolders; + useType = true; + } + + public AssignAssetIfNullAttribute(Type type, string filter, string[] searchFolders = null) + { + this.type = type; + this.filter = filter; + this.searchFolders = searchFolders; + useType = true; + } + } +} \ No newline at end of file diff --git a/Runtime/ValueModifiers/AssignAssetIfNullAttribute.cs.meta b/Runtime/ValueModifiers/AssignAssetIfNullAttribute.cs.meta new file mode 100644 index 0000000..bc1c1f1 --- /dev/null +++ b/Runtime/ValueModifiers/AssignAssetIfNullAttribute.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 82c31267a89846069809fd3085f7026e +timeCreated: 1661366494 \ No newline at end of file diff --git a/Runtime/ValueModifiers/AssignIfNullAttribute.cs b/Runtime/ValueModifiers/AssignComponentIfNullAttribute.cs similarity index 53% rename from Runtime/ValueModifiers/AssignIfNullAttribute.cs rename to Runtime/ValueModifiers/AssignComponentIfNullAttribute.cs index 81d71f7..4e86532 100644 --- a/Runtime/ValueModifiers/AssignIfNullAttribute.cs +++ b/Runtime/ValueModifiers/AssignComponentIfNullAttribute.cs @@ -3,30 +3,19 @@ using System; namespace Module.Inspector { [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)] - public sealed class AssignIfNullAttribute : ValueModifierPropertyAttribute + public sealed class AssignComponentIfNullAttribute : ValueModifierPropertyAttribute { + public readonly bool includeChildren; public readonly bool useType; public readonly Type type; - public readonly bool includeChildren; - public AssignIfNullAttribute() + public AssignComponentIfNullAttribute(bool includeChildren = false) { - useType = false; - } - - public AssignIfNullAttribute(bool includeChildren) - { - useType = false; this.includeChildren = includeChildren; + useType = false; } - - public AssignIfNullAttribute(Type type) - { - this.type = type; - useType = true; - } - - public AssignIfNullAttribute(Type type, bool includeChildren) + + public AssignComponentIfNullAttribute(Type type, bool includeChildren = false) { this.type = type; this.includeChildren = includeChildren; diff --git a/Runtime/ValueModifiers/AssignComponentIfNullAttribute.cs.meta b/Runtime/ValueModifiers/AssignComponentIfNullAttribute.cs.meta new file mode 100644 index 0000000..61cc7ee --- /dev/null +++ b/Runtime/ValueModifiers/AssignComponentIfNullAttribute.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 50df169977e042c4bfb5dcf29b06c86c +timeCreated: 1661598908 \ No newline at end of file diff --git a/Runtime/ValueModifiers/AssignIfNullAttribute.cs.meta b/Runtime/ValueModifiers/AssignIfNullAttribute.cs.meta deleted file mode 100644 index 687a964..0000000 --- a/Runtime/ValueModifiers/AssignIfNullAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: dfd8ecaea012b084f994832dd519d850 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/ValueModifiers/SceneObjectsOnlyAttribute.cs b/Runtime/ValueModifiers/SceneObjectsOnlyAttribute.cs new file mode 100644 index 0000000..88b5db4 --- /dev/null +++ b/Runtime/ValueModifiers/SceneObjectsOnlyAttribute.cs @@ -0,0 +1,14 @@ +using System; +using UnityEngine.Scripting; + +namespace Module.Inspector +{ + [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)] + public sealed class SceneObjectsOnlyAttribute : ValueModifierPropertyAttribute + { + [Preserve] + public SceneObjectsOnlyAttribute() + { + } + } +} \ No newline at end of file diff --git a/Runtime/ValueModifiers/SceneObjectsOnlyAttribute.cs.meta b/Runtime/ValueModifiers/SceneObjectsOnlyAttribute.cs.meta new file mode 100644 index 0000000..b0bc9f2 --- /dev/null +++ b/Runtime/ValueModifiers/SceneObjectsOnlyAttribute.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a5113fd42950401b823cee1be6f3450b +timeCreated: 1660250588 \ No newline at end of file diff --git a/package.json b/package.json index 1cfd52f..82b047e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.module.inspector", - "version": "1.7.0", + "version": "1.8.0", "displayName": "Module.Inspector", "description": "Custom inspector with various useful property drawers", "unity": "2019.2",