public static void JointLookAt(ConfigurableJoint joint, Transform pivot, Vector3 destinationWorldPos, Quaternion initialConnectedBodyLocalRotation) { Rigidbody rb = joint.GetComponent <Rigidbody>(); Quaternion desiredWorldRot = Quaternion.LookRotation(destinationWorldPos - pivot.position); Quaternion deltaPivotRot = Quaternion.Inverse(pivot.rotation) * desiredWorldRot; Quaternion rbWorldRot = rb.rotation * deltaPivotRot; if (joint.configuredInWorldSpace) { Quaternion worldToJointSpace = ConfigurableJointExtensions.GetWorldToJointSpace(joint); Quaternion jointSpaceToWorld = Quaternion.Inverse(worldToJointSpace); Quaternion resultRotation = ConfigurableJointExtensions.GetWorldResultRotation(joint, rbWorldRot, initialConnectedBodyLocalRotation, Space.World, jointSpaceToWorld); // Transform back into joint space resultRotation *= worldToJointSpace; // Set target rotation to our newly calculated rotation joint.targetRotation = resultRotation; } else { Quaternion connectedBodyDesiredLocalRot = Quaternion.Inverse(joint.connectedBody.rotation) * rbWorldRot; ConfigurableJointExtensions.SetTargetRotationLocal(joint, connectedBodyDesiredLocalRot, initialConnectedBodyLocalRotation); } }
// Does what the name says private void UpdateJointTargetRotation() { for (int i = 0; i < RagdollJoints.Count; i++) { ConfigurableJointExtensions.SetTargetRotationLocal(RagdollJoints[i], AnimationObjects[i].transform.rotation, JointInitialRotation[i]); } }
public static ConfigurableJoint CreateSnapJoint(Rigidbody body, Rigidbody connectedBody, Vector3 pointPosition, Quaternion pointRotation, Vector3 destinationPosition, Quaternion destinationRotation, bool matchRotation, bool enableCollisions, float massScale) { // Initial configuration ConfigurableJoint joint = body.gameObject.AddComponent <ConfigurableJoint>(); joint.connectedBody = connectedBody; joint.autoConfigureConnectedAnchor = false; joint.configuredInWorldSpace = false; joint.anchor = joint.transform.InverseTransformPoint(pointPosition); joint.connectedAnchor = joint.connectedBody.transform.InverseTransformPoint(destinationPosition); joint.massScale = massScale; joint.enableCollision = enableCollisions; // Linear limits joint.xMotion = ConfigurableJointMotion.Free; joint.yMotion = ConfigurableJointMotion.Free; joint.zMotion = ConfigurableJointMotion.Free; joint.targetPosition = Vector3.zero; // Target rotation if (matchRotation) { Quaternion initialRotation = joint.transform.rotation; Quaternion worldToJointSpace = ConfigurableJointExtensions.GetWorldToJointSpace(joint); Quaternion jointSpaceToWorld = Quaternion.Inverse(worldToJointSpace); Quaternion desiredWorldRot = (destinationRotation * Quaternion.Inverse(pointRotation)) * joint.transform.rotation; Quaternion resultRotation = jointSpaceToWorld * Quaternion.Inverse(desiredWorldRot) * initialRotation; // Transform back into joint space resultRotation *= worldToJointSpace; // Set target rotation to our newly calculated rotation joint.targetRotation = resultRotation; JointDrive rotDrive = new JointDrive(); rotDrive.positionDamper = 0.0f; rotDrive.maximumForce = 0.0f; rotDrive.positionSpring = 0.0f; joint.rotationDriveMode = RotationDriveMode.Slerp; joint.slerpDrive = rotDrive; } return(joint); }
private void UpdateSlaveBone(SlaveBoneModel slaveBone, Transform master, Space space, SlaveBoneConfiguration boneConf) { if (!slaveBone.jointRef) { return; } if (boneConf.followsPosition) { if (boneConf.useTargetPos) { if (space == Space.Self && slaveBone.jointRef.configuredInWorldSpace) { Debug.LogError(slaveBone.name + " is configured in world space. You can't use local position as target position here"); } if (space == Space.World && !slaveBone.jointRef.configuredInWorldSpace) { Debug.LogError(slaveBone.name + " is configured in local space. You can't use world position as target position here"); } Vector3 desiredWorldPosition = PhysHelpers.GetDesiredWorldPos(slaveBone.transformRef, master, space); if (slaveBone.jointRef.configuredInWorldSpace) { slaveBone.jointRef.connectedAnchor = desiredWorldPosition; } else { slaveBone.jointRef.connectedAnchor = slaveBone.jointRef.connectedBody.transform.InverseTransformPoint(desiredWorldPosition); } } else { // Position Vector3 desiredPosition = PhysHelpers.GetDesiredWorldPos(slaveBone.transformRef, master, space); // Velocity Vector3 newVelocity = (desiredPosition - slaveBone.transformRef.position) / Time.fixedDeltaTime; slaveBone.rigidbodyRef.velocity = newVelocity; } } if (boneConf.followsRotation) { // Error logs if (space == Space.Self && slaveBone.jointRef.configuredInWorldSpace) { Debug.LogError(slaveBone.name + " is configured in world space. You can't use local rotation as target rotation here"); } if (space == Space.World && !slaveBone.jointRef.configuredInWorldSpace) { Debug.LogError(slaveBone.name + " is configured in local space. You can't use world rotation as target rotation here"); } if (space == Space.Self) { Quaternion clampedLocalRot = master.localRotation; if (slaveBone.minLocalRot.eulerAngles.z > 180.0f /* && * master.localRotation.eulerAngles.z < slaveBone.minLocalRot.eulerAngles.z*/) { clampedLocalRot = slaveBone.minLocalRot; } ConfigurableJointExtensions.SetTargetRotationLocal(slaveBone.jointRef, clampedLocalRot, slaveBone.initialConnectedBodyLocalRotation); } else { Quaternion worldToJointSpace = ConfigurableJointExtensions.GetWorldToJointSpace(slaveBone.jointRef); Quaternion jointSpaceToWorld = Quaternion.Inverse(worldToJointSpace); Quaternion resultRotation = ConfigurableJointExtensions.GetWorldResultRotation(slaveBone.jointRef, master.rotation, slaveBone.initialConnectedBodyLocalRotation, space, jointSpaceToWorld); // Transform back into joint space resultRotation *= worldToJointSpace; // Set target rotation to our newly calculated rotation slaveBone.jointRef.targetRotation = resultRotation; } // Local rotation offset slaveBone.jointRef.targetRotation *= Quaternion.Euler(slaveBone.targetEulerOffsetRot); if (boneConf.useDynamicStrength) { PhysHelpers.UpdateBoneStrength(slaveBone, boneConf.minDynamicRotDrive.toJointDrive(), boneConf.maxDynamicRotDrive.toJointDrive(), slaveBone.finger.strengthLerp); } } if (boneConf.clampLinearVelocity) { slaveBone.rigidbodyRef.velocity = Vector3.ClampMagnitude(slaveBone.rigidbodyRef.velocity, boneConf.maxLinearVelocity); } if (boneConf.clampAngularVelocity) { slaveBone.rigidbodyRef.angularVelocity = Vector3.ClampMagnitude(slaveBone.rigidbodyRef.angularVelocity, boneConf.maxAngularVelocity); } }