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



}
相关推荐
2301_7671139811 小时前
Superpowers 游戏引擎从零开发实战指南
游戏引擎
吴梓穆13 小时前
untiy TextMeshPro (TMP) text 操作 中文字符集 字体材质操作(添加纹理 添加描边 添加阴影)
unity
想你依然心痛15 小时前
嵌入式单元测试:Unity/CMock框架与硬件在环测试——测试驱动、桩函数
unity·单元测试·游戏引擎
yangmu320316 小时前
《星露谷物语》MOD配置与实战安装综合指南
游戏·游戏引擎·游戏程序
xcLeigh16 小时前
Unity基础:Game视图详解——游戏预览、分辨率模拟与性能显示
游戏·unity·游戏引擎·音频·视频·game·play模式
ZJU_fish199617 小时前
全局光照/阴影的几个常见问题
游戏引擎·图形渲染
IT·陈寒18 小时前
Superpowers 游戏引擎核心应用场景与落地指南
游戏引擎
xcLeigh1 天前
Unity基础:Scene视图操作完全指南——视角控制、物体选择与场景导航
unity·游戏引擎·scene·试图·场景导航
mxwin1 天前
Unity Shader exp 函数的算法与渲染应用
算法·unity·游戏引擎·shader
mxwin1 天前
Unity URP Exposure曝光原理与实战应用
unity·游戏引擎