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



}
相关推荐
警醒与鞭策5 小时前
Direct3D 12 中的内存管理
3d·游戏引擎·direct3d
淡海水9 小时前
16-02-C#常用数据结构源码-附录B-源码索引速查
unity·c#·游戏引擎·il2cpp
速易达网络10 小时前
无人机远程操控仿真
游戏引擎·cocos2d
郝学胜-神的一滴11 小时前
游戏引擎原理与实践 02:揭开3A游戏背后的技术面纱
开发语言·计算机网络·程序人生·游戏·游戏引擎
警醒与鞭策19 小时前
【无标题】
android·unity·性能优化·游戏引擎·perforce
zhchyun200821 小时前
【Unity UI 进阶】仿 Element UI 打造企业级 Unity UI 组件库(10)
ui·unity·游戏引擎
地狱为王1 天前
Unity使用NVIDIA的Audio2Face驱动口型
unity·游戏引擎
ebiobiz1 天前
STM32F4 Unity 单元测试与多次测试失败率统计详细步骤
stm32·unity·单元测试
一线灵1 天前
跨平台游戏引擎 Axmol-2.11.5 发布
游戏引擎·lua
淡海水1 天前
16-01-C#数据结构源码-附录A-术语表
unity·c#·游戏引擎·il2cpp