first commit
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a8670d948642f1546a4835c189aea303
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 63110210264e2ee4da7389733e5958ae
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99a3cbe2e69614541bdf264c5e905f48
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a96277d4d9d2d04181fc5ce44119fdf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2326ba71c8dbcba4ea941bf20e7e1bbc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ca0517db96fdfc41b4230a34d84b37c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 74cfdd6a1e6ff244496d38de0c2bbee5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91a61b91969f07d448049f1b2c1bf3c8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16cd7f77b75e35946b191bd98757e5a2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f51e9e105d754014895d13788b539ae
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e52e5d5c12dea4e4397e6781cbeac36d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d47d5b10876eed042af2bccb184f9a5b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user