-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
using RicUtils.Attributes; | ||
using RicUtils.Editor.Utilities; | ||
using System; | ||
using System.Collections.Generic; | ||
using UnityEditor; | ||
using UnityEngine; | ||
|
||
namespace RicUtils.Editor.AttributeDrawer | ||
{ | ||
[CustomPropertyDrawer(typeof(ConstantSelectorAttribute))] | ||
public class ConstantSelectorAttributeDrawer : PropertyDrawer | ||
{ | ||
private ConstantSelectorAttribute cachedProperty; | ||
private Type targetType; | ||
private string[] names; | ||
private object[] values; | ||
private int selectedIndex; | ||
private bool foundValue; | ||
|
||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) | ||
{ | ||
return EditorGUI.GetPropertyHeight(property, label); | ||
} | ||
|
||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | ||
{ | ||
CacheProperty(property); | ||
|
||
if (values == null || values.Length == 0) | ||
{ | ||
EditorGUI.PropertyField(position, property, label); | ||
return; | ||
} | ||
|
||
if (targetType != fieldInfo.FieldType) | ||
{ | ||
EditorGUI.HelpBox(position, $"[ConstantSelector] '{targetType}' is not the same as '{fieldInfo.FieldType}'", MessageType.Error); | ||
return; | ||
} | ||
|
||
if (!foundValue && selectedIndex == 0) | ||
{ | ||
EditorGUIHelper.DrawBox(position, Color.yellow); | ||
} | ||
|
||
EditorGUI.BeginChangeCheck(); | ||
selectedIndex = EditorGUI.Popup(position, label.text, selectedIndex, names); | ||
if (EditorGUI.EndChangeCheck()) | ||
{ | ||
fieldInfo.SetValue(property.serializedObject.targetObject, values[selectedIndex]); | ||
property.serializedObject.ApplyModifiedProperties(); | ||
EditorUtility.SetDirty(property.serializedObject.targetObject); | ||
} | ||
} | ||
|
||
private void CacheProperty(SerializedProperty property) | ||
{ | ||
if (cachedProperty == null) | ||
{ | ||
cachedProperty = attribute as ConstantSelectorAttribute; | ||
|
||
targetType = fieldInfo.FieldType; | ||
|
||
var fields = targetType.GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy); | ||
var properties = targetType.GetProperties(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy); | ||
|
||
List<string> names = new List<string>(); | ||
List<object> values = new List<object>(); | ||
|
||
foreach (var field in fields) | ||
{ | ||
if ((field.IsInitOnly || field.IsLiteral) && field.FieldType == targetType) | ||
{ | ||
names.Add(field.Name); | ||
values.Add(field.GetValue(null)); | ||
} | ||
} | ||
|
||
foreach (var p in properties) | ||
{ | ||
if (p.PropertyType == targetType) | ||
{ | ||
names.Add(p.Name); | ||
values.Add(p.GetValue(null)); | ||
} | ||
} | ||
|
||
var currentValue = fieldInfo.GetValue(property.serializedObject.targetObject); | ||
if (currentValue != null) | ||
{ | ||
for (int i = 0; i < values.Count; i++) | ||
{ | ||
if (currentValue.Equals(values[i])) | ||
{ | ||
foundValue = true; | ||
selectedIndex = i; | ||
} | ||
} | ||
} | ||
|
||
if (!foundValue) | ||
{ | ||
var value = fieldInfo.GetValue(property.serializedObject.targetObject); | ||
var valueString = value == null ? "NULL" : value.ToString(); | ||
names.Add("ERROR: NO " + valueString); | ||
values.Add(value); | ||
} | ||
|
||
this.names = names.ToArray(); | ||
this.values = values.ToArray(); | ||
} | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
using RicUtils.Attributes; | ||
using RicUtils.Utilities; | ||
using UnityEditor; | ||
using UnityEngine; | ||
|
||
namespace RicUtils.Editor.AttributeDrawer | ||
{ | ||
[CustomPropertyDrawer(typeof(MaxValueAttribute))] | ||
public class MaxValueAttributeDrawer : PropertyDrawer | ||
{ | ||
private MaxValueAttribute cachedAttribute; | ||
|
||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) | ||
{ | ||
return EditorGUI.GetPropertyHeight(property, label); | ||
} | ||
|
||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | ||
{ | ||
if (cachedAttribute == null) cachedAttribute = attribute as MaxValueAttribute; | ||
|
||
if (!property.IsNumerical() && !property.IsVector()) | ||
{ | ||
EditorGUI.HelpBox(position, "[MaxValue] used with non-numeric property", MessageType.Warning); | ||
return; | ||
} | ||
if ((property.IsNumerical() && property.HandleMaxNumericalValues(cachedAttribute.X)) || | ||
(property.IsVectorInt() && property.HandleMaxVectorIntValues(new Vector3Int((int)cachedAttribute.X, (int)cachedAttribute.Y, (int)cachedAttribute.Z))) || | ||
(property.IsVectorFloat() && property.HandleMaxVectorValues(new Vector4(cachedAttribute.X, cachedAttribute.Y, cachedAttribute.Z, cachedAttribute.W)))) | ||
property.serializedObject.ApplyModifiedProperties(); | ||
EditorGUI.PropertyField(position, property, label, true); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
using RicUtils.Attributes; | ||
using RicUtils.Utilities; | ||
using UnityEditor; | ||
using UnityEngine; | ||
|
||
namespace RicUtils.Editor | ||
{ | ||
[CustomPropertyDrawer(typeof(MinValueAttribute))] | ||
public class MinValueAttributeDrawer : PropertyDrawer | ||
{ | ||
private MinValueAttribute cachedAttribute; | ||
|
||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) | ||
{ | ||
return EditorGUI.GetPropertyHeight(property, label); | ||
} | ||
|
||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | ||
{ | ||
if (cachedAttribute == null) cachedAttribute = attribute as MinValueAttribute; | ||
|
||
if (!property.IsNumerical() && !property.IsVector()) | ||
{ | ||
EditorGUI.HelpBox(position, "[MinValue] used with non-numeric property", MessageType.Warning); | ||
return; | ||
} | ||
if ((property.IsNumerical() && property.HandleMinNumericalValues(cachedAttribute.X)) || | ||
(property.IsVectorInt() && property.HandleMinVectorIntValues(new Vector3Int((int)cachedAttribute.X, (int)cachedAttribute.Y, (int)cachedAttribute.Z))) || | ||
(property.IsVectorFloat() && property.HandleMinVectorValues(new Vector4(cachedAttribute.X, cachedAttribute.Y, cachedAttribute.Z, cachedAttribute.W)))) | ||
property.serializedObject.ApplyModifiedProperties(); | ||
EditorGUI.PropertyField(position, property, label, true); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
using RicUtils.Attributes; | ||
using RicUtils.Editor.Utilities; | ||
using System.Reflection; | ||
using UnityEditor; | ||
using UnityEngine; | ||
|
||
namespace RicUtils.Editor.AttributeDrawer | ||
{ | ||
[CustomPropertyDrawer(typeof(MustBeAssignedAttribute))] | ||
public class MustBeAssignedAttributeDrawer : PropertyDrawer | ||
{ | ||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | ||
{ | ||
if (MustBeAssignedCheck.GetError(fieldInfo, property.serializedObject.targetObject) > 0) | ||
{ | ||
EditorGUIHelper.DrawBox(position, Color.red); | ||
} | ||
|
||
EditorGUI.PropertyField(position, property, label); | ||
} | ||
} | ||
|
||
[InitializeOnLoad] | ||
internal class MustBeAssignedCheck : UnityEditor.AssetModificationProcessor | ||
{ | ||
static MustBeAssignedCheck() | ||
{ | ||
Assert(); | ||
} | ||
|
||
public static string[] OnWillSaveAssets(string[] paths) | ||
{ | ||
if (paths.Length == 1 && (paths[0] == null || paths[0].EndsWith(".prefab"))) return paths; | ||
|
||
Assert(); | ||
|
||
return paths; | ||
} | ||
|
||
private static void Assert() | ||
{ | ||
var behaviours = Object.FindObjectsOfType<MonoBehaviour>(true); | ||
|
||
foreach (var behaviour in behaviours) | ||
{ | ||
if (behaviour == null) continue; | ||
|
||
var objType = behaviour.GetType(); | ||
var fields = objType.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); | ||
|
||
foreach (var field in fields) | ||
{ | ||
if (!field.IsDefined(typeof(MustBeAssignedAttribute), false) && !field.IsDefined(typeof(SerializeField), false)) continue; | ||
|
||
var error = GetError(field, behaviour); | ||
|
||
switch (error) | ||
{ | ||
case 1: | ||
Debug.LogError($"{objType.Name}: '{field.Name}' is Value Type with default value", behaviour); | ||
break; | ||
case 2: | ||
Debug.LogError($"{objType.Name}: '{field.Name}' not assigned (null value)", behaviour); | ||
break; | ||
case 3: | ||
Debug.LogError($"{objType.Name}: '{field.Name}' not assigned (empty string)", behaviour); | ||
break; | ||
case 4: | ||
Debug.LogError($"{objType.Name}: '{field.Name}' not assigned (empty array)", behaviour); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
public static int GetError(FieldInfo field, Object targetObject) | ||
{ | ||
var value = field.GetValue(targetObject); | ||
bool valueTypeWithDefaultValue = field.FieldType.IsValueType && System.Activator.CreateInstance(field.FieldType).Equals(value); | ||
if (valueTypeWithDefaultValue) | ||
{ | ||
return 1; | ||
} | ||
|
||
|
||
bool nullReferenceType = value == null || value.Equals(null); | ||
if (nullReferenceType) | ||
{ | ||
return 2; | ||
} | ||
|
||
|
||
bool emptyString = field.FieldType == typeof(string) && (string)value == string.Empty; | ||
if (emptyString) | ||
{ | ||
return 3; | ||
} | ||
|
||
|
||
var arr = value as System.Array; | ||
bool emptyArray = arr != null && arr.Length == 0; | ||
if (emptyArray) | ||
{ | ||
return 4; | ||
} | ||
|
||
return 0; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
using RicUtils.Attributes; | ||
using RicUtils.Utilities; | ||
using UnityEditor; | ||
using UnityEngine; | ||
|
||
namespace RicUtils.Editor.AttributeDrawer | ||
{ | ||
[CustomPropertyDrawer(typeof(NegativeValueOnlyAttribute))] | ||
public class NegativeValueOnlyAttributeDrawer : PropertyDrawer | ||
{ | ||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) | ||
{ | ||
return EditorGUI.GetPropertyHeight(property, label); | ||
} | ||
|
||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | ||
{ | ||
if (!property.IsNumerical() && !property.IsVector()) | ||
{ | ||
EditorGUI.HelpBox(position, "[NegativeValueOnly] used with non-numeric property", MessageType.Warning); | ||
return; | ||
} | ||
if (property.HandleMaxValues(0)) property.serializedObject.ApplyModifiedProperties(); | ||
EditorGUI.PropertyField(position, property, label, true); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.