You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CrowdControl/Assets/Plugins/NaughtyAttributes/Scripts/Editor/PropertyDrawers/AnimatorParamPropertyDrawer.cs

174 lines
6.0 KiB
C#

3 months ago
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;
namespace NaughtyAttributes.Editor
{
[CustomPropertyDrawer(typeof(AnimatorParamAttribute))]
public class AnimatorParamPropertyDrawer : PropertyDrawerBase
{
private const string InvalidAnimatorControllerWarningMessage = "Target animator controller is null";
private const string InvalidTypeWarningMessage = "{0} must be an int or a string";
protected override float GetPropertyHeight_Internal(SerializedProperty property, GUIContent label)
{
AnimatorParamAttribute animatorParamAttribute = PropertyUtility.GetAttribute<AnimatorParamAttribute>(property);
bool validAnimatorController = GetAnimatorController(property, animatorParamAttribute.AnimatorName) != null;
bool validPropertyType = property.propertyType == SerializedPropertyType.Integer || property.propertyType == SerializedPropertyType.String;
return (validAnimatorController && validPropertyType)
? GetPropertyHeight(property)
: GetPropertyHeight(property) + GetHelpBoxHeight();
}
protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(rect, label, property);
AnimatorParamAttribute animatorParamAttribute = PropertyUtility.GetAttribute<AnimatorParamAttribute>(property);
AnimatorController animatorController = GetAnimatorController(property, animatorParamAttribute.AnimatorName);
if (animatorController == null)
{
DrawDefaultPropertyAndHelpBox(rect, property, InvalidAnimatorControllerWarningMessage, MessageType.Warning);
return;
}
int parametersCount = animatorController.parameters.Length;
List<AnimatorControllerParameter> animatorParameters = new List<AnimatorControllerParameter>(parametersCount);
for (int i = 0; i < parametersCount; i++)
{
AnimatorControllerParameter parameter = animatorController.parameters[i];
if (animatorParamAttribute.AnimatorParamType == null || parameter.type == animatorParamAttribute.AnimatorParamType)
{
animatorParameters.Add(parameter);
}
}
switch (property.propertyType)
{
case SerializedPropertyType.Integer:
DrawPropertyForInt(rect, property, label, animatorParameters);
break;
case SerializedPropertyType.String:
DrawPropertyForString(rect, property, label, animatorParameters);
break;
default:
DrawDefaultPropertyAndHelpBox(rect, property, string.Format(InvalidTypeWarningMessage, property.name), MessageType.Warning);
break;
}
EditorGUI.EndProperty();
}
private static void DrawPropertyForInt(Rect rect, SerializedProperty property, GUIContent label, List<AnimatorControllerParameter> animatorParameters)
{
int paramNameHash = property.intValue;
int index = 0;
for (int i = 0; i < animatorParameters.Count; i++)
{
if (paramNameHash == animatorParameters[i].nameHash)
{
index = i + 1; // +1 because the first option is reserved for (None)
break;
}
}
string[] displayOptions = GetDisplayOptions(animatorParameters);
int newIndex = EditorGUI.Popup(rect, label.text, index, displayOptions);
int newValue = newIndex == 0 ? 0 : animatorParameters[newIndex - 1].nameHash;
if (property.intValue != newValue)
{
property.intValue = newValue;
}
}
private static void DrawPropertyForString(Rect rect, SerializedProperty property, GUIContent label, List<AnimatorControllerParameter> animatorParameters)
{
string paramName = property.stringValue;
int index = 0;
for (int i = 0; i < animatorParameters.Count; i++)
{
if (paramName.Equals(animatorParameters[i].name, System.StringComparison.Ordinal))
{
index = i + 1; // +1 because the first option is reserved for (None)
break;
}
}
string[] displayOptions = GetDisplayOptions(animatorParameters);
int newIndex = EditorGUI.Popup(rect, label.text, index, displayOptions);
string newValue = newIndex == 0 ? null : animatorParameters[newIndex - 1].name;
if (!property.stringValue.Equals(newValue, System.StringComparison.Ordinal))
{
property.stringValue = newValue;
}
}
private static string[] GetDisplayOptions(List<AnimatorControllerParameter> animatorParams)
{
string[] displayOptions = new string[animatorParams.Count + 1];
displayOptions[0] = "(None)";
for (int i = 0; i < animatorParams.Count; i++)
{
displayOptions[i + 1] = animatorParams[i].name;
}
return displayOptions;
}
private static AnimatorController GetAnimatorController(SerializedProperty property, string animatorName)
{
object target = PropertyUtility.GetTargetObjectWithProperty(property);
FieldInfo animatorFieldInfo = ReflectionUtility.GetField(target, animatorName);
if (animatorFieldInfo != null &&
animatorFieldInfo.FieldType == typeof(Animator))
{
Animator animator = animatorFieldInfo.GetValue(target) as Animator;
if (animator != null)
{
AnimatorController animatorController = animator.runtimeAnimatorController as AnimatorController;
return animatorController;
}
}
PropertyInfo animatorPropertyInfo = ReflectionUtility.GetProperty(target, animatorName);
if (animatorPropertyInfo != null &&
animatorPropertyInfo.PropertyType == typeof(Animator))
{
Animator animator = animatorPropertyInfo.GetValue(target) as Animator;
if (animator != null)
{
AnimatorController animatorController = animator.runtimeAnimatorController as AnimatorController;
return animatorController;
}
}
MethodInfo animatorGetterMethodInfo = ReflectionUtility.GetMethod(target, animatorName);
if (animatorGetterMethodInfo != null &&
animatorGetterMethodInfo.ReturnType == typeof(Animator) &&
animatorGetterMethodInfo.GetParameters().Length == 0)
{
Animator animator = animatorGetterMethodInfo.Invoke(target, null) as Animator;
if (animator != null)
{
AnimatorController animatorController = animator.runtimeAnimatorController as AnimatorController;
return animatorController;
}
}
return null;
}
}
}