Files
2026-03-04 10:03:45 +08:00

96 lines
3.2 KiB
C#

using System;
using RootMotion.FinalIK;
using UnityEngine;
namespace RootMotion.Demos
{
public class KissingRig : MonoBehaviour
{
[Serializable]
public class Partner
{
public FullBodyBipedIK ik;
public Transform mouth;
public Transform mouthTarget;
public Transform touchTargetLeftHand;
public Transform touchTargetRightHand;
public float bodyWeightHorizontal = 0.4f;
public float bodyWeightVertical = 1f;
public float neckRotationWeight = 0.3f;
public float headTiltAngle = 10f;
public Vector3 headTiltAxis;
private Quaternion neckRotation;
private Transform neck => ik.solver.spineMapping.spineBones[ik.solver.spineMapping.spineBones.Length - 1];
public void Initiate()
{
ik.enabled = false;
}
public void Update(float weight)
{
ik.solver.leftShoulderEffector.positionWeight = weight;
ik.solver.rightShoulderEffector.positionWeight = weight;
ik.solver.leftHandEffector.positionWeight = weight;
ik.solver.rightHandEffector.positionWeight = weight;
ik.solver.leftHandEffector.rotationWeight = weight;
ik.solver.rightHandEffector.rotationWeight = weight;
ik.solver.bodyEffector.positionWeight = weight;
InverseTransformEffector(FullBodyBipedEffector.LeftShoulder, mouth, mouthTarget.position, weight);
InverseTransformEffector(FullBodyBipedEffector.RightShoulder, mouth, mouthTarget.position, weight);
InverseTransformEffector(FullBodyBipedEffector.Body, mouth, mouthTarget.position, weight);
ik.solver.bodyEffector.position = Vector3.Lerp(new Vector3(ik.solver.bodyEffector.position.x, ik.solver.bodyEffector.bone.position.y, ik.solver.bodyEffector.position.z), ik.solver.bodyEffector.position, bodyWeightVertical * weight);
ik.solver.bodyEffector.position = Vector3.Lerp(new Vector3(ik.solver.bodyEffector.bone.position.x, ik.solver.bodyEffector.position.y, ik.solver.bodyEffector.bone.position.z), ik.solver.bodyEffector.position, bodyWeightHorizontal * weight);
ik.solver.leftHandEffector.position = touchTargetLeftHand.position;
ik.solver.rightHandEffector.position = touchTargetRightHand.position;
ik.solver.leftHandEffector.rotation = touchTargetLeftHand.rotation;
ik.solver.rightHandEffector.rotation = touchTargetRightHand.rotation;
neckRotation = neck.rotation;
ik.solver.Update();
neck.rotation = Quaternion.Slerp(neck.rotation, neckRotation, neckRotationWeight * weight);
ik.references.head.localRotation = Quaternion.AngleAxis(headTiltAngle * weight, headTiltAxis) * ik.references.head.localRotation;
}
private void InverseTransformEffector(FullBodyBipedEffector effector, Transform target, Vector3 targetPosition, float weight)
{
Vector3 vector = ik.solver.GetEffector(effector).bone.position - target.position;
ik.solver.GetEffector(effector).position = Vector3.Lerp(ik.solver.GetEffector(effector).bone.position, targetPosition + vector, weight);
}
}
public Partner partner1;
public Partner partner2;
public float weight;
public int iterations = 3;
private void Start()
{
partner1.Initiate();
partner2.Initiate();
}
private void LateUpdate()
{
for (int i = 0; i < iterations; i++)
{
partner1.Update(weight);
partner2.Update(weight);
}
}
}
}