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



}
相关推荐
RReality14 分钟前
【Unity Shader URP】全息扫描线(Hologram Scanline)源码+脚本控制
ui·unity·游戏引擎·图形渲染
渔民小镇2 小时前
一次编写到处对接 —— 为 Godot/Unity/React 生成统一交互接口
java·分布式·游戏·unity·godot
RReality15 小时前
【Unity Shader URP】序列帧动画(Sprite Sheet)实战教程
unity·游戏引擎
mxwin15 小时前
Unity URP 多线程渲染:理解 Shader 变体对加载时间的影响
unity·游戏引擎·shader
呆呆敲代码的小Y16 小时前
【Unity工具篇】| 游戏完整资源热更新流程,YooAsset官方示例项目
人工智能·游戏·unity·游戏引擎·热更新·yooasset·免费游戏
nainaire17 小时前
自学虚幻引擎记录1
游戏引擎·虚幻
想你依然心痛20 小时前
HarmonyOS 5.0游戏开发实战:构建高性能2D休闲游戏引擎与 monetization 系统
华为·游戏引擎·harmonyos
黄思搏2 天前
基于标注平台数据的 Unity UI 自动化构建工作流设计与工程实践
ui·unity·蓝湖·vectoui
羊羊20352 天前
开发手札:Unity6000与Android交互
android·unity·android-studio
Zarek枫煜3 天前
C3 编程语言 - 现代 C 的进化之选
c语言·开发语言·青少年编程·rust·游戏引擎