using System.Collections.Generic;
using System.Linq;
using Chronos.Controls.Editor;
using Chronos.Reflection.Internal;
using UnityEditor;
using UnityEditor.Animations;
using UnityEngine;
namespace Chronos.Reflection.Editor
{
[CustomPropertyDrawer(typeof(AnimatorParameter))]
public class AnimatorParameterDrawer : TargetedDrawer
{
#region Fields
///
/// The inspected property, of type AnimatorParameter.
///
protected SerializedProperty property;
///
/// The UnityMember.name of the inspected property, of type string.
///
protected SerializedProperty nameProperty;
///
/// The targeted animators.
///
protected Animator[] targets;
#endregion
///
protected override void Update(SerializedProperty property)
{
// Update the targeted drawer
base.Update(property);
// Assign the property and sub-properties
this.property = property;
nameProperty = property.FindPropertyRelative("_name");
// Find the targets
targets = FindTargets();
}
///
protected override void RenderMemberControl(Rect position)
{
var options = GetNameOptions();
DropdownOption selectedOption = null;
DropdownOption noneOption = new DropdownOption(null, "No Parameter");
AnimatorParameter value = GetValue();
if (value != null)
{
string label = value.name;
AnimatorParameter valueInOptions = options.Select(option => option.value).FirstOrDefault(ap => ap.Corresponds(value));
if (valueInOptions != null)
{
selectedOption = new DropdownOption(valueInOptions, label);
}
else
{
selectedOption = new DropdownOption(value, label);
}
}
// Make sure the callback uses the property of this drawer, not at its later value.
var propertyNow = property;
bool enabled = targets.Any(target => target != null);
if (!enabled) EditorGUI.BeginDisabledGroup(true);
DropdownGUI.PopupSingle
(
position,
newValue =>
{
Update(propertyNow);
SetValue(newValue);
propertyNow.serializedObject.ApplyModifiedProperties();
},
options,
selectedOption,
noneOption,
nameProperty.hasMultipleDifferentValues
);
if (!enabled) EditorGUI.EndDisabledGroup();
}
#region Value
///
/// Returns an animator parameter constructed from the current property values.
///
protected AnimatorParameter GetValue()
{
if (nameProperty.hasMultipleDifferentValues || string.IsNullOrEmpty(nameProperty.stringValue))
{
return null;
}
string name = nameProperty.stringValue;
if (name == string.Empty) name = null;
return new AnimatorParameter(name);
}
///
/// Assigns the property values from a specified animator parameter.
///
protected void SetValue(AnimatorParameter value)
{
if (value != null)
{
nameProperty.stringValue = value.name;
}
else
{
nameProperty.stringValue = null;
}
}
#endregion
#region Targetting
///
protected override Object GetSelfTarget(Object obj)
{
if (obj is GameObject)
{
return ((GameObject)obj).GetComponent();
}
else if (obj is Component)
{
return ((Component)obj).GetComponent();
}
else
{
return null;
}
}
///
/// Gets the list of targets on the inspected objects.
///
protected Animator[] FindTargets()
{
IEnumerable