此弹窗效果为弹出消息,自动消失,用DOTween实现
using System.Collections;
using System.Collections.Concurrent;
using DG.Tweening;
using TMPro;
using UnityEngine;
public class PopModel
{
public bool isPop;
public string tips;
public float time;
}
public class PopUpManager : MonoBehaviour
{
[SerializeField] private TMP_Text content;
[SerializeField] private Transform tip;
[SerializeField,Header("弹出过程所需时间")] private float upTime = 0.8f;
[SerializeField,Header("隐藏过程所需时间")] private float hideTime = 0.5f;
#region singleton
private static PopUpManager _instance;
public static PopUpManager Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType<PopUpManager>();
}
if (_instance == null)
{
var popManager = new GameObject("PopManager");
_instance = popManager.AddComponent<PopUpManager>();
DontDestroyOnLoad(popManager);
}
return _instance;
}
}
#endregion
private CanvasGroup tipCG;
private Coroutine _popCoroutine;
private readonly ConcurrentQueue<PopModel> _popQueue = new();
private bool _isPoping;
private void Awake()
{
_instance = this;
DontDestroyOnLoad(this);
}
private void Start()
{
tip.localScale = Vector3.zero;
tipCG = tip.GetComponent<CanvasGroup>();
tipCG.alpha = 0;
tip.gameObject.SetActive(false);
}
public void ShowTip(string tips,float time = 1f)
{
var popModel = new PopModel()
{
isPop = false,
tips = tips,
time = time,
};
AddTips(popModel);
}
private void AddTips(PopModel model)
{
_popQueue.Enqueue(model);
PopTips();
}
private void PopTips()
{
_popCoroutine ??= StartCoroutine(PopQueue());
}
IEnumerator PopQueue()
{
while (_popQueue.Count > 0)
{
_popQueue.TryPeek(out var popModel);
if (popModel.isPop)
{
_popQueue.TryDequeue(out var finishPopModel);
}
else
{
PopingTips(popModel);
}
yield return null;
}
_popCoroutine = null;
}
private void PopingTips(PopModel model)
{
if (!_isPoping)
{
_isPoping = true;
content.text = model.tips;
tip.gameObject.SetActive(true);
Show(model);
}
}
private void Show(PopModel model)
{
tipCG.DOFade(1, upTime)
.OnUpdate(() => { tip.localScale = Vector3.Lerp(Vector3.zero, Vector3.one, tipCG.alpha); })
.OnComplete(() => { Delay(model); });
}
private void Delay(PopModel model)
{
DOVirtual.DelayedCall(model.time, () =>
{
tipCG.DOFade(0, hideTime)
.OnUpdate(() => {tip.localScale = Vector3.Lerp(Vector3.one, Vector3.zero, 1 - tipCG.alpha);})
.OnComplete(() => { Hidden(model); });
});
}
private void Hidden(PopModel model)
{
tip.gameObject.SetActive(false);
_isPoping = false;
model.isPop = true;
}
}