You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.6 KiB
C#
75 lines
2.6 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace RootMotion.Dynamics
|
|
{
|
|
// Controls ConfigurableJoint.targetRotation and slerpDrive to match the localRotation of a target Transform.
|
|
public class Actuator : MonoBehaviour
|
|
{
|
|
public Transform target;
|
|
public float spring = 1000f;
|
|
public float damper = 100f;
|
|
|
|
private Rigidbody r;
|
|
private ConfigurableJoint joint;
|
|
private Quaternion toJointSpaceInverse = Quaternion.identity;
|
|
private Quaternion toJointSpaceDefault = Quaternion.identity;
|
|
private JointDrive slerpDrive = new JointDrive();
|
|
private float lastSpring;
|
|
private float lastDamper;
|
|
|
|
private void Start()
|
|
{
|
|
r = GetComponent<Rigidbody>();
|
|
|
|
joint = GetComponent<ConfigurableJoint>();
|
|
if (joint == null)
|
|
{
|
|
Debug.LogError("Actuator requires a ConfigurableJoint!");
|
|
enabled = false;
|
|
return;
|
|
}
|
|
|
|
// Joint space
|
|
Vector3 forward = Vector3.Cross(joint.axis, joint.secondaryAxis).normalized;
|
|
Vector3 up = Vector3.Cross(forward, joint.axis).normalized;
|
|
|
|
Quaternion defaultLocalRotation = transform.localRotation;
|
|
Quaternion toJointSpace = Quaternion.LookRotation(forward, up);
|
|
toJointSpaceInverse = Quaternion.Inverse(toJointSpace);
|
|
toJointSpaceDefault = defaultLocalRotation * toJointSpace;
|
|
|
|
// Set joint params
|
|
joint.rotationDriveMode = RotationDriveMode.Slerp;
|
|
joint.configuredInWorldSpace = false;
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
if (r.isKinematic) return;
|
|
|
|
// Update joint.targetRotation
|
|
if (spring > 0f) joint.targetRotation = LocalToJointSpace(target.localRotation);
|
|
|
|
// No need to update slerp drive if spring or damper haven't changed
|
|
if (spring == lastSpring && damper == lastDamper) return;
|
|
lastSpring = spring;
|
|
lastDamper = damper;
|
|
|
|
// Update slerp drive
|
|
slerpDrive.positionSpring = spring;
|
|
slerpDrive.positionDamper = damper;
|
|
slerpDrive.maximumForce = Mathf.Max(spring, damper);
|
|
joint.slerpDrive = slerpDrive;
|
|
}
|
|
|
|
// Convert a local rotation to local joint space rotation
|
|
private Quaternion LocalToJointSpace(Quaternion localRotation)
|
|
{
|
|
return toJointSpaceInverse * Quaternion.Inverse(localRotation) * toJointSpaceDefault;
|
|
}
|
|
|
|
}
|
|
}
|