first commit

This commit is contained in:
lethanhsonvsp
2025-11-17 15:16:36 +07:00
commit a40d0921eb
17012 changed files with 2652386 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 754562bd98582a44e875ea6d688127ac
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,163 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations.Rigging;
namespace UnityEditor.Animations.Rigging
{
[CustomEditor(typeof(BlendConstraint))]
[CanEditMultipleObjects]
class BlendConstraintEditor : Editor
{
static class Content
{
public static readonly GUIContent sourceObjects = new GUIContent(CommonContent.sourceObjects.text);
public static readonly GUIContent sourceA = EditorGUIUtility.TrTextContent(
"Source A",
"The first source GameObject that influences the position and rotation of the Constrained Object."
);
public static readonly GUIContent sourceB = EditorGUIUtility.TrTextContent(
"Source B",
"The second source GameObject that influences the position and rotation of the Constrained Object."
);
public static readonly GUIContent settings = CommonContent.settings;
public static readonly GUIContent maintainOffset = CommonContent.maintainOffset;
public static readonly GUIContent blendPosition = EditorGUIUtility.TrTextContent(
"Blend A | B Position",
"If enabled, the constrained GameObject's position blends between those of Source A and Source B by the specified amount."
);
public static readonly GUIContent blendRotation = EditorGUIUtility.TrTextContent(
"Blend A | B Rotation",
"If enabled, the constrained GameObject's rotation blends between those of Source A and Source B by the specified amount."
);
}
SerializedProperty m_Weight;
SerializedProperty m_ConstrainedObject;
SerializedProperty m_SourceA;
SerializedProperty m_SourceB;
SerializedProperty m_BlendPosition;
SerializedProperty m_BlendRotation;
SerializedProperty m_PositionWeight;
SerializedProperty m_RotationWeight;
SerializedProperty m_MaintainPositionOffsets;
SerializedProperty m_MaintainRotationOffsets;
readonly FoldoutState m_SourceObjectsToggle = FoldoutState.ForSourceObjects<BlendConstraintEditor>();
readonly FoldoutState m_SettingsToggle = FoldoutState.ForSettings<BlendConstraintEditor>();
void OnEnable()
{
m_Weight = serializedObject.FindProperty("m_Weight");
var data = serializedObject.FindProperty("m_Data");
m_ConstrainedObject = data.FindPropertyRelative("m_ConstrainedObject");
m_SourceA = data.FindPropertyRelative("m_SourceA");
m_SourceB = data.FindPropertyRelative("m_SourceB");
m_BlendPosition = data.FindPropertyRelative("m_BlendPosition");
m_BlendRotation = data.FindPropertyRelative("m_BlendRotation");
m_PositionWeight = data.FindPropertyRelative("m_PositionWeight");
m_RotationWeight = data.FindPropertyRelative("m_RotationWeight");
m_MaintainPositionOffsets = data.FindPropertyRelative("m_MaintainPositionOffsets");
m_MaintainRotationOffsets = data.FindPropertyRelative("m_MaintainRotationOffsets");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_Weight, CommonContent.weight);
EditorGUILayout.PropertyField(m_ConstrainedObject, CommonContent.constrainedObject);
m_SourceObjectsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SourceObjectsToggle.value, Content.sourceObjects);
if (m_SourceObjectsToggle.value)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_SourceA, Content.sourceA);
EditorGUILayout.PropertyField(m_SourceB, Content.sourceB);
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
m_SettingsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SettingsToggle.value, Content.settings);
if (m_SettingsToggle.value)
{
EditorGUI.indentLevel++;
MaintainOffsetHelper.DoDropdown(Content.maintainOffset, m_MaintainPositionOffsets, m_MaintainRotationOffsets);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PropertyField(m_BlendPosition, Content.blendPosition);
using (new EditorGUI.DisabledScope(!m_BlendPosition.boolValue))
EditorGUILayout.PropertyField(m_PositionWeight, GUIContent.none);
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PropertyField(m_BlendRotation, Content.blendRotation);
using (new EditorGUI.DisabledScope(!m_BlendRotation.boolValue))
EditorGUILayout.PropertyField(m_RotationWeight, GUIContent.none);
EditorGUILayout.EndHorizontal();
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
serializedObject.ApplyModifiedProperties();
}
[MenuItem("CONTEXT/BlendConstraint/Transfer motion to skeleton", false, 612)]
public static void TransferMotionToSkeleton(MenuCommand command)
{
var constraint = command.context as BlendConstraint;
BakeUtils.TransferMotionToSkeleton(constraint);
}
[MenuItem("CONTEXT/BlendConstraint/Transfer motion to skeleton", true)]
public static bool TransferMotionValidate(MenuCommand command)
{
var constraint = command.context as BlendConstraint;
return BakeUtils.TransferMotionValidate(constraint);
}
}
[BakeParameters(typeof(BlendConstraint))]
class BlendConstraintBakeParameters : BakeParameters<BlendConstraint>
{
public override bool canBakeToSkeleton => true;
public override bool canBakeToConstraint => false;
public override IEnumerable<EditorCurveBinding> GetSourceCurveBindings(RigBuilder rigBuilder, BlendConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
var sourceA = constraint.data.sourceObjectA;
var sourceB = constraint.data.sourceObjectB;
if (constraint.data.blendPosition)
{
EditorCurveBindingUtils.CollectPositionBindings(rigBuilder.transform, sourceA, bindings);
EditorCurveBindingUtils.CollectPositionBindings(rigBuilder.transform, sourceB, bindings);
}
if (constraint.data.blendRotation)
{
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, sourceA, bindings);
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, sourceB, bindings);
}
return bindings;
}
public override IEnumerable<EditorCurveBinding> GetConstrainedCurveBindings(RigBuilder rigBuilder, BlendConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
var constrained = constraint.data.constrainedObject;
if (constraint.data.blendPosition)
EditorCurveBindingUtils.CollectPositionBindings(rigBuilder.transform, constrained, bindings);
if(constraint.data.blendRotation)
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, constrained, bindings);
return bindings;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a8670d948642f1546a4835c189aea303
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,156 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations.Rigging;
namespace UnityEditor.Animations.Rigging
{
[CustomEditor(typeof(ChainIKConstraint))]
[CanEditMultipleObjects]
class ChainIKConstraintEditor : Editor
{
static class Content
{
public static readonly GUIContent root = EditorGUIUtility.TrTextContent(
"Root",
"The root GameObject of the chain hierarchy."
);
public static readonly GUIContent tip = EditorGUIUtility.TrTextContent(
"Tip",
"The final GameObject of the chain hierarchy. It must be a descendant of the Root GameObject."
);
public static readonly GUIContent target = EditorGUIUtility.TrTextContent(
"Target",
"The GameObject that specifies the desired target transform for the chain's Tip."
);
public static readonly GUIContent sourceObjects = new GUIContent(CommonContent.sourceObjects.text);
public static readonly GUIContent chainRotationWeight = EditorGUIUtility.TrTextContent(
"Chain Rotation Weight",
"The weight of rotations applied throughout the chain."
);
public static readonly GUIContent tipRotationWeight = EditorGUIUtility.TrTextContent(
"Tip Rotation Weight",
"The weight of the rotation applied to the Tip."
);
public static readonly GUIContent maxIterations = EditorGUIUtility.TrTextContent(
"Max Iterations",
"The maximum number of solver iterations to perform to try to make the Tip reach the Target within the specified Tolerance threshold."
);
public static readonly GUIContent tolerance = EditorGUIUtility.TrTextContent(
"Tolerance",
"Distance tolerance between the Target and Tip GameObjects. " +
"The solver will finish its computation if the distance is less than this value at any point, even if Max Iterations has not been reached."
);
}
SerializedProperty m_Weight;
SerializedProperty m_Root;
SerializedProperty m_Tip;
SerializedProperty m_Target;
SerializedProperty m_ChainRotationWeight;
SerializedProperty m_TipRotationWeight;
SerializedProperty m_MaxIterations;
SerializedProperty m_Tolerance;
SerializedProperty m_MaintainTargetPositionOffset;
SerializedProperty m_MaintainTargetRotationOffset;
readonly FoldoutState m_SourceObjectsToggle = FoldoutState.ForSourceObjects<ChainIKConstraintEditor>();
readonly FoldoutState m_SettingsToggle = FoldoutState.ForSettings<ChainIKConstraintEditor>();
void OnEnable()
{
m_Weight = serializedObject.FindProperty("m_Weight");
var data = serializedObject.FindProperty("m_Data");
m_Root = data.FindPropertyRelative("m_Root");
m_Tip = data.FindPropertyRelative("m_Tip");
m_Target = data.FindPropertyRelative("m_Target");
m_ChainRotationWeight = data.FindPropertyRelative("m_ChainRotationWeight");
m_TipRotationWeight = data.FindPropertyRelative("m_TipRotationWeight");
m_MaxIterations = data.FindPropertyRelative("m_MaxIterations");
m_Tolerance = data.FindPropertyRelative("m_Tolerance");
m_MaintainTargetPositionOffset = data.FindPropertyRelative("m_MaintainTargetPositionOffset");
m_MaintainTargetRotationOffset = data.FindPropertyRelative("m_MaintainTargetRotationOffset");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_Weight, CommonContent.weight);
EditorGUILayout.PropertyField(m_Root, Content.root);
EditorGUILayout.PropertyField(m_Tip, Content.tip);
m_SourceObjectsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SourceObjectsToggle.value, Content.sourceObjects);
if (m_SourceObjectsToggle.value)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_Target, Content.target);
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
m_SettingsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SettingsToggle.value, CommonContent.settings);
if (m_SettingsToggle.value)
{
EditorGUI.indentLevel++;
MaintainOffsetHelper.DoDropdown(CommonContent.maintainIKTargetOffset, m_MaintainTargetPositionOffset, m_MaintainTargetRotationOffset);
EditorGUILayout.PropertyField(m_ChainRotationWeight, Content.chainRotationWeight);
EditorGUILayout.PropertyField(m_TipRotationWeight, Content.tipRotationWeight);
EditorGUILayout.PropertyField(m_MaxIterations, Content.maxIterations);
EditorGUILayout.PropertyField(m_Tolerance, Content.tolerance);
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
serializedObject.ApplyModifiedProperties();
}
[MenuItem("CONTEXT/ChainIKConstraint/Transfer motion to skeleton", false, 612)]
public static void TransferMotionToSkeleton(MenuCommand command)
{
var constraint = command.context as ChainIKConstraint;
BakeUtils.TransferMotionToSkeleton(constraint);
}
[MenuItem("CONTEXT/ChainIKConstraint/Transfer motion to skeleton", true)]
public static bool TransferMotionValidate(MenuCommand command)
{
var constraint = command.context as ChainIKConstraint;
return BakeUtils.TransferMotionValidate(constraint);
}
}
[BakeParameters(typeof(ChainIKConstraint))]
class ChainIKConstraintBakeParameters : BakeParameters<ChainIKConstraint>
{
public override bool canBakeToSkeleton => true;
public override bool canBakeToConstraint => false;
public override IEnumerable<EditorCurveBinding> GetSourceCurveBindings(RigBuilder rigBuilder, ChainIKConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
EditorCurveBindingUtils.CollectTRBindings(rigBuilder.transform, constraint.data.target, bindings);
return bindings;
}
public override IEnumerable<EditorCurveBinding> GetConstrainedCurveBindings(RigBuilder rigBuilder, ChainIKConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
var root = constraint.data.root;
var tip = constraint.data.tip;
var tmp = tip;
while (tmp != root)
{
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, tmp, bindings);
tmp = tmp.parent;
}
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, root, bindings);
return bindings;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 63110210264e2ee4da7389733e5958ae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,122 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations.Rigging;
namespace UnityEditor.Animations.Rigging
{
[CustomEditor(typeof(DampedTransform))]
[CanEditMultipleObjects]
class DampedTransformEditor : Editor
{
static class Content
{
public static readonly GUIContent source = EditorGUIUtility.TrTextContent(
"Source",
"The GameObject that influences the Constrained Object's transform."
);
public static readonly GUIContent dampPosition = EditorGUIUtility.TrTextContent(
"Damp Position",
"The weight of positional damping to apply to the Constrained Object."
);
public static readonly GUIContent dampRotation = EditorGUIUtility.TrTextContent(
"Damp Rotation",
"The weight of rotational damping to apply to the Constrained Object."
);
public static readonly GUIContent maintainAim = EditorGUIUtility.TrTextContent(
"Maintain Aim",
"Specifies whether to maintain the initial rotation offset between the Constrained Object and the Source Object."
);
}
SerializedProperty m_Weight;
SerializedProperty m_ConstrainedObject;
SerializedProperty m_Source;
SerializedProperty m_DampPosition;
SerializedProperty m_DampRotation;
SerializedProperty m_MaintainAim;
readonly FoldoutState m_SourceObjectsToggle = FoldoutState.ForSourceObjects<DampedTransformEditor>();
readonly FoldoutState m_SettingsToggle = FoldoutState.ForSettings<DampedTransformEditor>();
void OnEnable()
{
m_Weight = serializedObject.FindProperty("m_Weight");
var data = serializedObject.FindProperty("m_Data");
m_ConstrainedObject = data.FindPropertyRelative("m_ConstrainedObject");
m_Source = data.FindPropertyRelative("m_Source");
m_DampPosition = data.FindPropertyRelative("m_DampPosition");
m_DampRotation = data.FindPropertyRelative("m_DampRotation");
m_MaintainAim = data.FindPropertyRelative("m_MaintainAim");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_Weight, CommonContent.weight);
EditorGUILayout.PropertyField(m_ConstrainedObject, CommonContent.constrainedObject);
m_SourceObjectsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SourceObjectsToggle.value, Content.source);
if (m_SourceObjectsToggle.value)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_Source, Content.source);
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
m_SettingsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SettingsToggle.value, CommonContent.settings);
if (m_SettingsToggle.value)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_DampPosition, Content.dampPosition);
EditorGUILayout.PropertyField(m_DampRotation, Content.dampRotation);
EditorGUILayout.PropertyField(m_MaintainAim, Content.maintainAim);
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
serializedObject.ApplyModifiedProperties();
}
[MenuItem("CONTEXT/DampedTransform/Transfer motion to skeleton", false, 612)]
public static void TransferMotionToSkeleton(MenuCommand command)
{
var constraint = command.context as DampedTransform;
BakeUtils.TransferMotionToSkeleton(constraint);
}
[MenuItem("CONTEXT/DampedTransform/Transfer motion to skeleton", true)]
public static bool TransferMotionValidate(MenuCommand command)
{
var constraint = command.context as DampedTransform;
return BakeUtils.TransferMotionValidate(constraint);
}
}
[BakeParameters(typeof(DampedTransform))]
class DampedTransformBakeParameters : BakeParameters<DampedTransform>
{
public override bool canBakeToSkeleton => true;
public override bool canBakeToConstraint => false;
public override IEnumerable<EditorCurveBinding> GetSourceCurveBindings(RigBuilder rigBuilder, DampedTransform constraint)
{
var bindings = new List<EditorCurveBinding>();
EditorCurveBindingUtils.CollectTRBindings(rigBuilder.transform, constraint.data.sourceObject, bindings);
return bindings;
}
public override IEnumerable<EditorCurveBinding> GetConstrainedCurveBindings(RigBuilder rigBuilder, DampedTransform constraint)
{
var bindings = new List<EditorCurveBinding>();
EditorCurveBindingUtils.CollectTRBindings(rigBuilder.transform, constraint.data.constrainedObject, bindings);
return bindings;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 99a3cbe2e69614541bdf264c5e905f48
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,197 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Animations.Rigging;
namespace UnityEditor.Animations.Rigging
{
[CustomEditor(typeof(MultiAimConstraint))]
[CanEditMultipleObjects]
class MultiAimConstraintEditor : Editor
{
static class Content
{
public static readonly GUIContent[] axisLabels = new []{ "X", "-X", "Y", "-Y", "Z", "-Z" }
.Select(c => new GUIContent(c))
.ToArray();
public static readonly GUIContent aimAxis = EditorGUIUtility.TrTextContent(
"Aim Axis",
"Specifies the local aim axis of the Constrained Object to use in order to orient its forward direction to the Source Objects."
);
public static readonly GUIContent upAxis = EditorGUIUtility.TrTextContent(
"Up Axis",
"Specifies the local up axis of the Constrained Object to use in order to orient its upward direction (i.e., roll orientation)."
);
public static readonly GUIContent worldUpType = EditorGUIUtility.TrTextContent(
"World Up Type",
"Specifies which mode to use to stabilize the upward direction (i.e., roll orientation) of the Constrained Object."
);
public static readonly GUIContent worldUpAxis = EditorGUIUtility.TrTextContent(
"World Up Axis",
"A vector in some reference frame that is used to stabilize the upward direction of the Constrained Object. " +
"This value is used when World Up Type is either Vector or Object Rotation Up."
);
public static readonly GUIContent worldUpObject = EditorGUIUtility.TrTextContent(
"World Up Object",
"A GameObject used as a reference frame for World Up Axis. " +
"This value is used when World Up Type is either Object Up or Object Rotation Up."
);
public static readonly GUIContent sourceObjects = CommonContent.sourceObjectsWeightedRotation;
public static readonly GUIContent settings = CommonContent.settings;
public static readonly GUIContent maintainOffset = CommonContent.maintainRotationOffset;
public static readonly GUIContent minLimit = EditorGUIUtility.TrTextContent(
"Min Limit",
"Clamps the minimum rotation that may be applied about any of the constrained axes of rotation."
);
public static readonly GUIContent maxLimit = EditorGUIUtility.TrTextContent(
"Max Limit",
"Clamps the maximum rotation that may be applied about any of the constrained axes of rotation."
);
}
SerializedProperty m_Weight;
SerializedProperty m_ConstrainedObject;
SerializedProperty m_AimAxis;
SerializedProperty m_UpAxis;
SerializedProperty m_WorldUpType;
SerializedProperty m_WorldUpAxis;
SerializedProperty m_WorldUpObject;
SerializedProperty m_SourceObjects;
SerializedProperty m_MaintainOffset;
SerializedProperty m_Offset;
SerializedProperty m_ConstrainedAxes;
SerializedProperty m_MinLimit;
SerializedProperty m_MaxLimit;
readonly FoldoutState m_SettingsToggle = FoldoutState.ForSettings<MultiAimConstraintEditor>();
void OnEnable()
{
m_Weight = serializedObject.FindProperty("m_Weight");
var data = serializedObject.FindProperty("m_Data");
m_ConstrainedObject = data.FindPropertyRelative("m_ConstrainedObject");
m_AimAxis = data.FindPropertyRelative("m_AimAxis");
m_UpAxis = data.FindPropertyRelative("m_UpAxis");
m_WorldUpType = data.FindPropertyRelative("m_WorldUpType");
m_WorldUpAxis = data.FindPropertyRelative("m_WorldUpAxis");
m_WorldUpObject = data.FindPropertyRelative("m_WorldUpObject");
m_SourceObjects = data.FindPropertyRelative("m_SourceObjects");
m_MaintainOffset = data.FindPropertyRelative("m_MaintainOffset");
m_Offset = data.FindPropertyRelative("m_Offset");
m_ConstrainedAxes = data.FindPropertyRelative("m_ConstrainedAxes");
m_MinLimit = data.FindPropertyRelative("m_MinLimit");
m_MaxLimit = data.FindPropertyRelative("m_MaxLimit");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_Weight, CommonContent.weight);
EditorGUILayout.PropertyField(m_ConstrainedObject, CommonContent.constrainedObject);
++EditorGUI.indentLevel;
DoAxisField(m_AimAxis, Content.aimAxis);
DoAxisField(m_UpAxis, Content.upAxis);
--EditorGUI.indentLevel;
EditorGUILayout.PropertyField(m_WorldUpType, Content.worldUpType);
var worldUpType = (MultiAimConstraintData.WorldUpType)m_WorldUpType.intValue;
++EditorGUI.indentLevel;
using (new EditorGUI.DisabledGroupScope(worldUpType != MultiAimConstraintData.WorldUpType.ObjectRotationUp && worldUpType != MultiAimConstraintData.WorldUpType.Vector))
{
DoAxisField(m_WorldUpAxis, Content.worldUpAxis);
}
using (new EditorGUI.DisabledGroupScope(worldUpType != MultiAimConstraintData.WorldUpType.ObjectUp && worldUpType != MultiAimConstraintData.WorldUpType.ObjectRotationUp))
{
EditorGUILayout.PropertyField(m_WorldUpObject, Content.worldUpObject);
}
--EditorGUI.indentLevel;
EditorGUILayout.PropertyField(m_SourceObjects, Content.sourceObjects);
m_SettingsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SettingsToggle.value, Content.settings);
if (m_SettingsToggle.value)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_MaintainOffset, Content.maintainOffset);
EditorGUILayout.PropertyField(m_Offset, CommonContent.offsetRotation);
EditorGUILayout.PropertyField(m_ConstrainedAxes, CommonContent.constrainedAxesRotation);
EditorGUILayout.PropertyField(m_MinLimit, Content.minLimit);
EditorGUILayout.PropertyField(m_MaxLimit, Content.maxLimit);
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
serializedObject.ApplyModifiedProperties();
}
static void DoAxisField(SerializedProperty property, GUIContent label)
{
var rect = EditorGUILayout.GetControlRect();
EditorGUI.BeginProperty(rect, label, property);
EditorGUI.BeginChangeCheck();
var newValue = EditorGUI.Popup(rect, label, property.intValue, Content.axisLabels);
if (EditorGUI.EndChangeCheck())
property.intValue = newValue;
EditorGUI.EndProperty();
}
[MenuItem("CONTEXT/MultiAimConstraint/Transfer motion to constraint", false, 611)]
public static void TransferMotionToConstraint(MenuCommand command)
{
var constraint = command.context as MultiAimConstraint;
BakeUtils.TransferMotionToConstraint(constraint);
}
[MenuItem("CONTEXT/MultiAimConstraint/Transfer motion to skeleton", false, 612)]
public static void TransferMotionToSkeleton(MenuCommand command)
{
var constraint = command.context as MultiAimConstraint;
BakeUtils.TransferMotionToSkeleton(constraint);
}
[MenuItem("CONTEXT/MultiAimConstraint/Transfer motion to constraint", true)]
[MenuItem("CONTEXT/MultiAimConstraint/Transfer motion to skeleton", true)]
public static bool TransferMotionValidate(MenuCommand command)
{
var constraint = command.context as MultiAimConstraint;
return BakeUtils.TransferMotionValidate(constraint);
}
}
[BakeParameters(typeof(MultiAimConstraint))]
class MultiAimConstraintBakeParameters : BakeParameters<MultiAimConstraint>
{
public override bool canBakeToSkeleton => true;
public override bool canBakeToConstraint => true;
public override IEnumerable<EditorCurveBinding> GetSourceCurveBindings(RigBuilder rigBuilder, MultiAimConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
for (int i = 0; i < constraint.data.sourceObjects.Count; ++i)
{
var sourceObject = constraint.data.sourceObjects[i];
EditorCurveBindingUtils.CollectPositionBindings(rigBuilder.transform, sourceObject.transform, bindings);
EditorCurveBindingUtils.CollectPropertyBindings(rigBuilder.transform, constraint, ((IMultiAimConstraintData)constraint.data).sourceObjectsProperty + ".m_Item" + i + ".weight", bindings);
}
return bindings;
}
public override IEnumerable<EditorCurveBinding> GetConstrainedCurveBindings(RigBuilder rigBuilder, MultiAimConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, constraint.data.constrainedObject, bindings);
return bindings;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9a96277d4d9d2d04181fc5ce44119fdf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,121 @@
using UnityEngine;
using UnityEngine.Animations.Rigging;
using System.Collections.Generic;
namespace UnityEditor.Animations.Rigging
{
[CustomEditor(typeof(MultiParentConstraint))]
[CanEditMultipleObjects]
class MultiParentConstraintEditor : Editor
{
static class Content
{
public static readonly GUIContent constrainedPositionAxes = new GUIContent(
L10n.Tr("Constrained Position Axes"),
CommonContent.constrainedAxesPosition.tooltip
);
public static readonly GUIContent constrainedRotationAxes = new GUIContent(
L10n.Tr("Constrained Rotation Axes"),
CommonContent.constrainedAxesRotation.tooltip
);
}
SerializedProperty m_Weight;
SerializedProperty m_ConstrainedObject;
SerializedProperty m_ConstrainedPositionAxes;
SerializedProperty m_ConstrainedRotationAxes;
SerializedProperty m_SourceObjects;
SerializedProperty m_MaintainPositionOffset;
SerializedProperty m_MaintainRotationOffset;
readonly FoldoutState m_SettingsToggle = FoldoutState.ForSettings<MultiParentConstraintEditor>();
void OnEnable()
{
m_Weight = serializedObject.FindProperty("m_Weight");
var data = serializedObject.FindProperty("m_Data");
m_ConstrainedObject = data.FindPropertyRelative("m_ConstrainedObject");
m_ConstrainedPositionAxes = data.FindPropertyRelative("m_ConstrainedPositionAxes");
m_ConstrainedRotationAxes = data.FindPropertyRelative("m_ConstrainedRotationAxes");
m_SourceObjects = data.FindPropertyRelative("m_SourceObjects");
m_MaintainPositionOffset = data.FindPropertyRelative("m_MaintainPositionOffset");
m_MaintainRotationOffset = data.FindPropertyRelative("m_MaintainRotationOffset");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_Weight, CommonContent.weight);
EditorGUILayout.PropertyField(m_ConstrainedObject, CommonContent.constrainedObject);
EditorGUILayout.PropertyField(m_SourceObjects, CommonContent.sourceObjects);
m_SettingsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SettingsToggle.value, CommonContent.settings);
if (m_SettingsToggle.value)
{
EditorGUI.indentLevel++;
MaintainOffsetHelper.DoDropdown(CommonContent.maintainOffset, m_MaintainPositionOffset, m_MaintainRotationOffset);
EditorGUILayout.PropertyField(m_ConstrainedPositionAxes, Content.constrainedPositionAxes);
EditorGUILayout.PropertyField(m_ConstrainedRotationAxes, Content.constrainedRotationAxes);
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
serializedObject.ApplyModifiedProperties();
}
[MenuItem("CONTEXT/MultiParentConstraint/Transfer motion to constraint", false, 611)]
public static void TransferMotionToConstraint(MenuCommand command)
{
var constraint = command.context as MultiParentConstraint;
BakeUtils.TransferMotionToConstraint(constraint);
}
[MenuItem("CONTEXT/MultiParentConstraint/Transfer motion to skeleton", false, 612)]
public static void TransferMotionToSkeleton(MenuCommand command)
{
var constraint = command.context as MultiParentConstraint;
BakeUtils.TransferMotionToSkeleton(constraint);
}
[MenuItem("CONTEXT/MultiParentConstraint/Transfer motion to constraint", true)]
[MenuItem("CONTEXT/MultiParentConstraint/Transfer motion to skeleton", true)]
public static bool TransferMotionValidate(MenuCommand command)
{
var constraint = command.context as MultiParentConstraint;
return BakeUtils.TransferMotionValidate(constraint);
}
}
[BakeParameters(typeof(MultiParentConstraint))]
class MultiParentConstraintParameters : BakeParameters<MultiParentConstraint>
{
public override bool canBakeToSkeleton => true;
public override bool canBakeToConstraint => true;
public override IEnumerable<EditorCurveBinding> GetSourceCurveBindings(RigBuilder rigBuilder, MultiParentConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
for (int i = 0; i < constraint.data.sourceObjects.Count; ++i)
{
var sourceObject = constraint.data.sourceObjects[i];
EditorCurveBindingUtils.CollectPositionBindings(rigBuilder.transform, sourceObject.transform, bindings);
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, sourceObject.transform, bindings);
EditorCurveBindingUtils.CollectPropertyBindings(rigBuilder.transform, constraint, ((IMultiParentConstraintData)constraint.data).sourceObjectsProperty + ".m_Item" + i + ".weight", bindings);
}
return bindings;
}
public override IEnumerable<EditorCurveBinding> GetConstrainedCurveBindings(RigBuilder rigBuilder, MultiParentConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
EditorCurveBindingUtils.CollectPositionBindings(rigBuilder.transform, constraint.data.constrainedObject, bindings);
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, constraint.data.constrainedObject, bindings);
return bindings;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2326ba71c8dbcba4ea941bf20e7e1bbc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,118 @@
using UnityEngine;
using UnityEngine.Animations.Rigging;
using System.Collections.Generic;
namespace UnityEditor.Animations.Rigging
{
[CustomEditor(typeof(MultiPositionConstraint))]
[CanEditMultipleObjects]
class MultiPositionConstraintEditor : Editor
{
SerializedProperty m_Weight;
SerializedProperty m_ConstrainedObject;
SerializedProperty m_ConstrainedAxes;
SerializedProperty m_SourceObjects;
SerializedProperty m_MaintainOffset;
SerializedProperty m_Offset;
readonly FoldoutState m_SettingsToggle = FoldoutState.ForSettings<MultiPositionConstraintEditor>();
void OnEnable()
{
m_Weight = serializedObject.FindProperty("m_Weight");
var data = serializedObject.FindProperty("m_Data");
m_ConstrainedObject = data.FindPropertyRelative("m_ConstrainedObject");
m_ConstrainedAxes = data.FindPropertyRelative("m_ConstrainedAxes");
m_SourceObjects = data.FindPropertyRelative("m_SourceObjects");
m_MaintainOffset = data.FindPropertyRelative("m_MaintainOffset");
m_Offset = data.FindPropertyRelative("m_Offset");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_Weight, CommonContent.weight);
EditorGUILayout.PropertyField(m_ConstrainedObject, CommonContent.constrainedObject);
EditorGUILayout.PropertyField(m_ConstrainedAxes, CommonContent.constrainedAxesPosition);
EditorGUILayout.PropertyField(m_SourceObjects, CommonContent.sourceObjectsWeightedPosition);
m_SettingsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SettingsToggle.value, CommonContent.settings);
if (m_SettingsToggle.value)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_MaintainOffset, CommonContent.maintainPositionOffset);
EditorGUILayout.PropertyField(m_Offset, CommonContent.offsetPosition);
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
serializedObject.ApplyModifiedProperties();
}
[MenuItem("CONTEXT/MultiPositionConstraint/Transfer motion to constraint", false, 611)]
public static void TransferMotionToConstraint(MenuCommand command)
{
var constraint = command.context as MultiPositionConstraint;
var axesMask = new Vector3(
System.Convert.ToSingle(constraint.data.constrainedXAxis),
System.Convert.ToSingle(constraint.data.constrainedYAxis),
System.Convert.ToSingle(constraint.data.constrainedZAxis));
if (Vector3.Dot(axesMask, axesMask) < 3f)
{
Debug.LogWarning("Multi-Position constraint with one or more Constrained Axes toggled off may lose precision when transferring its motion to constraint.");
}
BakeUtils.TransferMotionToConstraint(constraint);
}
[MenuItem("CONTEXT/MultiPositionConstraint/Transfer motion to skeleton", false, 612)]
public static void TransferMotionToSkeleton(MenuCommand command)
{
var constraint = command.context as MultiPositionConstraint;
BakeUtils.TransferMotionToSkeleton(constraint);
}
[MenuItem("CONTEXT/MultiPositionConstraint/Transfer motion to constraint", true)]
[MenuItem("CONTEXT/MultiPositionConstraint/Transfer motion to skeleton", true)]
public static bool TransferMotionValidate(MenuCommand command)
{
var constraint = command.context as MultiPositionConstraint;
return BakeUtils.TransferMotionValidate(constraint);
}
}
[BakeParameters(typeof(MultiPositionConstraint))]
class MultiPositionConstraintBakeParameters : BakeParameters<MultiPositionConstraint>
{
public override bool canBakeToSkeleton => true;
public override bool canBakeToConstraint => true;
public override IEnumerable<EditorCurveBinding> GetSourceCurveBindings(RigBuilder rigBuilder, MultiPositionConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
for (int i = 0; i < constraint.data.sourceObjects.Count; ++i)
{
var sourceObject = constraint.data.sourceObjects[i];
EditorCurveBindingUtils.CollectPositionBindings(rigBuilder.transform, sourceObject.transform, bindings);
EditorCurveBindingUtils.CollectPropertyBindings(rigBuilder.transform, constraint, ((IMultiPositionConstraintData)constraint.data).sourceObjectsProperty + ".m_Item" + i + ".weight", bindings);
}
return bindings;
}
public override IEnumerable<EditorCurveBinding> GetConstrainedCurveBindings(RigBuilder rigBuilder, MultiPositionConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
EditorCurveBindingUtils.CollectPositionBindings(rigBuilder.transform, constraint.data.constrainedObject, bindings);
return bindings;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6ca0517db96fdfc41b4230a34d84b37c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations.Rigging;
namespace UnityEditor.Animations.Rigging
{
[CustomEditor(typeof(MultiReferentialConstraint))]
[CanEditMultipleObjects]
class MultiReferentialConstraintEditor : Editor
{
static class Content
{
public static readonly GUIContent driving = EditorGUIUtility.TrTextContent(
"Driving",
"An object from the list of Referenced Objects, whose motion drives that of all other Referenced Objects."
);
public static readonly GUIContent referenceObjects = EditorGUIUtility.TrTextContent(
"Reference Objects",
"A list of GameObjects to be driven by the specified Driving object."
);
}
SerializedProperty m_Weight;
SerializedProperty m_Driver;
SerializedProperty m_SourceObjects;
SerializedProperty m_SourceObjectsSize;
GUIContent[] m_DrivingLabels = Array.Empty<GUIContent>();
int m_PreviousSourceSize;
void OnEnable()
{
m_Weight = serializedObject.FindProperty("m_Weight");
var data = serializedObject.FindProperty("m_Data");
m_Driver = data.FindPropertyRelative("m_Driver");
m_SourceObjects = data.FindPropertyRelative("m_SourceObjects");
m_SourceObjectsSize = m_SourceObjects.FindPropertyRelative("Array.size");
m_PreviousSourceSize = m_SourceObjectsSize.intValue;
UpdateDrivingLabels();
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_Weight, CommonContent.weight);
Rect rect = EditorGUILayout.GetControlRect();
EditorGUI.BeginProperty(rect, Content.driving, m_Driver);
EditorGUI.BeginChangeCheck();
var newValue = EditorGUI.Popup(rect, Content.driving, m_Driver.intValue, m_DrivingLabels);
if (EditorGUI.EndChangeCheck())
m_Driver.intValue = newValue;
EditorGUI.EndProperty();
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(m_SourceObjects, Content.referenceObjects);
// also check if size has changed, because drag/drop on default control and Reset do not trigger change
if (EditorGUI.EndChangeCheck() || m_PreviousSourceSize != m_SourceObjectsSize.intValue)
{
UpdateDrivingLabels();
m_PreviousSourceSize = m_SourceObjectsSize.intValue;
}
serializedObject.ApplyModifiedProperties();
}
void UpdateDrivingLabels()
{
Array.Resize(ref m_DrivingLabels, m_SourceObjects.arraySize);
for (int i = 0; i < m_DrivingLabels.Length; ++i)
{
var element = m_SourceObjects.GetArrayElementAtIndex(i);
var name = element.objectReferenceValue == null ? "None" : element.objectReferenceValue.name;
m_DrivingLabels[i] = new GUIContent($"{i} : {name}");
}
}
[MenuItem("CONTEXT/MultiReferentialConstraint/Transfer motion to constraint", false, 611)]
public static void TransferMotionToConstraint(MenuCommand command)
{
var constraint = command.context as MultiReferentialConstraint;
BakeUtils.TransferMotionToConstraint(constraint);
}
[MenuItem("CONTEXT/MultiReferentialConstraint/Transfer motion to skeleton", false, 612)]
public static void TransferMotionToSkeleton(MenuCommand command)
{
var constraint = command.context as MultiReferentialConstraint;
BakeUtils.TransferMotionToSkeleton(constraint);
}
[MenuItem("CONTEXT/MultiReferentialConstraint/Transfer motion to constraint", true)]
[MenuItem("CONTEXT/MultiReferentialConstraint/Transfer motion to skeleton", true)]
public static bool TransferMotionValidate(MenuCommand command)
{
var constraint = command.context as MultiReferentialConstraint;
return BakeUtils.TransferMotionValidate(constraint);
}
}
[BakeParameters(typeof(MultiReferentialConstraint))]
class MultiReferentialConstraintBakeParameters : BakeParameters<MultiReferentialConstraint>
{
public override bool canBakeToSkeleton => true;
public override bool canBakeToConstraint => true;
public override IEnumerable<EditorCurveBinding> GetSourceCurveBindings(RigBuilder rigBuilder, MultiReferentialConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
var sources = constraint.data.sourceObjects;
for (int i = 1; i < sources.Count; ++i)
EditorCurveBindingUtils.CollectTRBindings(rigBuilder.transform, sources[i], bindings);
return bindings;
}
public override IEnumerable<EditorCurveBinding> GetConstrainedCurveBindings(RigBuilder rigBuilder, MultiReferentialConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
var transform = constraint.data.sourceObjects[0];
EditorCurveBindingUtils.CollectTRBindings(rigBuilder.transform, transform, bindings);
return bindings;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 74cfdd6a1e6ff244496d38de0c2bbee5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,118 @@
using UnityEngine;
using UnityEngine.Animations.Rigging;
using System.Collections.Generic;
namespace UnityEditor.Animations.Rigging
{
[CustomEditor(typeof(MultiRotationConstraint))]
[CanEditMultipleObjects]
class MultiRotationConstraintEditor : Editor
{
SerializedProperty m_Weight;
SerializedProperty m_ConstrainedObject;
SerializedProperty m_ConstrainedAxes;
SerializedProperty m_SourceObjects;
SerializedProperty m_MaintainOffset;
SerializedProperty m_Offset;
readonly FoldoutState m_SettingsToggle = FoldoutState.ForSettings<MultiRotationConstraintEditor>();
void OnEnable()
{
m_Weight = serializedObject.FindProperty("m_Weight");
var data = serializedObject.FindProperty("m_Data");
m_ConstrainedObject = data.FindPropertyRelative("m_ConstrainedObject");
m_ConstrainedAxes = data.FindPropertyRelative("m_ConstrainedAxes");
m_SourceObjects = data.FindPropertyRelative("m_SourceObjects");
m_MaintainOffset = data.FindPropertyRelative("m_MaintainOffset");
m_Offset = data.FindPropertyRelative("m_Offset");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_Weight, CommonContent.weight);
EditorGUILayout.PropertyField(m_ConstrainedObject, CommonContent.constrainedObject);
EditorGUILayout.PropertyField(m_ConstrainedAxes, CommonContent.constrainedAxesRotation);
EditorGUILayout.PropertyField(m_SourceObjects, CommonContent.sourceObjectsWeightedRotation);
m_SettingsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SettingsToggle.value, CommonContent.settings);
if (m_SettingsToggle.value)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_MaintainOffset, CommonContent.maintainRotationOffset);
EditorGUILayout.PropertyField(m_Offset, CommonContent.offsetRotation);
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
serializedObject.ApplyModifiedProperties();
}
[MenuItem("CONTEXT/MultiRotationConstraint/Transfer motion to constraint", false, 611)]
public static void TransferMotionToConstraint(MenuCommand command)
{
var constraint = command.context as MultiRotationConstraint;
var axesMask = new Vector3(
System.Convert.ToSingle(constraint.data.constrainedXAxis),
System.Convert.ToSingle(constraint.data.constrainedYAxis),
System.Convert.ToSingle(constraint.data.constrainedZAxis));
if (Vector3.Dot(axesMask, axesMask) < 3f)
{
Debug.LogWarning("Multi-Rotation constraint with one or more Constrained Axes toggled off may lose precision when transferring its motion to constraint.");
}
BakeUtils.TransferMotionToConstraint(constraint);
}
[MenuItem("CONTEXT/MultiRotationConstraint/Transfer motion to skeleton", false, 612)]
public static void TransferMotionToSkeleton(MenuCommand command)
{
var constraint = command.context as MultiRotationConstraint;
BakeUtils.TransferMotionToSkeleton(constraint);
}
[MenuItem("CONTEXT/MultiRotationConstraint/Transfer motion to constraint", true)]
[MenuItem("CONTEXT/MultiRotationConstraint/Transfer motion to skeleton", true)]
public static bool TransferMotionValidate(MenuCommand command)
{
var constraint = command.context as MultiRotationConstraint;
return BakeUtils.TransferMotionValidate(constraint);
}
}
[BakeParameters(typeof(MultiRotationConstraint))]
class MultiRotationConstraintBakeParameters : BakeParameters<MultiRotationConstraint>
{
public override bool canBakeToSkeleton => true;
public override bool canBakeToConstraint => true;
public override IEnumerable<EditorCurveBinding> GetSourceCurveBindings(RigBuilder rigBuilder, MultiRotationConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
for (int i = 0; i < constraint.data.sourceObjects.Count; ++i)
{
var sourceObject = constraint.data.sourceObjects[i];
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, sourceObject.transform, bindings);
EditorCurveBindingUtils.CollectPropertyBindings(rigBuilder.transform, constraint, ((IMultiRotationConstraintData)constraint.data).sourceObjectsProperty + ".m_Item" + i + ".weight", bindings);
}
return bindings;
}
public override IEnumerable<EditorCurveBinding> GetConstrainedCurveBindings(RigBuilder rigBuilder, MultiRotationConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, constraint.data.constrainedObject, bindings);
return bindings;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 91a61b91969f07d448049f1b2c1bf3c8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,152 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations.Rigging;
namespace UnityEditor.Animations.Rigging
{
[CustomEditor(typeof(OverrideTransform))]
[CanEditMultipleObjects]
class OverrideTransformEditor : Editor
{
static class Content
{
public static readonly GUIContent sourceObjects = new GUIContent(CommonContent.sourceObjects.text);
public static readonly GUIContent overrideSource = EditorGUIUtility.TrTextContent(
"Override Source",
"The GameObject that influences the Constrained Object's transform. " +
"If specified, Override Position and Override Rotation fields are ignored."
);
public static readonly GUIContent overridePosition = EditorGUIUtility.TrTextContent(
"Override Position",
"A specific position value to apply to the Constrained Object. " +
"This value is ignored if an Override Source is specified."
);
public static readonly GUIContent overrideRotation = EditorGUIUtility.TrTextContent(
"Override Rotation",
"A specific rotation value to apply to the Constrained Object. " +
"This value is ignored if an Override Source is specified."
);
public static readonly GUIContent space = EditorGUIUtility.TrTextContent(
"Space",
"Specifies how the Override Source's local transform values (or manual Override Position and Rotation) should be applied to Constrained Object."
);
public static readonly GUIContent positionWeight = EditorGUIUtility.TrTextContent(
"Position Weight",
"The weight of the position influence."
);
public static readonly GUIContent rotationWeight = EditorGUIUtility.TrTextContent(
"Rotation Weight",
"The weight of the rotation influence."
);
}
SerializedProperty m_Weight;
SerializedProperty m_ConstrainedObject;
SerializedProperty m_OverrideSource;
SerializedProperty m_OverridePosition;
SerializedProperty m_OverrideRotation;
SerializedProperty m_Space;
SerializedProperty m_PositionWeight;
SerializedProperty m_RotationWeight;
readonly FoldoutState m_SourceObjectsToggle = FoldoutState.ForSourceObjects<OverrideTransformEditor>();
readonly FoldoutState m_SettingsToggle = FoldoutState.ForSettings<OverrideTransformEditor>();
void OnEnable()
{
m_Weight = serializedObject.FindProperty("m_Weight");
var data = serializedObject.FindProperty("m_Data");
m_ConstrainedObject = data.FindPropertyRelative("m_ConstrainedObject");
m_OverrideSource = data.FindPropertyRelative("m_OverrideSource");
m_OverridePosition = data.FindPropertyRelative("m_OverridePosition");
m_OverrideRotation = data.FindPropertyRelative("m_OverrideRotation");
m_Space = data.FindPropertyRelative("m_Space");
m_PositionWeight = data.FindPropertyRelative("m_PositionWeight");
m_RotationWeight = data.FindPropertyRelative("m_RotationWeight");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_Weight, CommonContent.weight);
EditorGUILayout.PropertyField(m_ConstrainedObject, CommonContent.constrainedObject);
m_SourceObjectsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SourceObjectsToggle.value, Content.sourceObjects);
if (m_SourceObjectsToggle.value)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_OverrideSource, Content.overrideSource);
using (new EditorGUI.DisabledScope(m_OverrideSource.objectReferenceValue != null))
{
EditorGUILayout.PropertyField(m_OverridePosition, Content.overridePosition);
EditorGUILayout.PropertyField(m_OverrideRotation, Content.overrideRotation);
}
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
m_SettingsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SettingsToggle.value, CommonContent.settings);
if (m_SettingsToggle.value)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_Space, Content.space);
EditorGUILayout.PropertyField(m_PositionWeight, Content.positionWeight);
EditorGUILayout.PropertyField(m_RotationWeight, Content.rotationWeight);
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
serializedObject.ApplyModifiedProperties();
}
[MenuItem("CONTEXT/OverrideTransform/Transfer motion to skeleton", false, 612)]
public static void TransferMotionToSkeleton(MenuCommand command)
{
var constraint = command.context as OverrideTransform;
BakeUtils.TransferMotionToSkeleton(constraint);
}
[MenuItem("CONTEXT/OverrideTransform/Transfer motion to skeleton", true)]
public static bool TransferMotionValidate(MenuCommand command)
{
var constraint = command.context as OverrideTransform;
return BakeUtils.TransferMotionValidate(constraint);
}
}
[BakeParameters(typeof(OverrideTransform))]
class OverrideTransformBakeParameters : BakeParameters<OverrideTransform>
{
public override bool canBakeToSkeleton => true;
public override bool canBakeToConstraint => false;
public override IEnumerable<EditorCurveBinding> GetSourceCurveBindings(RigBuilder rigBuilder, OverrideTransform constraint)
{
var bindings = new List<EditorCurveBinding>();
if (constraint.data.sourceObject != null)
{
EditorCurveBindingUtils.CollectTRBindings(rigBuilder.transform, constraint.data.sourceObject, bindings);
}
else
{
var data = (IOverrideTransformData)constraint.data;
EditorCurveBindingUtils.CollectVector3Bindings(rigBuilder.transform, constraint, data.positionVector3Property, bindings);
EditorCurveBindingUtils.CollectVector3Bindings(rigBuilder.transform, constraint, data.rotationVector3Property, bindings);
}
return bindings;
}
public override IEnumerable<EditorCurveBinding> GetConstrainedCurveBindings(RigBuilder rigBuilder, OverrideTransform constraint)
{
var bindings = new List<EditorCurveBinding>();
EditorCurveBindingUtils.CollectTRSBindings(rigBuilder.transform, constraint.data.constrainedObject, bindings);
return bindings;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 16cd7f77b75e35946b191bd98757e5a2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,143 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations.Rigging;
namespace UnityEditor.Animations.Rigging
{
[CustomEditor(typeof(TwistChainConstraint))]
[CanEditMultipleObjects]
class TwistChainConstraintEditor : Editor
{
static class Content
{
public static readonly GUIContent root = EditorGUIUtility.TrTextContent(
"Root",
"The root GameObject of the chain hierarchy."
);
public static readonly GUIContent tip = EditorGUIUtility.TrTextContent(
"Tip",
"The final GameObject of the chain hierarchy. It must be a descendant of the Root GameObject."
);
public static readonly GUIContent sourceObjects = new GUIContent(CommonContent.sourceObjects.text);
public static readonly GUIContent rootTarget = EditorGUIUtility.TrTextContent(
"Root Target",
"The GameObject that specifies the desired target rotation for the chain's Root."
);
public static readonly GUIContent tipTarget = EditorGUIUtility.TrTextContent(
"Tip Target",
"The GameObject that specifies the desired target rotation for the chain's Tip."
);
public static readonly GUIContent curve = EditorGUIUtility.TrTextContent(
"Curve",
"A curve with a normalized domain and range, specifying how the twist rotation should be distributed down the length of the chain."
);
}
SerializedProperty m_Weight;
SerializedProperty m_Root;
SerializedProperty m_Tip;
SerializedProperty m_RootTarget;
SerializedProperty m_TipTarget;
SerializedProperty m_Curve;
readonly FoldoutState m_SourceObjectsToggle = FoldoutState.ForSourceObjects<TwistChainConstraintEditor>();
readonly FoldoutState m_SettingsToggle = FoldoutState.ForSettings<TwistChainConstraintEditor>();
void OnEnable()
{
m_Weight = serializedObject.FindProperty("m_Weight");
var data = serializedObject.FindProperty("m_Data");
m_RootTarget = data.FindPropertyRelative("m_RootTarget");
m_TipTarget = data.FindPropertyRelative("m_TipTarget");
m_Root = data.FindPropertyRelative("m_Root");
m_Tip = data.FindPropertyRelative("m_Tip");
m_Curve = data.FindPropertyRelative("m_Curve");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_Weight, CommonContent.weight);
EditorGUILayout.PropertyField(m_Root, Content.root);
EditorGUILayout.PropertyField(m_Tip, Content.tip);
m_SourceObjectsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SourceObjectsToggle.value, Content.sourceObjects);
if (m_SourceObjectsToggle.value)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_RootTarget, Content.rootTarget);
EditorGUILayout.PropertyField(m_TipTarget, Content.tipTarget);
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
m_SettingsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SettingsToggle.value, CommonContent.settings);
if (m_SettingsToggle.value)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_Curve, Content.curve);
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
serializedObject.ApplyModifiedProperties();
}
[MenuItem("CONTEXT/TwistChainConstraint/Transfer motion to constraint", false, 611)]
public static void TransferMotionToConstraint(MenuCommand command)
{
var constraint = command.context as TwistChainConstraint;
BakeUtils.TransferMotionToConstraint(constraint);
}
[MenuItem("CONTEXT/TwistChainConstraint/Transfer motion to skeleton", false, 612)]
public static void TransferMotionToSkeleton(MenuCommand command)
{
var constraint = command.context as TwistChainConstraint;
BakeUtils.TransferMotionToSkeleton(constraint);
}
[MenuItem("CONTEXT/TwistChainConstraint/Transfer motion to constraint", true)]
[MenuItem("CONTEXT/TwistChainConstraint/Transfer motion to skeleton", true)]
public static bool TransferMotionValidate(MenuCommand command)
{
var constraint = command.context as TwistChainConstraint;
return BakeUtils.TransferMotionValidate(constraint);
}
}
[BakeParameters(typeof(TwistChainConstraint))]
class TwistChainConstraintBakeParameters : BakeParameters<TwistChainConstraint>
{
public override bool canBakeToSkeleton => true;
public override bool canBakeToConstraint => true;
public override IEnumerable<EditorCurveBinding> GetSourceCurveBindings(RigBuilder rigBuilder, TwistChainConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
EditorCurveBindingUtils.CollectTRBindings(rigBuilder.transform, constraint.data.rootTarget, bindings);
EditorCurveBindingUtils.CollectTRBindings(rigBuilder.transform, constraint.data.tipTarget, bindings);
return bindings;
}
public override IEnumerable<EditorCurveBinding> GetConstrainedCurveBindings(RigBuilder rigBuilder, TwistChainConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
// Retrieve chain in-between root and tip transforms.
Transform[] chain = ConstraintsUtils.ExtractChain(constraint.data.root, constraint.data.tip);
for (int i = 0; i < chain.Length; ++i)
{
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, chain[i], bindings);
}
return bindings;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6f51e9e105d754014895d13788b539ae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,114 @@
using UnityEngine;
using UnityEngine.Animations.Rigging;
using System.Collections.Generic;
namespace UnityEditor.Animations.Rigging
{
[CustomEditor(typeof(TwistCorrection))]
[CanEditMultipleObjects]
class TwistCorrectionEditor : Editor
{
static class Content
{
public static readonly GUIContent source = EditorGUIUtility.TrTextContent(
"Source",
"The GameObject that influences the Twist Nodes to rotate around a specific Twist Axis."
);
public static readonly GUIContent twistAxis = EditorGUIUtility.TrTextContent(
"Twist Axis",
"Specifies the axis on the Source object from which the rotation is extracted and then redistributed to the Twist Nodes."
);
public static readonly GUIContent twistNodes = EditorGUIUtility.TrTextContent(
"Twist Nodes",
"The list of GameObjects that will be influenced by the Source GameObject, and the cumulative percentage of the Source's twist rotation they should inherit. " +
"They are generally expected to all be leaf nodes in the hierarchy (i.e., they have a common parent and no children), and to have their twist axes oriented the same as the Source object in their initial pose."
);
}
SerializedProperty m_Weight;
SerializedProperty m_Source;
SerializedProperty m_TwistAxis;
SerializedProperty m_TwistNodes;
SerializedProperty m_TwistNodesLength;
readonly FoldoutState m_SourceObjectsToggle = FoldoutState.ForSourceObjects<TwistChainConstraintEditor>();
void OnEnable()
{
m_Weight = serializedObject.FindProperty("m_Weight");
var data = serializedObject.FindProperty("m_Data");
m_Source = data.FindPropertyRelative("m_Source");
m_TwistAxis = data.FindPropertyRelative("m_TwistAxis");
m_TwistNodes = data.FindPropertyRelative("m_TwistNodes");
m_TwistNodesLength = m_TwistNodes.FindPropertyRelative("m_Length");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_Weight, CommonContent.weight);
// by default, the first WeightedTransform element a user adds has a weight of 1
// for this constraint, the first twist node usually should not have a value of 1
// TODO: make drag/drop auto-distribute weights
EditorGUI.BeginChangeCheck();
var oldLength = m_TwistNodesLength.intValue;
EditorGUILayout.PropertyField(m_TwistNodes, Content.twistNodes);
if (EditorGUI.EndChangeCheck() && oldLength == 0 && m_TwistNodesLength.intValue != oldLength)
m_TwistNodes.FindPropertyRelative("m_Item0.weight").floatValue = 0f;
EditorGUILayout.PropertyField(m_TwistAxis, Content.twistAxis);
m_SourceObjectsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SourceObjectsToggle.value, Content.source);
{
++EditorGUI.indentLevel;
EditorGUILayout.PropertyField(m_Source);
--EditorGUI.indentLevel;
}
EditorGUILayout.EndFoldoutHeaderGroup();
serializedObject.ApplyModifiedProperties();
}
[MenuItem("CONTEXT/TwistCorrection/Transfer motion to skeleton", false, 612)]
public static void TransferMotionToSkeleton(MenuCommand command)
{
var constraint = command.context as TwistCorrection;
BakeUtils.TransferMotionToSkeleton(constraint);
}
[MenuItem("CONTEXT/TwistCorrection/Transfer motion to skeleton", true)]
public static bool TransferMotionValidate(MenuCommand command)
{
var constraint = command.context as TwistCorrection;
return BakeUtils.TransferMotionValidate(constraint);
}
}
[BakeParameters(typeof(TwistCorrection))]
class TwistCorrectionBakeParameters : BakeParameters<TwistCorrection>
{
public override bool canBakeToSkeleton => true;
public override bool canBakeToConstraint => false;
public override IEnumerable<EditorCurveBinding> GetSourceCurveBindings(RigBuilder rigBuilder, TwistCorrection constraint)
{
var bindings = new List<EditorCurveBinding>();
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, constraint.data.sourceObject, bindings);
return bindings;
}
public override IEnumerable<EditorCurveBinding> GetConstrainedCurveBindings(RigBuilder rigBuilder, TwistCorrection constraint)
{
var bindings = new List<EditorCurveBinding>();
foreach (var node in constraint.data.twistNodes)
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, node.transform, bindings);
return bindings;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e52e5d5c12dea4e4397e6781cbeac36d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,301 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations.Rigging;
namespace UnityEditor.Animations.Rigging
{
[CustomEditor(typeof(TwoBoneIKConstraint))]
[CanEditMultipleObjects]
class TwoBoneIKConstraintEditor : Editor
{
static class Content
{
public static readonly GUIContent root = EditorGUIUtility.TrTextContent(
"Root",
"The root GameObject of the limb hierarchy."
);
public static readonly GUIContent mid = EditorGUIUtility.TrTextContent(
"Mid",
"The middle GameObject of the limb hierarchy. It must be a child of the Root GameObject."
);
public static readonly GUIContent tip = EditorGUIUtility.TrTextContent(
"Tip",
"The final GameObject of the limb hierarchy. It must be a child of the Mid GameObject."
);
public static readonly GUIContent sourceObjects = new GUIContent(CommonContent.sourceObjects.text);
public static readonly GUIContent target = EditorGUIUtility.TrTextContent(
"Target",
"Source GameObject that specifies the desired position of the Tip."
);
public static readonly GUIContent hint = EditorGUIUtility.TrTextContent(
"Hint",
"Optional Source GameObject, whose position is used to specify the direction the limb should be oriented when it bends."
);
public static readonly GUIContent targetPositionWeight = EditorGUIUtility.TrTextContent(
"Target Position Weight",
"The weight to apply for calculating the desired position when reaching for the Target."
);
public static readonly GUIContent targetRotationWeight = EditorGUIUtility.TrTextContent(
"Target Rotation Weight",
"The weight of the rotation applied to the Tip."
);
public static readonly GUIContent hintWeight = EditorGUIUtility.TrTextContent(
"Hint Weight",
"The amount of influence the Hint has on the configuration of the hierarchy."
);
}
SerializedProperty m_Weight;
SerializedProperty m_Root;
SerializedProperty m_Mid;
SerializedProperty m_Tip;
SerializedProperty m_Target;
SerializedProperty m_Hint;
SerializedProperty m_TargetPositionWeight;
SerializedProperty m_TargetRotationWeight;
SerializedProperty m_HintWeight;
SerializedProperty m_MaintainTargetPositionOffset;
SerializedProperty m_MaintainTargetRotationOffset;
readonly FoldoutState m_SourceObjectsToggle = FoldoutState.ForSourceObjects<TwoBoneIKConstraintEditor>();
readonly FoldoutState m_SettingsToggle = FoldoutState.ForSettings<TwoBoneIKConstraintEditor>();
void OnEnable()
{
m_Weight = serializedObject.FindProperty("m_Weight");
var data = serializedObject.FindProperty("m_Data");
m_Root = data.FindPropertyRelative("m_Root");
m_Mid = data.FindPropertyRelative("m_Mid");
m_Tip = data.FindPropertyRelative("m_Tip");
m_Target = data.FindPropertyRelative("m_Target");
m_Hint = data.FindPropertyRelative("m_Hint");
m_TargetPositionWeight = data.FindPropertyRelative("m_TargetPositionWeight");
m_TargetRotationWeight = data.FindPropertyRelative("m_TargetRotationWeight");
m_HintWeight = data.FindPropertyRelative("m_HintWeight");
m_MaintainTargetPositionOffset = data.FindPropertyRelative("m_MaintainTargetPositionOffset");
m_MaintainTargetRotationOffset = data.FindPropertyRelative("m_MaintainTargetRotationOffset");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(m_Weight, CommonContent.weight);
EditorGUILayout.PropertyField(m_Root, Content.root);
EditorGUILayout.PropertyField(m_Mid, Content.mid);
EditorGUILayout.PropertyField(m_Tip, Content.tip);
m_SourceObjectsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SourceObjectsToggle.value, Content.sourceObjects);
if (m_SourceObjectsToggle.value)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(m_Target, Content.target);
EditorGUILayout.PropertyField(m_Hint, Content.hint);
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
m_SettingsToggle.value = EditorGUILayout.BeginFoldoutHeaderGroup(m_SettingsToggle.value, CommonContent.settings);
if (m_SettingsToggle.value)
{
EditorGUI.indentLevel++;
MaintainOffsetHelper.DoDropdown(CommonContent.maintainIKTargetOffset, m_MaintainTargetPositionOffset, m_MaintainTargetRotationOffset);
EditorGUILayout.PropertyField(m_TargetPositionWeight, Content.targetPositionWeight);
EditorGUILayout.PropertyField(m_TargetRotationWeight, Content.targetRotationWeight);
EditorGUILayout.PropertyField(m_HintWeight, Content.hintWeight);
EditorGUI.indentLevel--;
}
EditorGUILayout.EndFoldoutHeaderGroup();
serializedObject.ApplyModifiedProperties();
}
[MenuItem("CONTEXT/TwoBoneIKConstraint/Transfer motion to constraint", false, 611)]
public static void TransferMotionToConstraint(MenuCommand command)
{
var constraint = command.context as TwoBoneIKConstraint;
BakeUtils.TransferMotionToConstraint(constraint);
}
[MenuItem("CONTEXT/TwoBoneIKConstraint/Transfer motion to skeleton", false, 612)]
public static void TransferMotionToSkeleton(MenuCommand command)
{
var constraint = command.context as TwoBoneIKConstraint;
BakeUtils.TransferMotionToSkeleton(constraint);
}
[MenuItem("CONTEXT/TwoBoneIKConstraint/Transfer motion to constraint", true)]
[MenuItem("CONTEXT/TwoBoneIKConstraint/Transfer motion to skeleton", true)]
public static bool TransferMotionValidate(MenuCommand command)
{
var constraint = command.context as TwoBoneIKConstraint;
return BakeUtils.TransferMotionValidate(constraint);
}
[MenuItem("CONTEXT/TwoBoneIKConstraint/Auto Setup from Tip Transform", false, 631)]
public static void TwoBoneIKAutoSetup(MenuCommand command)
{
var constraint = command.context as TwoBoneIKConstraint;
var tip = constraint.data.tip;
var animator = constraint.GetComponentInParent<Animator>()?.transform;
var dirty = false;
if (!tip)
{
var selection = Selection.transforms;
var constraintInSelection = false;
// Take transform from selection that is part of the animator hierarchy & not the constraint transform.
if (animator)
{
for (int i = 0; i < selection.Length; i++)
{
if (selection[i].IsChildOf(animator))
{
if (selection[i] != constraint.transform)
{
tip = selection[i];
break;
}
else
{
constraintInSelection = true;
}
}
}
}
// If the constraint itself was selected and we haven't found anything use that.
if (!tip && constraintInSelection)
tip = constraint.transform;
// If there is still no tip return.
if (!tip)
{
Debug.LogWarning("Please provide a tip before running auto setup!");
return;
}
else
{
Undo.RecordObject(constraint, "Setup tip bone from user selection");
constraint.data.tip = tip;
dirty = true;
}
}
if (!constraint.data.mid)
{
Undo.RecordObject(constraint, "Setup mid bone for TwoBoneIK");
constraint.data.mid = tip.parent;
dirty = true;
}
if (!constraint.data.root)
{
Undo.RecordObject(constraint, "Setup root bone for TwoBoneIK");
constraint.data.root = tip.parent.parent;
dirty = true;
}
if (!constraint.data.target)
{
var target = constraint.transform.Find(constraint.gameObject.name + "_target");
if (target == null)
{
var t = new GameObject();
Undo.RegisterCreatedObjectUndo(t, "Created target");
t.name = constraint.gameObject.name + "_target";
t.transform.localScale = .1f * t.transform.localScale;
Undo.SetTransformParent(t.transform, constraint.transform, "Set new parent");
target = t.transform;
}
constraint.data.target = target;
dirty = true;
}
if (!constraint.data.hint)
{
var hint = constraint.transform.Find(constraint.gameObject.name + "_hint");
if (hint == null)
{
var t = new GameObject();
Undo.RegisterCreatedObjectUndo(t, "Created hint");
t.name = constraint.gameObject.name + "_hint";
t.transform.localScale = .1f * t.transform.localScale;
Undo.SetTransformParent(t.transform, constraint.transform, "Set new parent");
hint = t.transform;
}
constraint.data.hint = hint;
dirty = true;
}
Vector3 rootPosition = constraint.data.root.position;
Vector3 midPosition = constraint.data.mid.position;
Vector3 tipPosition = constraint.data.tip.position;
Quaternion tipRotation = constraint.data.tip.rotation;
Vector3 targetPosition = constraint.data.target.position;
Quaternion targetRotation = constraint.data.target.rotation;
Vector3 hintPosition = constraint.data.hint.position;
float posWeight = constraint.data.targetPositionWeight;
float rotWeight = constraint.data.targetRotationWeight;
float hintWeight = constraint.data.hintWeight;
AffineTransform targetOffset = new AffineTransform(Vector3.zero, Quaternion.identity);
AnimationRuntimeUtils.InverseSolveTwoBoneIK(rootPosition, midPosition, tipPosition, tipRotation,
ref targetPosition, ref targetRotation, ref hintPosition, true, posWeight, rotWeight, hintWeight, targetOffset);
constraint.data.target.position = targetPosition;
constraint.data.target.rotation = targetRotation;
constraint.data.hint.position = hintPosition;
Rig rig = constraint.GetComponentInParent<Rig>();
if (rig != null)
{
RigEffectorData.Style targetStyle = RigEffector.defaultStyle;
targetStyle.shape = EditorHelper.LoadShape("BoxEffector.asset");
rig.AddEffector(constraint.data.target, targetStyle);
RigEffectorData.Style hintStyle = RigEffector.defaultStyle;
hintStyle.shape = EditorHelper.LoadShape("BallEffector.asset");
rig.AddEffector(constraint.data.hint, hintStyle);
}
if (dirty && PrefabUtility.IsPartOfPrefabInstance(constraint))
EditorUtility.SetDirty(constraint);
}
}
[BakeParameters(typeof(TwoBoneIKConstraint))]
class TwoBoneIKConstraintBakeParameters : BakeParameters<TwoBoneIKConstraint>
{
public override bool canBakeToSkeleton => true;
public override bool canBakeToConstraint => true;
public override IEnumerable<EditorCurveBinding> GetSourceCurveBindings(RigBuilder rigBuilder, TwoBoneIKConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
EditorCurveBindingUtils.CollectTRBindings(rigBuilder.transform, constraint.data.target, bindings);
if (constraint.data.hint != null)
EditorCurveBindingUtils.CollectPositionBindings(rigBuilder.transform, constraint.data.hint, bindings);
return bindings;
}
public override IEnumerable<EditorCurveBinding> GetConstrainedCurveBindings(RigBuilder rigBuilder, TwoBoneIKConstraint constraint)
{
var bindings = new List<EditorCurveBinding>();
var root = constraint.data.root;
var mid = constraint.data.mid;
var tip = constraint.data.tip;
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, root, bindings);
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, mid, bindings);
EditorCurveBindingUtils.CollectRotationBindings(rigBuilder.transform, tip, bindings);
return bindings;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d47d5b10876eed042af2bccb184f9a5b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,61 @@
using UnityEngine;
using UnityEngine.Animations.Rigging;
using UnityEditorInternal;
namespace UnityEditor.Animations.Rigging
{
[CustomEditor(typeof(RigBuilder))]
class RigBuilderEditor : Editor
{
static readonly GUIContent k_RigLabel = new GUIContent("Rig Layers");
SerializedProperty m_Rigs;
ReorderableList m_ReorderableList;
void OnEnable()
{
m_Rigs = serializedObject.FindProperty("m_RigLayers");
m_ReorderableList = ReorderableListHelper.Create(serializedObject, m_Rigs, true, true);
if (m_ReorderableList.count == 0)
((RigBuilder)serializedObject.targetObject).layers.Add(new RigLayer(null));
m_ReorderableList.drawHeaderCallback = (Rect rect) => EditorGUI.LabelField(rect, k_RigLabel);
m_ReorderableList.onAddCallback = (ReorderableList list) =>
{
((RigBuilder)(serializedObject.targetObject)).layers.Add(new RigLayer(null, true));
};
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.Separator();
m_ReorderableList.DoLayoutList();
serializedObject.ApplyModifiedProperties();
}
[MenuItem("CONTEXT/RigBuilder/Transfer motion to constraint", false, 611)]
public static void TransferMotionToConstraint(MenuCommand command)
{
var rigBuilder = command.context as RigBuilder;
BakeUtils.TransferMotionToConstraint(rigBuilder);
}
[MenuItem("CONTEXT/RigBuilder/Transfer motion to skeleton", false, 612)]
public static void TransferMotionToSkeleton(MenuCommand command)
{
var rigBuilder = command.context as RigBuilder;
BakeUtils.TransferMotionToSkeleton(rigBuilder);
}
[MenuItem("CONTEXT/RigBuilder/Transfer motion to constraint", true)]
[MenuItem("CONTEXT/RigBuilder/Transfer motion to skeleton", true)]
public static bool TransferMotionValidate(MenuCommand command)
{
var rigBuilder = command.context as RigBuilder;
return BakeUtils.TransferMotionValidate(rigBuilder);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5f920510daf5fba46b137a815f4e9a1b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,76 @@
using UnityEngine.Animations.Rigging;
namespace UnityEditor.Animations.Rigging
{
[CustomEditor(typeof(Rig))]
[CanEditMultipleObjects]
class RigEditor : Editor
{
SerializedProperty m_Weight;
void OnEnable()
{
m_Weight = serializedObject.FindProperty("m_Weight");
}
public override void OnInspectorGUI()
{
bool isEditingMultipleObjects = targets.Length > 1;
serializedObject.Update();
EditorGUILayout.Separator();
EditorGUILayout.PropertyField(m_Weight);
serializedObject.ApplyModifiedProperties();
if (!isEditingMultipleObjects)
{
var rig = target as Rig;
var rigBuilder = rig.GetComponentInParent<RigBuilder>();
if (rigBuilder == null)
{
EditorGUILayout.HelpBox("Rig component is not child of a GameObject with a RigBuilder component.", MessageType.Warning, true);
}
else
{
var inRigBuilder = false;
var layers = rigBuilder.layers;
for (int i = 0; i < layers.Count; ++i)
{
if (layers[i].rig == rig && layers[i].active)
{
inRigBuilder = true;
break;
}
}
if (!inRigBuilder)
EditorGUILayout.HelpBox("Rig component is not referenced or not active in the RigBuilder component.", MessageType.Warning, true);
}
}
}
[MenuItem("CONTEXT/Rig/Transfer motion to constraint", false, 611)]
public static void TransferMotionToConstraint(MenuCommand command)
{
var rig = command.context as Rig;
BakeUtils.TransferMotionToConstraint(rig);
}
[MenuItem("CONTEXT/Rig/Transfer motion to skeleton", false, 612)]
public static void TransferMotionToSkeleton(MenuCommand command)
{
var rig = command.context as Rig;
BakeUtils.TransferMotionToSkeleton(rig);
}
[MenuItem("CONTEXT/Rig/Transfer motion to constraint", true)]
[MenuItem("CONTEXT/Rig/Transfer motion to skeleton", true)]
public static bool TransferMotionValidate(MenuCommand command)
{
var rig = command.context as Rig;
return BakeUtils.TransferMotionValidate(rig);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6856dd80c42d3244b9d9eb1844f8715f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
using UnityEngine;
using UnityEngine.Animations.Rigging;
namespace UnityEditor.Animations.Rigging
{
[CustomPropertyDrawer(typeof(RigLayer))]
class RigLayerDrawer : PropertyDrawer
{
const int k_Padding = 6;
const int k_TogglePadding = 30;
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.singleLineHeight;
}
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(rect, label, property);
var w = rect.width - k_TogglePadding;
var weightRect = new Rect(rect.x + w + k_Padding, rect.y, rect.width - w - k_Padding, rect.height);
rect.width = w;
EditorGUI.BeginChangeCheck();
EditorGUI.PropertyField(rect, property.FindPropertyRelative("m_Rig"), label);
var indentLvl = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
EditorGUI.PropertyField(weightRect, property.FindPropertyRelative("m_Active"), GUIContent.none);
EditorGUI.indentLevel = indentLvl;
if (EditorGUI.EndChangeCheck())
property.serializedObject.ApplyModifiedProperties();
EditorGUI.EndProperty();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cfddd68cbf078454ab5dfd53ed554127
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,12 @@
using UnityEngine.Animations.Rigging;
namespace UnityEditor.Animations.Rigging
{
[CustomEditor(typeof(RigTransform))]
class RigTransformEditor : Editor
{
public override void OnInspectorGUI()
{
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ab480ae8b7295e54c9c72a011401317e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,249 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.Animations.Rigging;
using UnityObject = UnityEngine.Object;
namespace UnityEditor.Animations.Rigging
{
[CustomPropertyDrawer(typeof(WeightedTransformArray))]
sealed class WeightedTransformArrayDrawer : PropertyDrawer
{
const string k_LengthPath = "m_Length";
const string k_ItemTransformPath = nameof(WeightedTransform.transform);
const string k_ItemWeightPath = nameof(WeightedTransform.weight);
static readonly string[] k_ItemPropertyPaths =
Enumerable.Range(0, WeightedTransformArray.k_MaxLength).Select(i => $"m_Item{i}").ToArray();
// one reorderable list per unique property path
readonly Dictionary<string, (ReorderableList listControl, SerializedProperty lengthProperty)> m_GUIState =
new Dictionary<string, (ReorderableList listControl, SerializedProperty lengthProperty)>();
// function to get WeightedTransform from item property
static WeightedTransform GetValueSingle(SerializedProperty item) => new WeightedTransform
{
transform = item.FindPropertyRelative(k_ItemTransformPath).objectReferenceValue as Transform,
weight = item.FindPropertyRelative(k_ItemWeightPath).floatValue
};
// function to modify a list of items per target
static void ModifyItemsSingle(SerializedProperty parentProperty, Action<List<WeightedTransform>> modifyList)
{
foreach (var target in parentProperty.serializedObject.targetObjects)
{
using (var so = new SerializedObject(target))
{
var sp = so.FindProperty(parentProperty.propertyPath);
var length = sp.FindPropertyRelative(k_LengthPath);
// create a live list of items
var items =
Enumerable.Range(0, length.intValue)
.Select(i => GetValueSingle(sp.FindPropertyRelative(k_ItemPropertyPaths[i])))
.ToList();
// modify the list
modifyList(items);
// write the results back to the serialized data stream
for (var i = 0; i < items.Count; ++i)
{
var item = sp.FindPropertyRelative(k_ItemPropertyPaths[i]);
item.FindPropertyRelative(k_ItemTransformPath).objectReferenceValue = items[i].transform;
item.FindPropertyRelative(k_ItemWeightPath).floatValue = items[i].weight;
}
// clear other items
for (var i = items.Count; i < WeightedTransformArray.k_MaxLength; ++i)
{
var item = sp.FindPropertyRelative(k_ItemPropertyPaths[i]);
item.FindPropertyRelative(k_ItemTransformPath).objectReferenceValue = default;
item.FindPropertyRelative(k_ItemWeightPath).floatValue = default;
}
// synchronize length property
length.intValue = items.Count;
// write back results
so.ApplyModifiedProperties();
}
}
// update parent property's serialized data stream to get new (shared) values for all targets
parentProperty.serializedObject.Update();
}
(ReorderableList listControl, SerializedProperty lengthProperty) GetGUIState(SerializedProperty property, GUIContent label)
{
var lengthProperty = property.FindPropertyRelative(k_LengthPath);
// create a new reorderable list if one does not exist
if (!m_GUIState.TryGetValue(property.propertyPath, out var guiState))
{
// bind the control to a proxy list
var proxy = Enumerable.Range(0, lengthProperty.intValue)
.ToList();
var reorderableList = new ReorderableList(proxy, typeof(int));
reorderableList.headerHeight = Styles.minHeaderHeight;
// default array control only allocates single line height, but that leaves no spacing between object fields
reorderableList.elementHeight =
EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
var attr = fieldInfo.GetCustomAttribute<WeightRangeAttribute>();
var legacyAttr = fieldInfo.GetCustomAttribute<RangeAttribute>();
var min = attr?.min ?? legacyAttr?.min ?? float.NaN;
var max = attr?.max ?? legacyAttr?.max ?? float.NaN;
var spacing = EditorGUIUtility.standardVerticalSpacing / 2f;
reorderableList.drawElementCallback += (rect, index, active, focused) =>
{
rect = new Rect(rect) { height = EditorGUIUtility.singleLineHeight, y = rect.y + spacing };
WeightedTransformDrawer.DoGUI(rect, property.FindPropertyRelative(k_ItemPropertyPaths[index]), min, max);
};
reorderableList.onCanAddCallback += list =>
!Application.isPlaying
&& !AnimationMode.InAnimationMode()
&& lengthProperty.intValue < WeightedTransformArray.k_MaxLength;
reorderableList.onCanRemoveCallback += list =>
!Application.isPlaying
&& !AnimationMode.InAnimationMode()
&& lengthProperty.intValue > 0;
reorderableList.onAddCallback += list =>
{
ModifyItemsSingle(property, items =>
{
int insertIndex = Math.Max(0, reorderableList.index >= 0 ? reorderableList.index : items.Count - 1);
if (items.Count < WeightedTransformArray.k_MaxLength)
items.Insert(insertIndex, insertIndex < items.Count ? items[insertIndex] : WeightedTransform.Default(1f));
});
proxy.Add(proxy.Count);
};
reorderableList.onRemoveCallback += list =>
{
ModifyItemsSingle(property, items =>
{
int removeIndex = Math.Max(0, reorderableList.index >= 0 ? reorderableList.index : items.Count - 1);
if (removeIndex >= 0)
items.RemoveAt(removeIndex);
});
proxy.RemoveAt(proxy.Count - 1);
};
reorderableList.onReorderCallbackWithDetails += (list, srcIndex, dstIndex) =>
ModifyItemsSingle(property, items =>
{
var moved = items[srcIndex];
items.RemoveAt(srcIndex);
items.Insert(dstIndex, moved);
});
guiState = m_GUIState[property.propertyPath] = (reorderableList, lengthProperty.Copy());
}
// synchronize proxy list to serialized length
var proxyList = guiState.listControl.list;
while (proxyList.Count < lengthProperty.intValue)
proxyList.Add(proxyList.Count);
while (proxyList.Count > lengthProperty.intValue)
proxyList.RemoveAt(proxyList.Count - 1);
return guiState;
}
static class Styles
{
// cf. ReorderableList.Defaults.minHeaderHeight;
public static float minHeaderHeight = 2f;
// cf. ReorderableListWrapper.cs
public const float headerPadding = 3f;
public const float arraySizeWidth = 50f; // 48 in ReorderableListWrapper, but EditorGUI.Slider() field is 50
public const float defaultFoldoutHeaderHeight = 18f;
public static readonly GUIContent sizeLabel = EditorGUIUtility.TrTextContent("", "Length");
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) =>
Styles.defaultFoldoutHeaderHeight
+ (property.isExpanded ? Styles.headerPadding + GetGUIState(property, label).listControl.GetHeight() : 0f);
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var guiState = GetGUIState(property, label);
Rect headerRect = new Rect(position) { height = EditorGUIUtility.singleLineHeight };
Rect sizeRect = new Rect(headerRect) { xMin = headerRect.xMax - Styles.arraySizeWidth };
EventType prevType = Event.current.type;
if (Event.current.type == EventType.MouseUp && sizeRect.Contains(Event.current.mousePosition))
{
Event.current.type = EventType.Used;
}
property.isExpanded = EditorGUI.BeginFoldoutHeaderGroup(headerRect, property.isExpanded, label);
EditorGUI.EndFoldoutHeaderGroup();
if (Event.current.type == EventType.Used && sizeRect.Contains(Event.current.mousePosition)) Event.current.type = prevType;
EditorGUI.BeginChangeCheck();
EditorGUI.DelayedIntField(sizeRect, guiState.lengthProperty, Styles.sizeLabel);
if (EditorGUI.EndChangeCheck())
guiState.lengthProperty.intValue = Mathf.Clamp(guiState.lengthProperty.intValue, 0, WeightedTransformArray.k_MaxLength);
EditorGUI.LabelField(sizeRect, Styles.sizeLabel);
if (headerRect.Contains(Event.current.mousePosition))
{
if (Event.current.type == EventType.DragUpdated || Event.current.type == EventType.DragPerform)
{
OnDropObjects(property, DragAndDrop.objectReferences, guiState.listControl);
DragAndDrop.AcceptDrag();
Event.current.Use();
}
}
if (Event.current.type == EventType.DragExited)
{
DragAndDrop.visualMode = DragAndDropVisualMode.None;
Event.current.Use();
}
if (property.isExpanded)
guiState.listControl.DoList(new Rect(position) { yMin = headerRect.yMax + Styles.headerPadding });
}
static void OnDropObjects(SerializedProperty property, UnityObject[] objectReferences, ReorderableList listControl)
{
foreach (var o in objectReferences)
{
var go = o as GameObject;
var c = o as Component;
if (go == null && c == null)
continue;
if (listControl.list.Count >= WeightedTransformArray.k_MaxLength)
{
DragAndDrop.visualMode = DragAndDropVisualMode.Rejected;
continue;
}
DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
var t = c == null ? go.transform : c.transform;
if (Event.current.type == EventType.DragPerform)
{
ModifyItemsSingle(property, items =>
{
var weight = items.Count == 0 ? 1f : items[items.Count - 1].weight;
items.Add(new WeightedTransform(t, weight));
});
listControl.list.Add(listControl.list.Count);
}
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ee7818cdc02e4548adb5ae6bc5901523
timeCreated: 1607593832

View File

@@ -0,0 +1,59 @@
using System.Reflection;
using UnityEngine;
using UnityEngine.Animations.Rigging;
namespace UnityEditor.Animations.Rigging
{
[CustomPropertyDrawer(typeof(WeightedTransform))]
class WeightedTransformDrawer : PropertyDrawer
{
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) =>
EditorGUIUtility.singleLineHeight;
(WeightRangeAttribute attr, RangeAttribute legacyAttr)? m_RangeAttributes;
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
{
var (attr, legacyAttr) = m_RangeAttributes ??= (
fieldInfo.GetCustomAttribute<WeightRangeAttribute>(),
fieldInfo.GetCustomAttribute<RangeAttribute>()
);
float min = attr?.min ?? legacyAttr?.min ?? float.NaN;
float max = attr?.max ?? legacyAttr?.max ?? float.NaN;
DoGUI(rect, property, min, max);
}
static class Styles
{
public static float transformFieldWidthScale = 0.65f;
public static readonly int horizontalMargin = (
EditorStyles.objectField.margin.right + GUI.skin.horizontalSlider.margin.left
) / 2;
}
internal static void DoGUI(Rect rect, SerializedProperty property, float min, float max)
{
EditorGUI.BeginProperty(rect, GUIContent.none, property);
var w = rect.width * Styles.transformFieldWidthScale;
var weightRect = new Rect(rect.x + w, rect.y, rect.width - w, EditorGUIUtility.singleLineHeight);
rect.width = w;
var transformRect = new Rect(rect.x, rect.y, rect.width - Styles.horizontalMargin, EditorGUIUtility.singleLineHeight);
EditorGUI.PropertyField(transformRect, property.FindPropertyRelative("transform"), GUIContent.none);
var indentLvl = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;
if (float.IsNaN(max) || float.IsNaN(min))
EditorGUI.PropertyField(weightRect, property.FindPropertyRelative("weight"), GUIContent.none);
else
EditorGUI.Slider(weightRect, property.FindPropertyRelative("weight"), min, max, GUIContent.none);
EditorGUI.indentLevel = indentLvl;
EditorGUI.EndProperty();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a015bc034afc6b742996a3d23fa85902
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: