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



}
相关推荐
HonestGoat10 小时前
Unity3d之碰撞体设置
unity
那个村的李富贵18 小时前
Unity自适应文本提示框:从原理到实战
unity·游戏引擎
HonestGoat18 小时前
Unity3d之鼠标光标
unity
WarPigs18 小时前
Unity人物翻越功能
unity·游戏引擎
游乐码19 小时前
Unity基础(四)向量相关
游戏·unity·游戏引擎
VT LI20 小时前
Cocos2d-x 引擎架构全面深度解析:从底层渲染到上层交互的系统性技术全景
游戏引擎·cocos·引擎架构
Kurisu57521 小时前
探灵直播2026最新官方正版免费下载 一键转存 永久更新 (看到速转存 资源随时走丢)
游戏·游戏引擎·游戏程序·动画·关卡设计
神码编程1 天前
【Unity】MiniGame编辑器小游戏(十五)中国象棋局域网对战【Chinese Chess】(上)
unity·编辑器·游戏引擎·小游戏
伽蓝_游戏1 天前
第四章:AssetBundle 核心机制与文件结构
unity·c#·游戏引擎·游戏程序
郝学胜-神的一滴1 天前
中级OpenGL教程 006:高光反射原理与 Shader 实现
c++·unity·godot·图形渲染·three.js·opengl·unreal