Unity按钮动态效果

Unity中Button的缩放、旋转、透明度、图片切换效果

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class ButtonEffect : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
{
    [Header("缩放效果")]
    public bool enableHoverScale = false;
    public bool enableClickScale = false;
    [SerializeField] private float hoverScale = 1.1f;
    [SerializeField] private float clickScale = 0.9f;
    [SerializeField] private float scaleDuration = 0.2f;

    [Header("旋转效果")]
    public bool enableHoverRotate = false;
    public bool enableClickRotate = false;
    [SerializeField] private float hoverRotation = 5f;
    [SerializeField] private float clickRotation = -5f;
    [SerializeField] private float rotateDuration = 0.2f;

    [Header("透明度效果")]
    public bool enableHoverAlpha = false;
    public bool enableClickAlpha = false;
    [SerializeField] private float hoverAlpha = 0.8f;
    [SerializeField] private float clickAlpha = 0.6f;
    [SerializeField] private float alphaDuration = 0.2f;

    [Header("图片切换")]
    public bool enableImageSwap = false;
    [SerializeField] private Sprite hoverSprite;
    [SerializeField] private Sprite clickSprite;



    private Vector3 originalScale;
    private Vector3 originalRotation;
    private Color originalColor;
    private Image buttonImage;
    private Sprite originalSprite;

    // 用于跟踪当前运行的协程
    private Coroutine currentRotateCoroutine;
    private Coroutine currentScaleCoroutine;
    private Coroutine currentAlphaCoroutine;




    void Start()
    {
        // 保存原始状态
        originalScale = transform.localScale;
        originalRotation = transform.localEulerAngles;

        buttonImage = GetComponent<Image>();
        if (buttonImage != null)
        {
            originalColor = buttonImage.color;
            originalSprite = buttonImage.sprite;
        }


    }



    public void OnPointerEnter(PointerEventData eventData)
    {


        if (enableHoverScale)
            StartScaleEffect(originalScale * hoverScale, scaleDuration);

        if (enableHoverRotate)
        {
            // 旋转到目标角度(只转一次)
            Vector3 targetRotation = originalRotation + new Vector3(0, 0, hoverRotation);
            StartRotateEffect(targetRotation, rotateDuration);
        }

        if (enableHoverAlpha && buttonImage != null)
            StartAlphaEffect(hoverAlpha, alphaDuration);

        if (enableImageSwap && buttonImage != null && hoverSprite != null)
            buttonImage.sprite = hoverSprite;


    }

    public void OnPointerExit(PointerEventData eventData)
    {

        ResetToOriginal();
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        if (enableClickScale)
            StartCoroutine(ClickScaleEffect());

        if (enableClickRotate)
            StartCoroutine(ClickRotateEffect());

        if (enableClickAlpha && buttonImage != null)
            StartCoroutine(ClickAlphaEffect());

        if (enableImageSwap && buttonImage != null && clickSprite != null)
            buttonImage.sprite = clickSprite;


    }
    #region 恢复
    private void ResetToOriginal()
    {
        // 停止所有动画
        StopAllCoroutines();


        // 立即重置到原始状态
        transform.localScale = originalScale;
        transform.localEulerAngles = originalRotation;

        if (buttonImage != null)
        {
            buttonImage.color = originalColor;
            if (enableImageSwap)
                buttonImage.sprite = originalSprite;
        }
    }
    #endregion

    #region 旋转方法
    // 新的旋转效果方法 - 只执行一次
    private void StartRotateEffect(Vector3 targetRotation, float duration)
    {
        // 停止之前的旋转协程
        if (currentRotateCoroutine != null)
            StopCoroutine(currentRotateCoroutine);

        currentRotateCoroutine = StartCoroutine(RotateTo(targetRotation, duration));
    }
    private IEnumerator ClickRotateEffect()
    {
        Vector3 targetRotation = originalRotation + new Vector3(0, 0, clickRotation);
        yield return StartCoroutine(RotateTo(targetRotation, rotateDuration * 0.5f));
        yield return StartCoroutine(RotateTo(originalRotation, rotateDuration * 0.5f));
    }
    private IEnumerator RotateTo(Vector3 targetRotation, float duration)
    {
        Vector3 startRotation = transform.localEulerAngles;
        float time = 0;

        while (time < duration)
        {
            transform.localEulerAngles = Vector3.Lerp(startRotation, targetRotation, time / duration);
            time += Time.deltaTime;
            yield return null;
        }
        transform.localEulerAngles = targetRotation;
    }
    #endregion

    #region 缩放方法
    // 新的缩放效果方法
    private void StartScaleEffect(Vector3 targetScale, float duration)
    {
        if (currentScaleCoroutine != null)
            StopCoroutine(currentScaleCoroutine);

        currentScaleCoroutine = StartCoroutine(ScaleTo(targetScale, duration));
    }
    private IEnumerator ClickScaleEffect()
    {
        yield return StartCoroutine(ScaleTo(originalScale * clickScale, scaleDuration * 0.5f));
        yield return StartCoroutine(ScaleTo(originalScale, scaleDuration * 0.5f));
    }

    private IEnumerator ScaleTo(Vector3 targetScale, float duration)
    {
        Vector3 startScale = transform.localScale;
        float time = 0;

        while (time < duration)
        {
            transform.localScale = Vector3.Lerp(startScale, targetScale, time / duration);
            time += Time.deltaTime;
            yield return null;
        }
        transform.localScale = targetScale;
    }

    #endregion

    #region 透明度方法
    // 新的透明度效果方法
    private void StartAlphaEffect(float targetAlpha, float duration)
    {
        if (currentAlphaCoroutine != null)
            StopCoroutine(currentAlphaCoroutine);

        currentAlphaCoroutine = StartCoroutine(FadeTo(targetAlpha, duration));
    }
    private IEnumerator ClickAlphaEffect()
    {
        if (buttonImage == null) yield break;

        yield return StartCoroutine(FadeTo(clickAlpha, alphaDuration * 0.5f));
        yield return StartCoroutine(FadeTo(originalColor.a, alphaDuration * 0.5f));
    }
    private IEnumerator FadeTo(float targetAlpha, float duration)
    {
        if (buttonImage == null) yield break;

        Color startColor = buttonImage.color;
        Color targetColor = new Color(startColor.r, startColor.g, startColor.b, targetAlpha);
        float time = 0;

        while (time < duration)
        {
            buttonImage.color = Color.Lerp(startColor, targetColor, time / duration);
            time += Time.deltaTime;
            yield return null;
        }
        buttonImage.color = targetColor;
    }
    #endregion



}
相关推荐
_Cherry|5 小时前
Unity读取文件夹内容
unity·c#
lrh30256 小时前
Custom SRP - 15 Particles
unity·渲染管线·粒子·srp·扰动效果
璞瑜无文7 小时前
Unity 游戏开发之布局(二)
unity·c#·游戏引擎
高远-临客10 小时前
unity IL2CPP模式下中使用UMP插件打包后无法播放视频监控报错问题解决方案
android·unity·音视频
_Cherry|10 小时前
Unity中窗口调整
unity·c#·游戏引擎
qq_4286396112 小时前
虚幻基础:特效
游戏引擎·虚幻
qq_4286396113 小时前
虚幻基础:将角色的模型替换为自己的模型
游戏引擎·虚幻
_Cherry|15 小时前
Unity在屏幕上滑动
unity·游戏引擎
_Cherry|15 小时前
Unity中使用AVPRO播放视频
unity·c#·音视频