此弹窗效果为弹出消息,自动消失,用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;
}
}

第二种,弹出多个,然后逐一消失(可自行用对象池优化)
using System.Collections;
using System.Collections.Concurrent;
using DG.Tweening;
using TMPro;
using UnityEngine;
public class PopModel
{
public string content;
public float time;
}
public class PopUpManager : MonoBehaviour
{
[SerializeField] private Transform tips;
[SerializeField] private GameObject tip;
[SerializeField,Header("弹出过程所需时间")] private float upTime = 0.1f;
[SerializeField,Header("隐藏过程所需时间")] private float hideTime = 0.1f;
#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 Coroutine _popCoroutine;
private readonly ConcurrentQueue<PopModel> _popQueue = new();
private void Awake()
{
_instance = this;
DontDestroyOnLoad(this);
}
private void Start()
{
tip.gameObject.SetActive(false);
}
public void ShowTip(string content,float time = 0.5f)
{
var popModel = new PopModel()
{
content = content,
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.TryDequeue(out var finishPopModel);
PopingTips(finishPopModel);
yield return null;
}
_popCoroutine = null;
}
private void PopingTips(PopModel model)
{
GameObject go = Instantiate(tip, tips);
go.gameObject.SetActive(true);
go.transform.GetChild(0).GetComponent<TextMeshProUGUI>().text = model.content;
CanvasGroup cg = go.GetComponent<CanvasGroup>();
Show(model,cg,go.transform);
}
private void Show(PopModel model,CanvasGroup tipCG,Transform tipTrans)
{
tipCG.DOFade(1, upTime)
.OnUpdate(() => { tipTrans.localScale = Vector3.Lerp(Vector3.zero, Vector3.one, tipCG.alpha); })
.OnComplete(() => { Delay(model, tipCG, tipTrans); });
}
private void Delay(PopModel model,CanvasGroup tipCG,Transform tipTrans)
{
DOVirtual.DelayedCall(model.time, () =>
{
tipCG.DOFade(0, hideTime)
.OnUpdate(() => {tipTrans.localScale = Vector3.Lerp(Vector3.one, Vector3.zero, 1 - tipCG.alpha);})
.OnComplete(() => { Hidden(tipTrans); });
});
}
private void Hidden(Transform tipTrans)
{
Destroy(tipTrans.gameObject);
}
}



