Files
2026-03-04 09:37:33 +08:00

132 lines
4.5 KiB
C#

using System;
using UnityEngine;
namespace RootMotion.FinalIK
{
public class UniversalPoser : Poser
{
[Serializable]
public class Map
{
public Transform bone;
[HideInInspector]
public Transform target;
private Vector3 defaultLocalPosition;
private Quaternion defaultLocalRotation;
public Map(Transform bone, Transform target)
{
this.bone = bone;
this.target = target;
StoreDefaultState();
}
public void StoreDefaultState()
{
defaultLocalPosition = bone.localPosition;
defaultLocalRotation = bone.localRotation;
}
public void FixTransform()
{
bone.localPosition = defaultLocalPosition;
bone.localRotation = defaultLocalRotation;
}
public void Update(float localRotationWeight, float localPositionWeight, Vector3 targetAxis1, Vector3 targetAxis2, Vector3 axis1, Vector3 axis2)
{
if (targetAxis1 == axis1 && targetAxis2 == axis2)
{
bone.localRotation = Quaternion.Lerp(bone.localRotation, target.localRotation, localRotationWeight);
return;
}
Quaternion quaternion = Quaternion.Lerp(bone.localRotation, QuaTools.MatchRotation(target.localRotation, targetAxis1, targetAxis2, axis1, axis2), localRotationWeight);
Quaternion quaternion2 = QuaTools.MatchRotation(Quaternion.identity, targetAxis1, targetAxis2, axis1, axis2);
bone.localRotation = quaternion2 * quaternion;
}
}
[Tooltip("Choose 2 axes of a finger bone. For example 1 pointing towards the next finger and 2 pointing up. Select a finger bone in the InteractionTarget hierarchy and see which local axis points towards the next bone and which local axis points up and set targetAxis1 and targetAxis2 accordingly. Then select a finger in this poser's hierarchy and do the same for axis1 and axis2.")]
public Vector3 targetAxis1;
[Tooltip("Choose 2 axes of a finger bone. For example 1 pointing towards the next finger and 2 pointing up. Select a finger bone in the InteractionTarget hierarchy and see which local axis points towards the next bone and which local axis points up and set targetAxis1 and targetAxis2 accordingly. Then select a finger in this poser's hierarchy and do the same for axis1 and axis2.")]
public Vector3 targetAxis2;
[Tooltip("Choose 2 axes of a finger bone. For example 1 pointing towards the next finger and 2 pointing up. Select a finger bone in the InteractionTarget hierarchy and see which local axis points towards the next bone and which local axis points up and set targetAxis1 and targetAxis2 accordingly. Then select a finger in this poser's hierarchy and do the same for axis1 and axis2.")]
public Vector3 axis1;
[Tooltip("Choose 2 axes of a finger bone. For example 1 pointing towards the next finger and 2 pointing up. Select a finger bone in the InteractionTarget hierarchy and see which local axis points towards the next bone and which local axis points up and set targetAxis1 and targetAxis2 accordingly. Then select a finger in this poser's hierarchy and do the same for axis1 and axis2.")]
public Vector3 axis2;
[Tooltip("List of bones must match InteractionTarget's list of bones in both array size and hierarchy.")]
public Map[] bones;
public override void AutoMapping()
{
}
public override void AutoMapping(Transform[] bones)
{
if (bones.Length != this.bones.Length)
{
Debug.LogError("Trying to use UniversalPoser with an InteractionTarget that has a different number of bones. Bones must match with UniversalPoser bones in both array size and hierarchy", base.transform);
return;
}
for (int i = 0; i < this.bones.Length; i++)
{
this.bones[i].target = bones[i];
}
StoreDefaultState();
}
protected override void InitiatePoser()
{
StoreDefaultState();
}
protected override void UpdatePoser()
{
if (!(weight <= 0f) && (!(localPositionWeight <= 0f) || !(localRotationWeight <= 0f)) && !(poseRoot == null))
{
float num = localRotationWeight * weight;
float num2 = localPositionWeight * weight;
for (int i = 0; i < bones.Length; i++)
{
bones[i].Update(num, num2, targetAxis1, targetAxis2, axis1, axis2);
}
}
}
protected override void FixPoserTransforms()
{
for (int i = 0; i < bones.Length; i++)
{
bones[i].FixTransform();
}
}
private void StoreDefaultState()
{
for (int i = 0; i < bones.Length; i++)
{
bones[i].StoreDefaultState();
}
}
private Transform GetTargetNamed(string tName, Transform[] array)
{
for (int i = 0; i < array.Length; i++)
{
if (array[i].name == tName)
{
return array[i];
}
}
return null;
}
}
}