using DentedPixel; using UnityEngine; using UnityEngine.EventSystems; namespace BulletHellTemplate { /// /// EnhancedButtonAnimation provides advanced button interaction animations such as scale, position shift, fade, shake, and a looping pulse effect. /// Attach this script to a UI button or any UI element to animate hover, press, and release interactions. /// public class EnhancedButtonAnimation : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler { /// /// Enum for selecting the axis along which to move the UI element. /// public enum MovementAxis { None, Horizontal, Vertical, Both } [Header("Button Transform Settings")] /// /// The transform of the button to animate. /// [Tooltip("The transform of the button to animate.")] public Transform buttonTransform; /// /// Optional CanvasGroup for fade animations. If not assigned, it will be added automatically. /// [Tooltip("Optional CanvasGroup for fade animations. If not assigned, it will be added automatically.")] public CanvasGroup canvasGroup; private Vector3 originalScale; private Vector3 originalPosition; [Header("Scale Animation Settings")] /// /// Scale factor applied when the button is hovered. /// [Tooltip("Scale factor applied when the button is hovered.")] public float hoverScaleFactor = 1.05f; /// /// Scale factor applied when the button is pressed. /// [Tooltip("Scale factor applied when the button is pressed.")] public float pressScaleFactor = 0.95f; /// /// Duration for scale animations. /// [Tooltip("Duration for scale animations.")] public float scaleAnimationDuration = 0.1f; [Header("Position Shift Settings")] /// /// Axis along which the button will shift on hover. /// [Tooltip("Axis along which the button will shift on hover.")] public MovementAxis hoverMovementAxis = MovementAxis.None; /// /// Distance in pixels for the position shift on hover. /// [Tooltip("Distance in pixels for the position shift on hover.")] public float hoverMoveDistance = 10f; [Header("Fade Animation Settings")] /// /// If true, the button will fade when hovered. /// [Tooltip("If true, the button will fade when hovered.")] public bool applyFadeOnHover = false; /// /// Target alpha for the fade effect on hover. /// [Tooltip("Target alpha for the fade effect on hover.")] public float hoverFadeAlpha = 0.8f; /// /// Duration for fade animations. /// [Tooltip("Duration for fade animations.")] public float fadeAnimationDuration = 0.1f; [Header("Shake Animation Settings")] /// /// If true, a shake effect will be applied when the button is clicked. /// [Tooltip("If true, a shake effect will be applied when the button is clicked.")] public bool applyShakeOnClick = false; /// /// Duration of the shake effect. /// [Tooltip("Duration of the shake effect.")] public float shakeDuration = 0.2f; /// /// Strength of the shake effect in pixels. /// [Tooltip("Strength of the shake effect in pixels.")] public float shakeStrength = 10f; [Header("Loop Animation Settings (Pulse)")] /// /// If true, the button will continuously pulse (scale up and down). /// [Tooltip("If true, the button will continuously pulse (scale up and down).")] public bool enablePulseLoop = false; /// /// Scale factor for the pulse loop. /// [Tooltip("Scale factor for the pulse loop.")] public float pulseScaleFactor = 1.1f; /// /// Duration for one pulse cycle. /// [Tooltip("Duration for one pulse cycle.")] public float pulseDuration = 0.5f; private void Awake() { if (buttonTransform == null) { buttonTransform = transform; } originalScale = buttonTransform.localScale; originalPosition = buttonTransform.localPosition; if (applyFadeOnHover && canvasGroup == null) { canvasGroup = buttonTransform.GetComponent(); if (canvasGroup == null) { canvasGroup = buttonTransform.gameObject.AddComponent(); } } } private void Start() { // Optionally start a pulse loop animation if (enablePulseLoop) { StartPulseLoop(); } } /// /// Starts a continuous pulse animation on the button. /// public void StartPulseLoop() { LeanTween.scale(buttonTransform.gameObject, originalScale * pulseScaleFactor, pulseDuration) .setEase(LeanTweenType.easeInOutSine) .setLoopPingPong(); } /// /// Called when the pointer enters the button area. /// /// Pointer event data. public void OnPointerEnter(PointerEventData eventData) { // Scale animation on hover LeanTween.scale(buttonTransform.gameObject, originalScale * hoverScaleFactor, scaleAnimationDuration) .setEase(LeanTweenType.easeOutQuad); // Position shift on hover based on selected axis Vector3 targetPos = originalPosition; switch (hoverMovementAxis) { case MovementAxis.Horizontal: targetPos.x += hoverMoveDistance; break; case MovementAxis.Vertical: targetPos.y += hoverMoveDistance; break; case MovementAxis.Both: targetPos += new Vector3(hoverMoveDistance, hoverMoveDistance, 0f); break; default: break; } LeanTween.moveLocal(buttonTransform.gameObject, targetPos, scaleAnimationDuration) .setEase(LeanTweenType.easeOutQuad); // Fade effect on hover if (applyFadeOnHover && canvasGroup != null) { LeanTween.alphaCanvas(canvasGroup, hoverFadeAlpha, fadeAnimationDuration) .setEase(LeanTweenType.easeOutQuad); } } /// /// Called when the pointer exits the button area. /// /// Pointer event data. public void OnPointerExit(PointerEventData eventData) { // Revert scale animation LeanTween.scale(buttonTransform.gameObject, originalScale, scaleAnimationDuration) .setEase(LeanTweenType.easeOutQuad); // Revert position shift LeanTween.moveLocal(buttonTransform.gameObject, originalPosition, scaleAnimationDuration) .setEase(LeanTweenType.easeOutQuad); // Revert fade effect if (applyFadeOnHover && canvasGroup != null) { LeanTween.alphaCanvas(canvasGroup, 1f, fadeAnimationDuration) .setEase(LeanTweenType.easeOutQuad); } } /// /// Called when the pointer is pressed on the button. /// /// Pointer event data. public void OnPointerDown(PointerEventData eventData) { LeanTween.scale(buttonTransform.gameObject, originalScale * pressScaleFactor, scaleAnimationDuration) .setEase(LeanTweenType.easeOutQuad); } /// /// Called when the pointer is released from the button. /// /// Pointer event data. public void OnPointerUp(PointerEventData eventData) { LeanTween.scale(buttonTransform.gameObject, originalScale, scaleAnimationDuration) .setEase(LeanTweenType.easeOutQuad); // Optionally apply a shake effect on click release if (applyShakeOnClick) { ApplyShakeEffect(); } } /// /// Applies a shake effect to the button. /// private void ApplyShakeEffect() { Vector3 currentPos = buttonTransform.localPosition; LeanTween.value(gameObject, 0f, 1f, shakeDuration) .setOnUpdate((float val) => { // Generate a random offset inside a circle Vector2 shakeOffset = Random.insideUnitCircle * shakeStrength; buttonTransform.localPosition = currentPos + new Vector3(shakeOffset.x, shakeOffset.y, 0f); }) .setOnComplete(() => { buttonTransform.localPosition = currentPos; }); } /// /// Ensures all LeanTween animations on the button are canceled when the object is destroyed. /// private void OnDestroy() { if (buttonTransform != null) { LeanTween.cancel(buttonTransform.gameObject); } } } }