工程截图
using System; using System.Collections; using UnityEngine; using UnityEngine.Events; using UnityEngine.Serialization; using TMPro; /// <summary> /// 倒计时-数字缩放效果 /// </summary> public class CountdownEffect : MonoBehaviour { [SerializeField] private TextMeshProUGUI _textMeshPro; public int second = 5; public float minScale = 3f; public float maxScale = 10f; public float speed = 10f; private bool _active = false; private float _frameTime; private int _cd = 0; private bool _zooming = false; [Serializable] public class OnCompletedEvent : UnityEvent { } [FormerlySerializedAs("OnCompleted")] [SerializeField] private OnCompletedEvent m_OnCompleted = new OnCompletedEvent(); private void Start() { _frameTime = Application.targetFrameRate > 0 ? 1.0f / Application.targetFrameRate : 1.0f / 60.0f; } void Update() { if (!_active) return; if (_zooming) return; if (_cd <= 0) return; StartCoroutine(ZoomIn()); } IEnumerator ZoomIn() { _zooming = true; yield return null; var rt = _textMeshPro.rectTransform; float scale = minScale; float scaleTime = 0; while (true) { scale += _frameTime * speed; scale = Mathf.Clamp(scale, minScale, maxScale); rt.localScale = new Vector3(scale, scale, scale); _textMeshPro.text = _cd.ToString(); Color color = _textMeshPro.color; color.a = Mathf.Lerp(0, 1, scale/maxScale); _textMeshPro.color = color; scaleTime += _frameTime; yield return new WaitForSeconds(_frameTime); if (Mathf.Approximately(scale, maxScale)) break; } float remain = 1.0f - scaleTime; if (remain > 0f) yield return new WaitForSeconds(remain); _cd--; if (_cd <= 0) m_OnCompleted?.Invoke(); _zooming = false; } public void Play() { StopAllCoroutines(); _cd = second; _active = true; _zooming = false; } public void ShowText() { _textMeshPro.gameObject.SetActive(true); } public void HideText() { _textMeshPro.gameObject.SetActive(false); } }
运行效果