96 lines
3.2 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|