RbRotatable.cs (2401B)
1 using System; 2 using UnityEngine; 3 4 namespace Slimecing.SimpleComponents.Movement 5 { 6 [RequireComponent(typeof(Rigidbody))] 7 public class RbRotatable : MonoBehaviour 8 { 9 [SerializeField] protected float rotSpeed; 10 [SerializeField] protected float alignmentDamping; 11 [SerializeField] private float maxAngularVelocity; 12 13 private bool _slowedAngVel; 14 private bool _stoppedAngVel; 15 private Rigidbody rb; 16 17 public bool StoppedAngVel => _stoppedAngVel; 18 19 private void Awake() 20 { 21 rb = GetComponent<Rigidbody>(); 22 rb.maxAngularVelocity = maxAngularVelocity; 23 } 24 25 public void RotateToVector(Vector3 desiredLookAt) 26 { 27 Quaternion targetRotation = Quaternion.LookRotation(desiredLookAt); 28 29 if (Quaternion.Angle(transform.rotation, targetRotation) < 13) 30 { 31 if (!_slowedAngVel) 32 { 33 SlowAngularVelocity(); 34 } 35 transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotSpeed); 36 return; 37 } 38 39 if (_slowedAngVel) 40 _slowedAngVel = false; 41 if (_stoppedAngVel) 42 _stoppedAngVel = false; 43 44 Quaternion deltaRotation = Quaternion.Inverse(transform.rotation) * targetRotation; 45 Vector3 deltaAngles = GetRelativeAngles(deltaRotation.eulerAngles); 46 Vector3 spaceDeltaAngles = transform.TransformDirection(deltaAngles); 47 rb.AddTorque(rotSpeed * spaceDeltaAngles - alignmentDamping * rb.angularVelocity, ForceMode.Impulse); 48 } 49 50 private Vector3 GetRelativeAngles(Vector3 angles) 51 { 52 Vector3 relativeAngles = angles; 53 if (relativeAngles.x > 180f) 54 relativeAngles.x -= 360f; 55 if (relativeAngles.y > 180f) 56 relativeAngles.y -= 360f; 57 if (relativeAngles.z > 180f) 58 relativeAngles.z -= 360f; 59 60 return relativeAngles; 61 } 62 63 public void SlowAngularVelocity() 64 { 65 rb.angularVelocity *= 0.5f; 66 _slowedAngVel = true; 67 } 68 69 public void StopAngularVelocity() 70 { 71 rb.angularVelocity = Vector3.zero; 72 _stoppedAngVel = true; 73 } 74 75 } 76 }