导入角色动画,和增加角色控制
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
// Designed by KINEMATION, 2025.
|
||||
|
||||
using KINEMATION.KAnimationCore.Runtime.Attributes;
|
||||
using KINEMATION.KAnimationCore.Runtime.Rig;
|
||||
using KINEMATION.KAnimationCore.Runtime.Input;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEditor.Animations;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KINEMATION.KAnimationCore.Editor.Attributes
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(CurveSelectorAttribute))]
|
||||
public class CurveSelectorDrawer : PropertyDrawer
|
||||
{
|
||||
private void AddAnimatorNames(ref List<string> options, RuntimeAnimatorController controller)
|
||||
{
|
||||
if (controller == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AnimatorController animatorController = controller as AnimatorController;
|
||||
if (animatorController != null)
|
||||
{
|
||||
var parameters = animatorController.parameters;
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
if (parameters[i].type != AnimatorControllerParameterType.Float)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
options.Add($"{parameters[i].name} (Animator)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddInputNames(ref List<string> options, UserInputConfig config)
|
||||
{
|
||||
if (config == null) return;
|
||||
|
||||
foreach (var property in config.floatProperties)
|
||||
{
|
||||
options.Add($"{property.name} (Input)");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
CurveSelectorAttribute curveAttribute = attribute as CurveSelectorAttribute;
|
||||
if (curveAttribute == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
KRig rig = (property.serializedObject.targetObject as IRigUser)?.GetRigAsset();
|
||||
if (rig == null)
|
||||
{
|
||||
EditorGUI.PropertyField(position, property, label, true);
|
||||
return;
|
||||
}
|
||||
|
||||
SerializedProperty name = property.FindPropertyRelative("name");
|
||||
SerializedProperty source = property.FindPropertyRelative("source");
|
||||
SerializedProperty mode = property.FindPropertyRelative("mode");
|
||||
SerializedProperty clampMin = property.FindPropertyRelative("clampMin");
|
||||
|
||||
List<string> options = new List<string>();
|
||||
options.Add("None");
|
||||
|
||||
if (rig != null)
|
||||
{
|
||||
if (curveAttribute.useAnimator)
|
||||
{
|
||||
// Add the Animator curves.
|
||||
AddAnimatorNames(ref options, rig.targetAnimator);
|
||||
}
|
||||
|
||||
if (curveAttribute.usePlayables)
|
||||
{
|
||||
// Add the Playables curves.
|
||||
foreach (var curve in rig.rigCurves)
|
||||
{
|
||||
options.Add($"{curve} (Playables)");
|
||||
}
|
||||
}
|
||||
|
||||
// Add the Input parameters.
|
||||
if (curveAttribute.useInput)
|
||||
{
|
||||
AddInputNames(ref options, rig.inputConfig);
|
||||
}
|
||||
}
|
||||
|
||||
name ??= property;
|
||||
|
||||
int index = options.IndexOf(name.stringValue);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
index = options.ToList().IndexOf(name.stringValue + " (Animator)");
|
||||
}
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
index = options.ToList().IndexOf(name.stringValue + " (Playables)");
|
||||
}
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
index = options.ToList().IndexOf(name.stringValue + " (Input)");
|
||||
}
|
||||
|
||||
Rect propertyRect = position;
|
||||
propertyRect.height = EditorGUIUtility.singleLineHeight;
|
||||
|
||||
index = EditorGUI.Popup(propertyRect, label.text, index, options.ToArray());
|
||||
string selection = index >= 0 ? options[index] : "None";
|
||||
|
||||
if (source != null)
|
||||
{
|
||||
if (selection.EndsWith("(Animator)"))
|
||||
{
|
||||
source.intValue = 0;
|
||||
}
|
||||
|
||||
if (selection.EndsWith("(Playables)"))
|
||||
{
|
||||
source.intValue = 1;
|
||||
}
|
||||
|
||||
if (selection.EndsWith("(Input)"))
|
||||
{
|
||||
source.intValue = 2;
|
||||
}
|
||||
}
|
||||
|
||||
selection = selection.Replace(" (Playables)", "");
|
||||
selection = selection.Replace(" (Animator)", "");
|
||||
selection = selection.Replace(" (Input)", "");
|
||||
|
||||
name.stringValue = selection;
|
||||
|
||||
if (mode != null)
|
||||
{
|
||||
propertyRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(propertyRect, mode);
|
||||
}
|
||||
|
||||
if (clampMin != null)
|
||||
{
|
||||
propertyRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(propertyRect, clampMin);
|
||||
}
|
||||
}
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
SerializedProperty name = property.FindPropertyRelative("name");
|
||||
SerializedProperty mode = property.FindPropertyRelative("mode");
|
||||
SerializedProperty clampMin = property.FindPropertyRelative("clampMin");
|
||||
|
||||
if (name == null || mode == null || clampMin == null)
|
||||
{
|
||||
return base.GetPropertyHeight(property, label);
|
||||
}
|
||||
|
||||
return EditorGUIUtility.singleLineHeight * 3f + EditorGUIUtility.standardVerticalSpacing;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 291f05330bc74df98860957b47e438f2
|
||||
timeCreated: 1704268108
|
||||
@@ -0,0 +1,131 @@
|
||||
// Designed by KINEMATION, 2025.
|
||||
|
||||
using System;
|
||||
using KINEMATION.KAnimationCore.Runtime.Rig;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using KINEMATION.KAnimationCore.Editor.Rig;
|
||||
using KINEMATION.KAnimationCore.Runtime.Attributes;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KINEMATION.KAnimationCore.Editor.Attributes
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(KRigElementChain))]
|
||||
public class ElementChainDrawer : PropertyDrawer
|
||||
{
|
||||
private CustomElementChainDrawerAttribute GetCustomChainAttribute()
|
||||
{
|
||||
CustomElementChainDrawerAttribute attr = null;
|
||||
|
||||
var attributes = fieldInfo.GetCustomAttributes(true);
|
||||
foreach (var customAttribute in attributes)
|
||||
{
|
||||
attr = customAttribute as CustomElementChainDrawerAttribute;
|
||||
if (attr != null) break;
|
||||
}
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
EditorGUI.BeginProperty(position, label, property);
|
||||
|
||||
IRigProvider rig = RigEditorUtility.TryGetRigProvider(fieldInfo, property);
|
||||
|
||||
SerializedProperty elementChain = property.FindPropertyRelative("elementChain");
|
||||
SerializedProperty chainName = property.FindPropertyRelative("chainName");
|
||||
|
||||
if (rig != null)
|
||||
{
|
||||
float labelWidth = EditorGUIUtility.labelWidth;
|
||||
var customChain = GetCustomChainAttribute();
|
||||
|
||||
Rect labelRect = new Rect(position.x, position.y, labelWidth, EditorGUIUtility.singleLineHeight);
|
||||
Rect buttonRect = position;
|
||||
|
||||
string buttonText = $"Edit {chainName.stringValue}";
|
||||
|
||||
if (customChain is {drawLabel: true})
|
||||
{
|
||||
EditorGUI.PrefixLabel(labelRect, label);
|
||||
labelRect.x += labelRect.width;
|
||||
labelRect.width = (position.width - labelWidth) / 2f;
|
||||
|
||||
buttonRect.x = labelRect.x;
|
||||
buttonRect.width = position.width - labelWidth;
|
||||
|
||||
buttonText = $"Edit {label.text}";
|
||||
}
|
||||
|
||||
if (customChain is {drawTextField: true})
|
||||
{
|
||||
chainName.stringValue = EditorGUI.TextField(labelRect, chainName.stringValue);
|
||||
|
||||
buttonRect.width = position.width - labelRect.width - (labelRect.x - position.x);
|
||||
buttonRect.x = labelRect.x + labelRect.width;
|
||||
|
||||
buttonText = "Edit";
|
||||
}
|
||||
|
||||
if (GUI.Button(buttonRect, buttonText))
|
||||
{
|
||||
var hierarchy = rig.GetHierarchy();
|
||||
if (hierarchy != null)
|
||||
{
|
||||
List<int> selectedIds = null;
|
||||
|
||||
// Get the active element indexes.
|
||||
int arraySize = elementChain.arraySize;
|
||||
|
||||
if (arraySize > 0)
|
||||
{
|
||||
selectedIds = new List<int>();
|
||||
|
||||
for (int i = 0; i < arraySize; i++)
|
||||
{
|
||||
var boneName
|
||||
= elementChain.GetArrayElementAtIndex(i).FindPropertyRelative("name").stringValue;
|
||||
selectedIds.Add(Array.FindIndex(hierarchy,
|
||||
element => element.name.Equals(boneName)) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
RigWindow.ShowWindow(hierarchy,
|
||||
(selectedElement) => { },
|
||||
items =>
|
||||
{
|
||||
elementChain.ClearArray();
|
||||
|
||||
foreach (var selection in items)
|
||||
{
|
||||
elementChain.arraySize++;
|
||||
int lastIndex = elementChain.arraySize - 1;
|
||||
|
||||
var element = elementChain.GetArrayElementAtIndex(lastIndex);
|
||||
var name = element.FindPropertyRelative("name");
|
||||
var index = element.FindPropertyRelative("index");
|
||||
|
||||
name.stringValue = selection.name;
|
||||
index.intValue = selection.index;
|
||||
}
|
||||
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
},
|
||||
true, selectedIds, "Element Chain Selection"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.enabled = false;
|
||||
EditorGUI.PropertyField(position, property, label, true);
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a14bd657f5c4df59493632603d3441f
|
||||
timeCreated: 1711355637
|
||||
@@ -0,0 +1,52 @@
|
||||
// Designed by KINEMATION, 2024.
|
||||
|
||||
using KINEMATION.KAnimationCore.Runtime.Attributes;
|
||||
using KINEMATION.KAnimationCore.Runtime.Rig;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KINEMATION.KAnimationCore.Editor.Attributes
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(ElementChainSelectorAttribute))]
|
||||
public class ElementChainSelectorDrawer : PropertyDrawer
|
||||
{
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
ElementChainSelectorAttribute chainSelectorAttribute = attribute as ElementChainSelectorAttribute;
|
||||
|
||||
if (chainSelectorAttribute == null)
|
||||
{
|
||||
EditorGUI.PropertyField(position, property, label, true);
|
||||
return;
|
||||
}
|
||||
|
||||
KRig rig = (property.serializedObject.targetObject as IRigUser)?.GetRigAsset();
|
||||
SerializedProperty assetProp = property.serializedObject.FindProperty(chainSelectorAttribute.assetName);
|
||||
|
||||
if (rig == null || assetProp != null)
|
||||
{
|
||||
if (assetProp == null) return;
|
||||
rig = assetProp.objectReferenceValue as KRig;
|
||||
}
|
||||
|
||||
if (rig == null)
|
||||
{
|
||||
EditorGUI.PropertyField(position, property, label, true);
|
||||
return;
|
||||
}
|
||||
|
||||
List<string> options = new List<string> {"None"};
|
||||
var chainNames = rig.rigElementChains.Select(chain => chain.chainName).ToArray();
|
||||
options.AddRange(chainNames);
|
||||
|
||||
int currentIndex = options.IndexOf(property.stringValue);
|
||||
currentIndex = EditorGUI.Popup(position, label.text, currentIndex, options.ToArray());
|
||||
string selection = currentIndex >= 0 ? options[currentIndex] : "None";
|
||||
|
||||
property.stringValue = selection;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df661746193b43b98e92a78be79cd084
|
||||
timeCreated: 1710236013
|
||||
@@ -0,0 +1,102 @@
|
||||
// Designed by KINEMATION, 2024.
|
||||
|
||||
using KINEMATION.KAnimationCore.Runtime.Attributes;
|
||||
using KINEMATION.KAnimationCore.Runtime.Input;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using KINEMATION.KAnimationCore.Runtime.Rig;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KINEMATION.KAnimationCore.Editor.Attributes
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(InputProperty))]
|
||||
public class InputPropertyDrawer : PropertyDrawer
|
||||
{
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
MonoBehaviour component = property.serializedObject.targetObject as MonoBehaviour;
|
||||
UserInputConfig config = null;
|
||||
|
||||
if (component != null)
|
||||
{
|
||||
var root = component.transform.root;
|
||||
UserInputController controller = root.gameObject.GetComponentInChildren<UserInputController>();
|
||||
config = controller == null ? null : controller.inputConfig;
|
||||
}
|
||||
|
||||
if (config == null)
|
||||
{
|
||||
config = (property.serializedObject.targetObject as IRigUser)?.GetRigAsset().inputConfig;
|
||||
}
|
||||
|
||||
if (config == null)
|
||||
{
|
||||
EditorGUI.PropertyField(position, property, label, true);
|
||||
return;
|
||||
}
|
||||
|
||||
int selectedIndex = -1;
|
||||
int indexOffset = 0;
|
||||
|
||||
List<string> properties = new List<string>();
|
||||
List<string> options = new List<string>();
|
||||
|
||||
int count = config.boolProperties.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var inputProperty = config.boolProperties[i];
|
||||
properties.Add(inputProperty.name);
|
||||
options.Add($"{inputProperty.name} (bool)");
|
||||
if (property.stringValue.Equals(inputProperty.name))
|
||||
{
|
||||
selectedIndex = i + indexOffset;
|
||||
}
|
||||
}
|
||||
indexOffset += count;
|
||||
|
||||
count = config.intProperties.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var inputProperty = config.intProperties[i];
|
||||
properties.Add(inputProperty.name);
|
||||
options.Add($"{inputProperty.name} (int)");
|
||||
if (property.stringValue.Equals(inputProperty.name))
|
||||
{
|
||||
selectedIndex = i + indexOffset;
|
||||
}
|
||||
}
|
||||
indexOffset += count;
|
||||
|
||||
count = config.floatProperties.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var inputProperty = config.floatProperties[i];
|
||||
properties.Add(inputProperty.name);
|
||||
options.Add($"{inputProperty.name} (float)");
|
||||
if (property.stringValue.Equals(inputProperty.name))
|
||||
{
|
||||
selectedIndex = i + indexOffset;
|
||||
}
|
||||
}
|
||||
indexOffset += count;
|
||||
|
||||
count = config.vectorProperties.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var inputProperty = config.vectorProperties[i];
|
||||
properties.Add(inputProperty.name);
|
||||
options.Add($"{inputProperty.name} (Vector4)");
|
||||
if (property.stringValue.Equals(inputProperty.name))
|
||||
{
|
||||
selectedIndex = i + indexOffset;
|
||||
}
|
||||
}
|
||||
|
||||
selectedIndex = EditorGUI.Popup(position, label.text, selectedIndex,
|
||||
options.ToArray());
|
||||
|
||||
property.stringValue = selectedIndex == -1 ? "None" : properties[selectedIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d71581c42592488289ee2189885f2deb
|
||||
timeCreated: 1711297253
|
||||
@@ -0,0 +1,23 @@
|
||||
// Designed by KINEMATION, 2024
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KINEMATION.KAnimationCore.Editor.Attributes
|
||||
{
|
||||
public class KAttributesEditor
|
||||
{
|
||||
public static T GetComponent<T>(SerializedProperty property) where T : class
|
||||
{
|
||||
Object targetObject = property.serializedObject.targetObject;
|
||||
|
||||
Component targetComponent = targetObject as Component;
|
||||
if (targetComponent != null)
|
||||
{
|
||||
return targetComponent.GetComponentInChildren<T>();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d63cd2c08ebe834286c4a63636ea284
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
// Designed by KINEMATION, 2024.
|
||||
|
||||
using KINEMATION.KAnimationCore.Runtime.Attributes;
|
||||
using KINEMATION.KAnimationCore.Runtime.Rig;
|
||||
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KINEMATION.KAnimationCore.Editor.Attributes
|
||||
{
|
||||
public class RigEditorUtility
|
||||
{
|
||||
public static IRigProvider TryGetRigProvider(FieldInfo fieldInfo, SerializedProperty property)
|
||||
{
|
||||
IRigProvider provider = null;
|
||||
|
||||
RigAssetSelectorAttribute assetAttribute = null;
|
||||
foreach (var customAttribute in fieldInfo.GetCustomAttributes(false))
|
||||
{
|
||||
if (customAttribute is RigAssetSelectorAttribute)
|
||||
{
|
||||
assetAttribute = customAttribute as RigAssetSelectorAttribute;
|
||||
}
|
||||
}
|
||||
|
||||
if (assetAttribute != null && !string.IsNullOrEmpty(assetAttribute.assetName))
|
||||
{
|
||||
if (property.serializedObject.FindProperty(assetAttribute.assetName) is var prop)
|
||||
{
|
||||
provider = prop.objectReferenceValue as IRigProvider;
|
||||
}
|
||||
}
|
||||
|
||||
if (provider == null)
|
||||
{
|
||||
provider = property.serializedObject.targetObject as IRigProvider;
|
||||
}
|
||||
|
||||
if (provider == null && property.serializedObject.targetObject is MonoBehaviour component)
|
||||
{
|
||||
provider = component.GetComponentInChildren<IRigProvider>();
|
||||
}
|
||||
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa2c3b5e5c3a4334a4d0ac853266c22f
|
||||
timeCreated: 1722195056
|
||||
@@ -0,0 +1,80 @@
|
||||
// Designed by KINEMATION, 2024.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using KINEMATION.KAnimationCore.Runtime.Rig;
|
||||
using KINEMATION.KAnimationCore.Editor.Rig;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KINEMATION.KAnimationCore.Editor.Attributes
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(KRigElement))]
|
||||
public class RigElementDrawer : PropertyDrawer
|
||||
{
|
||||
private void DrawRigElement(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
IRigProvider rig = RigEditorUtility.TryGetRigProvider(fieldInfo, property);
|
||||
|
||||
SerializedProperty name = property.FindPropertyRelative("name");
|
||||
SerializedProperty index = property.FindPropertyRelative("index");
|
||||
|
||||
if (rig == null)
|
||||
{
|
||||
EditorGUI.PropertyField(position, name, label, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate label width
|
||||
float labelWidth = EditorGUIUtility.labelWidth;
|
||||
float indentLevel = EditorGUI.indentLevel;
|
||||
|
||||
// Calculate button width and property field width
|
||||
float totalWidth = position.width - indentLevel - labelWidth;
|
||||
|
||||
// Display the default property field
|
||||
Rect propertyFieldRect = new Rect(position.x + indentLevel, position.y,
|
||||
labelWidth, position.height);
|
||||
|
||||
EditorGUI.LabelField(propertyFieldRect, label.text);
|
||||
|
||||
// Display the bone selection button
|
||||
Rect buttonRect = new Rect(position.x + indentLevel + labelWidth, position.y,
|
||||
totalWidth, EditorGUIUtility.singleLineHeight);
|
||||
|
||||
string currentName = string.IsNullOrEmpty(name.stringValue) ? "None" : name.stringValue;
|
||||
|
||||
if (GUI.Button(buttonRect, currentName))
|
||||
{
|
||||
var hierarchy = rig.GetHierarchy();
|
||||
if (hierarchy == null) return;
|
||||
|
||||
List<int> selection = null;
|
||||
if (index.intValue > -1 || !string.IsNullOrEmpty(name.stringValue))
|
||||
{
|
||||
int foundIndex = ArrayUtility.FindIndex(hierarchy,
|
||||
element => element.name.Equals(name.stringValue));
|
||||
if(foundIndex >= 0) selection = new List<int>() { foundIndex + 1 };
|
||||
}
|
||||
|
||||
RigWindow.ShowWindow(hierarchy, (selectedElement) =>
|
||||
{
|
||||
name.stringValue = selectedElement.name;
|
||||
index.intValue = selectedElement.index;
|
||||
name.serializedObject.ApplyModifiedProperties();
|
||||
},
|
||||
items => { },
|
||||
false, selection, "Rig Element Selection"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
EditorGUI.BeginProperty(position, label, property);
|
||||
|
||||
DrawRigElement(position, property, label);
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8de53271a60e4843b40829a26b606311
|
||||
timeCreated: 1704268272
|
||||
@@ -0,0 +1,74 @@
|
||||
using KINEMATION.KAnimationCore.Runtime.Attributes;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KINEMATION.KAnimationCore.Editor.Attributes
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(UnfoldAttribute))]
|
||||
public class UnfoldDrawer : PropertyDrawer
|
||||
{
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
EditorGUI.BeginProperty(position, label, property);
|
||||
|
||||
if (property.propertyType == SerializedPropertyType.Generic && !property.isArray)
|
||||
{
|
||||
SerializedProperty iterator = property.Copy();
|
||||
bool enterChildren = true;
|
||||
|
||||
// Calculate the initial position rect for the first property
|
||||
Rect propertyPosition = position;
|
||||
propertyPosition.height = EditorGUIUtility.singleLineHeight;
|
||||
|
||||
while (iterator.NextVisible(enterChildren))
|
||||
{
|
||||
if (SerializedProperty.EqualContents(iterator, property.GetEndProperty()))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
enterChildren = false;
|
||||
|
||||
EditorGUI.PropertyField(propertyPosition, iterator, new GUIContent(iterator.displayName), true);
|
||||
|
||||
// Update the position for the next property
|
||||
propertyPosition.y +=
|
||||
EditorGUI.GetPropertyHeight(iterator, new GUIContent(iterator.displayName), true) +
|
||||
EditorGUIUtility.standardVerticalSpacing;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.PropertyField(position, property, GUIContent.none, false);
|
||||
}
|
||||
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
if (property.propertyType == SerializedPropertyType.Generic && !property.isArray)
|
||||
{
|
||||
float totalHeight = 0;
|
||||
SerializedProperty iterator = property.Copy();
|
||||
bool enterChildren = true;
|
||||
while (iterator.NextVisible(enterChildren))
|
||||
{
|
||||
if (SerializedProperty.EqualContents(iterator, property.GetEndProperty()))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
enterChildren = false;
|
||||
totalHeight +=
|
||||
EditorGUI.GetPropertyHeight(iterator, new GUIContent(iterator.displayName), true) +
|
||||
EditorGUIUtility.standardVerticalSpacing;
|
||||
}
|
||||
|
||||
return totalHeight;
|
||||
}
|
||||
|
||||
return EditorGUI.GetPropertyHeight(property, GUIContent.none, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0cfc4757c394ac39bff808454cc13bc
|
||||
timeCreated: 1708710029
|
||||
Reference in New Issue
Block a user