using UnityEngine; using FSA = UnityEngine.Serialization.FormerlySerializedAsAttribute; namespace Lean.Common { /// This component rotates the current GameObject based on the current Angle value. /// NOTE: This component overrides and takes over the rotation of this GameObject, so you can no longer externally influence it. [ExecuteInEditMode] [HelpURL(LeanHelper.HelpUrlPrefix + "LeanRoll")] [AddComponentMenu(LeanHelper.ComponentPathPrefix + "Roll")] public class LeanRoll : MonoBehaviour { /// The current angle in degrees. public float Angle { set { angle = value; } get { return angle; } } [FSA("Angle")] [SerializeField] private float angle; /// Should the Angle value be clamped? public bool Clamp { set { clamp = value; } get { return clamp; } } [FSA("Clamp")] [SerializeField] private bool clamp; /// The minimum Angle value. public float ClampMin { set { clampMin = value; } get { return clampMin; } } [FSA("ClampMin")] [SerializeField] private float clampMin; /// The maximum Angle value. public float ClampMax { set { clampMax = value; } get { return clampMax; } } [FSA("ClampMax")] [SerializeField] private float clampMax; /// If you want this component to change smoothly over time, then this allows you to control how quick the changes reach their target value. /// -1 = Instantly change. /// 1 = Slowly change. /// 10 = Quickly change. public float Damping { set { damping = value; } get { return damping; } } [FSA("Damping")] [FSA("Dampening")] [SerializeField] private float damping = -1.0f; [SerializeField] private float currentAngle; /// The Angle value will be incremented by the specified angle in degrees. public void IncrementAngle(float delta) { angle += delta; } /// The Angle value will be decremented by the specified angle in degrees. public void DecrementAngle(float delta) { angle -= delta; } /// This method will update the Angle value based on the specified vector. public void RotateToDelta(Vector2 delta) { if (delta.sqrMagnitude > 0.0f) { angle = Mathf.Atan2(delta.x, delta.y) * Mathf.Rad2Deg; } } /// This method will immediately snap the current angle to its target value. [ContextMenu("Snap To Target")] public void SnapToTarget() { currentAngle = angle; } protected virtual void Start() { currentAngle = angle; } protected virtual void Update() { // Get t value var factor = LeanHelper.GetDampenFactor(damping, Time.deltaTime); if (clamp == true) { angle = Mathf.Clamp(angle, clampMin, clampMax); } // Lerp angle currentAngle = Mathf.LerpAngle(currentAngle, angle, factor); // Update rotation transform.rotation = Quaternion.Euler(0.0f, 0.0f, -currentAngle); } } } #if UNITY_EDITOR namespace Lean.Common.Editor { using TARGET = LeanRoll; [UnityEditor.CanEditMultipleObjects] [UnityEditor.CustomEditor(typeof(TARGET))] public class LeanRoll_Editor : LeanEditor { protected override void OnInspector() { TARGET tgt; TARGET[] tgts; GetTargets(out tgt, out tgts); Draw("angle", "The current angle in degrees."); Draw("clamp", "Should the Angle value be clamped?"); if (Any(tgts, t => t.Clamp == true)) { BeginIndent(); Draw("clampMin", "The minimum Angle value.", "Min"); Draw("clampMax", "The maximum Angle value.", "Max"); EndIndent(); Separator(); } Draw("damping", "If you want this component to change smoothly over time, then this allows you to control how quick the changes reach their target value.\n\n-1 = Instantly change.\n\n1 = Slowly change.\n\n10 = Quickly change."); } } } #endif