TwoHandedProp.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. using UnityEngine;
  2. using System.Collections;
  3. using RootMotion.FinalIK;
  4. namespace RootMotion.Demos {
  5. // Targeting hands to 2-handed props with the FullBodyBipedIK component. It is not good to parent IK targets directly to the bones that use IK (circular dependency).
  6. // The bones are moved in the solving process, but it will not update the IK targets parented to the bones. All IK target positions/rotations need to be set before the solver updates.
  7. public class TwoHandedProp : MonoBehaviour {
  8. [Tooltip("The left hand target parented to the right hand.")] public Transform leftHandTarget;
  9. private FullBodyBipedIK ik;
  10. private Vector3 targetPosRelativeToRight;
  11. private Quaternion targetRotRelativeToRight;
  12. void Start() {
  13. ik = GetComponent<FullBodyBipedIK>();
  14. // Get a call from FBBIK each time it has finished updating
  15. ik.solver.OnPostUpdate += AfterFBBIK;
  16. // Weight in the effectors
  17. ik.solver.leftHandEffector.positionWeight = 1f;
  18. ik.solver.rightHandEffector.positionWeight = 1f;
  19. if (ik.solver.rightHandEffector.target == null) Debug.LogError("Right Hand Effector needs a Target in this demo.");
  20. }
  21. void LateUpdate() {
  22. // Get the position/rotation of the left hand target relative to the right hand.
  23. targetPosRelativeToRight = ik.references.rightHand.InverseTransformPoint(leftHandTarget.position);
  24. targetRotRelativeToRight = Quaternion.Inverse(ik.references.rightHand.rotation) * leftHandTarget.rotation;
  25. // Set the position/rotation of the left hand target relative to the right hand effector target.
  26. ik.solver.leftHandEffector.position = ik.solver.rightHandEffector.target.position + ik.solver.rightHandEffector.target.rotation * targetPosRelativeToRight;
  27. ik.solver.leftHandEffector.rotation = ik.solver.rightHandEffector.target.rotation * targetRotRelativeToRight;
  28. }
  29. // Called by FBBIK after it updates
  30. void AfterFBBIK() {
  31. // Rotate the hand bones to effector.rotation directly instead of using effector.rotationWeight that might fail to get the limb bending right under some circumstances
  32. ik.solver.leftHandEffector.bone.rotation = ik.solver.leftHandEffector.rotation;
  33. ik.solver.rightHandEffector.bone.rotation = ik.solver.rightHandEffector.rotation;
  34. }
  35. // Clean up the delegate
  36. void OnDestroy() {
  37. if (ik != null) ik.solver.OnPostUpdate -= AfterFBBIK;
  38. }
  39. }
  40. }