|
|
|
|
using UnityEngine;
|
|
|
|
|
using System.Collections;
|
|
|
|
|
using RootMotion.FinalIK;
|
|
|
|
|
|
|
|
|
|
namespace RootMotion.FinalIK {
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Calculates bending direction and hand rotations for a FBBIK rig for VR hand controllers.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class FBBIKArmBending : MonoBehaviour {
|
|
|
|
|
|
|
|
|
|
public FullBodyBipedIK ik;
|
|
|
|
|
|
|
|
|
|
// Bend direction offset for the arms
|
|
|
|
|
public Vector3 bendDirectionOffsetLeft;
|
|
|
|
|
public Vector3 bendDirectionOffsetRight;
|
|
|
|
|
|
|
|
|
|
// Add some bend direction offset in character space
|
|
|
|
|
public Vector3 characterSpaceBendOffsetLeft;
|
|
|
|
|
public Vector3 characterSpaceBendOffsetRight;
|
|
|
|
|
|
|
|
|
|
private Quaternion leftHandTargetRotation;
|
|
|
|
|
private Quaternion rightHandTargetRotation;
|
|
|
|
|
private bool initiated;
|
|
|
|
|
|
|
|
|
|
void LateUpdate() {
|
|
|
|
|
if (ik == null) return;
|
|
|
|
|
|
|
|
|
|
if (!initiated) {
|
|
|
|
|
ik.solver.OnPostUpdate += OnPostFBBIK;
|
|
|
|
|
initiated = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Left arm bend direction
|
|
|
|
|
if (ik.solver.leftHandEffector.target != null) {
|
|
|
|
|
Vector3 armAxisLeft = Vector3.left;
|
|
|
|
|
ik.solver.leftArmChain.bendConstraint.direction = ik.solver.leftHandEffector.target.rotation * armAxisLeft + ik.solver.leftHandEffector.target.rotation * bendDirectionOffsetLeft + ik.transform.rotation * characterSpaceBendOffsetLeft;
|
|
|
|
|
ik.solver.leftArmChain.bendConstraint.weight = 1f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Right arm bend direction
|
|
|
|
|
if (ik.solver.rightHandEffector.target != null) {
|
|
|
|
|
Vector3 armAxisRight = Vector3.right;
|
|
|
|
|
ik.solver.rightArmChain.bendConstraint.direction = ik.solver.rightHandEffector.target.rotation * armAxisRight + ik.solver.rightHandEffector.target.rotation * bendDirectionOffsetRight + ik.transform.rotation * characterSpaceBendOffsetRight;
|
|
|
|
|
ik.solver.rightArmChain.bendConstraint.weight = 1f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnPostFBBIK() {
|
|
|
|
|
if (ik == null) return;
|
|
|
|
|
|
|
|
|
|
// Rotate hand bones
|
|
|
|
|
if (ik.solver.leftHandEffector.target != null) {
|
|
|
|
|
ik.references.leftHand.rotation = ik.solver.leftHandEffector.target.rotation;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ik.solver.rightHandEffector.target != null) {
|
|
|
|
|
ik.references.rightHand.rotation = ik.solver.rightHandEffector.target.rotation;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnDestroy() {
|
|
|
|
|
if (ik != null) ik.solver.OnPostUpdate -= OnPostFBBIK;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|