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
}