forked from Shardstone/trail-into-darkness
105 lines
4.4 KiB
C#
105 lines
4.4 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
#endif
|
|
|
|
namespace InspectorToolkit {
|
|
public class AnimatorParameterAttribute : PropertyAttribute {
|
|
public readonly string animatorPropertyName;
|
|
public bool allParameterTypes;
|
|
public AnimatorControllerParameterType parameterType;
|
|
|
|
public AnimatorParameterAttribute(string animatorPropertyName) {
|
|
this.animatorPropertyName = animatorPropertyName;
|
|
allParameterTypes = true;
|
|
}
|
|
|
|
public AnimatorParameterAttribute(string animatorPropertyName, AnimatorControllerParameterType parameterType) {
|
|
this.animatorPropertyName = animatorPropertyName;
|
|
allParameterTypes = false;
|
|
this.parameterType = parameterType;
|
|
}
|
|
}
|
|
}
|
|
#if UNITY_EDITOR
|
|
namespace InspectorToolkit.Internal {
|
|
[CustomPropertyDrawer(typeof(AnimatorParameterAttribute))]
|
|
public class AnimatorParameterAttributeDrawer : PropertyDrawer {
|
|
private bool hasAnimator;
|
|
private Animator animator;
|
|
|
|
private string[] parameterNames;
|
|
|
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
|
|
label = EditorGUI.BeginProperty(position, label, property);
|
|
position = EditorGUI.PrefixLabel(position, label);
|
|
|
|
if(parameterNames == null) {
|
|
var animatorParameterAttribute = (AnimatorParameterAttribute)attribute;
|
|
string animatorFieldName = animatorParameterAttribute.animatorPropertyName;
|
|
parameterNames = UpdateParameterNames(property, animatorFieldName, animatorParameterAttribute.allParameterTypes, animatorParameterAttribute.parameterType);
|
|
}
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
|
|
bool didChange = false;
|
|
if(parameterNames is { Length: > 0 }) {
|
|
int parameterIndex = Array.IndexOf(parameterNames, property.stringValue);
|
|
int newIndex = EditorGUI.Popup(position, parameterIndex, parameterNames);
|
|
if(parameterIndex != newIndex) {
|
|
property.stringValue = parameterNames[newIndex];
|
|
didChange = true;
|
|
}
|
|
}
|
|
else {
|
|
EditorGUI.PropertyField(position, property, GUIContent.none);
|
|
}
|
|
|
|
int indentLevel = EditorGUI.indentLevel;
|
|
EditorGUI.indentLevel = 0;
|
|
|
|
if(EditorGUI.EndChangeCheck() || didChange) {
|
|
property.serializedObject.ApplyModifiedProperties();
|
|
}
|
|
|
|
EditorGUI.indentLevel = indentLevel;
|
|
EditorGUI.EndProperty();
|
|
}
|
|
|
|
private string[] UpdateParameterNames(SerializedProperty property, string animatorFieldName, bool allParameterTypesAllowed, AnimatorControllerParameterType parameterType) {
|
|
int pathIndexOfPropertyName = property.propertyPath.LastIndexOf(property.name, StringComparison.Ordinal);
|
|
bool isTopLevelObject = pathIndexOfPropertyName == 0;
|
|
SerializedProperty animatorProperty;
|
|
if(isTopLevelObject) {
|
|
animatorProperty = property.serializedObject.FindProperty(animatorFieldName);
|
|
}
|
|
else {
|
|
SerializedProperty parentProperty = property.serializedObject.FindProperty(property.propertyPath.Substring(0, pathIndexOfPropertyName - 1));
|
|
animatorProperty = parentProperty.FindPropertyRelative(animatorFieldName);
|
|
}
|
|
|
|
if(animatorProperty is { objectReferenceValue: Animator targetAnimator }) {
|
|
if(!targetAnimator.gameObject.activeSelf ||
|
|
!targetAnimator.gameObject.activeInHierarchy ||
|
|
targetAnimator.runtimeAnimatorController == null) {
|
|
return new string[] { }; // return an empty array so it uses the fallback of just text
|
|
}
|
|
|
|
AnimatorControllerParameter[] parameters = targetAnimator.parameters;
|
|
|
|
if(allParameterTypesAllowed) {
|
|
return parameters.Select(p => p.name).ToArray();
|
|
}
|
|
else {
|
|
return parameters.Where(p => p.type == parameterType).Select(p => p.name).ToArray();
|
|
}
|
|
}
|
|
return new[] { "<MISSING>" };
|
|
}
|
|
}
|
|
}
|
|
#endif |