using UnityEngine; using DentedPixel; namespace BulletHellTemplate { /// /// UpgradeAnimation uses LeanTween to move a 3D GameObject on selected axes, /// rotate it on selected axes, and then return it to its original position and rotation. /// It supports both discrete rotation (by a fixed angle) and continuous rotation /// for a defined duration. /// public class UpgradeAnimation : MonoBehaviour { #region Inspector Fields [Header("Target Settings")] /// /// Reference to the GameObject that will be moved and rotated. /// [Tooltip("Reference to the GameObject that will be moved and rotated.")] public GameObject targetObject; [Header("Movement Settings")] /// /// Movement offset for each axis. Set non-zero values for the axes you want to move. /// [Tooltip("Movement offset for each axis. Set non-zero values for the axes you want to move.")] public Vector3 moveDistance = new Vector3(5f, 0f, 0f); /// /// Time in seconds for moving from the start position to the target position. /// [Tooltip("Time in seconds for moving from the start position to the target position.")] public float moveTime = 1f; /// /// LeanTweenType used for the movement tween. /// [Tooltip("LeanTweenType used for the movement tween.")] public LeanTweenType moveTweenType = LeanTweenType.linear; [Header("Rotation Settings")] /// /// Delay in seconds before starting the rotation after the movement completes. /// [Tooltip("Delay in seconds before starting the rotation after the movement completes.")] public float delayBeforeRotation = 0.5f; /// /// Discrete rotation offset in degrees for each axis. /// Used when continuousRotation is false. /// [Tooltip("Discrete rotation offset in degrees for each axis. Used when continuousRotation is false.")] public Vector3 rotationAngle = new Vector3(45f, 0f, 0f); /// /// Time in seconds for performing the rotation tween. /// When continuousRotation is false, it rotates by rotationAngle. /// When continuousRotation is true, it continuously rotates for this duration. /// [Tooltip("Time in seconds for performing the rotation tween.")] public float rotationTime = 1f; /// /// Time in seconds for returning from the current rotation to the original rotation. /// [Tooltip("Time in seconds for returning from the current rotation to the original rotation.")] public float returnRotationTime = 1f; /// /// LeanTweenType used for the rotation tween. /// [Tooltip("LeanTweenType used for the rotation tween.")] public LeanTweenType rotationTweenType = LeanTweenType.linear; [Header("Continuous Rotation Settings")] /// /// If true, the object will continuously rotate for the duration specified in rotationTime, /// instead of performing a discrete rotation by a fixed angle. /// [Tooltip("If true, the object will continuously rotate for the duration specified in rotationTime.")] public bool continuousRotation = false; /// /// Rotation speed in degrees per second for continuous rotation. /// Only used if continuousRotation is true. /// [Tooltip("Rotation speed in degrees per second for continuous rotation. Only used if continuousRotation is true.")] public Vector3 continuousRotationSpeed = new Vector3(45f, 0f, 0f); [Header("Return Movement")] /// /// Time in seconds to move back to the original position. /// [Tooltip("Time in seconds to move back to the original position.")] public float returnMoveTime = 1f; /// /// LeanTweenType used for the return movement tween. /// [Tooltip("LeanTweenType used for the return movement tween.")] public LeanTweenType returnMoveTweenType = LeanTweenType.linear; [Header("Restart Settings")] /// /// If true, when StartMovement is called again, any ongoing tween sequence will be canceled and restarted. /// [Tooltip("If true, when StartMovement is called again, any ongoing tween sequence will be canceled and restarted.")] public bool restartIfCalledAgain = true; #endregion #region Private Fields /// /// The original local position of the target. /// private Vector3 originalPosition; /// /// The original local rotation of the target. /// private Quaternion originalRotation; #endregion #region Unity Callbacks /// /// Stores the initial position and rotation of the targetObject. /// private void Awake() { if (targetObject == null) { targetObject = this.gameObject; } originalPosition = targetObject.transform.localPosition; originalRotation = targetObject.transform.localRotation; } /// /// Cancels all LeanTween animations when the object is disabled. /// private void OnDisable() { LeanTween.cancel(targetObject); } /// /// Cancels all LeanTween animations when the object is destroyed. /// private void OnDestroy() { LeanTween.cancel(targetObject); } #endregion #region Public Methods /// /// Starts the movement and rotation sequence using LeanTween. /// Moves to a target position by adding moveDistance to the original position, /// then after a delay rotates according to the configuration: /// - If continuousRotation is false: rotates by rotationAngle then returns to original rotation. /// - If continuousRotation is true: continuously rotates using continuousRotationSpeed for rotationTime, /// then returns to the original rotation. /// Finally, moves back to the original position. /// public void StartMovement() { if (restartIfCalledAgain) { LeanTween.cancel(targetObject); } // Restore the original local position and rotation before starting a new sequence. targetObject.transform.localPosition = originalPosition; targetObject.transform.localRotation = originalRotation; // Create a LeanTween sequence to chain the tweens. LTSeq sequence = LeanTween.sequence(); // 1) Move to target position (originalPosition + moveDistance). sequence.append( LeanTween.moveLocal(targetObject, originalPosition + moveDistance, moveTime) .setEase(moveTweenType) ); // 2) Add delay before rotation. sequence.append(delayBeforeRotation); // 3) Apply rotation. if (continuousRotation) { // Continuous rotation: update rotation over time. sequence.append( LeanTween.value(gameObject, 0f, rotationTime, rotationTime) .setEase(LeanTweenType.linear) .setOnUpdate((float t) => { Vector3 newEuler = originalRotation.eulerAngles + continuousRotationSpeed * t; targetObject.transform.localRotation = Quaternion.Euler(newEuler); }) ); } else { // Discrete rotation: rotate to a fixed angle. Vector3 targetRotationEuler = originalRotation.eulerAngles + rotationAngle; sequence.append( LeanTween.rotateLocal(targetObject, targetRotationEuler, rotationTime) .setEase(rotationTweenType) ); // Rotate back to original rotation. sequence.append( LeanTween.rotateLocal(targetObject, originalRotation.eulerAngles, returnRotationTime) .setEase(rotationTweenType) ); } // 4) Return to original rotation if continuous rotation was applied. if (continuousRotation) { sequence.append( LeanTween.rotateLocal(targetObject, originalRotation.eulerAngles, returnRotationTime) .setEase(rotationTweenType) ); } // 5) Move back to the original position. sequence.append( LeanTween.moveLocal(targetObject, originalPosition, returnMoveTime) .setEase(returnMoveTweenType) ); } #endregion } }