项目中有些信息需要以Toast的形式体现出来,不需要交互,弹出后一段时间后消失,多个Toast会向上重叠,下面是一个UGUI Toast的实现,动画部份用到了Dotween来实现
首先需要制作Toast预制体,预制体初始化后就进行淡出动画,初始化的过程中根据str长度改变父节点图片大小
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using DG.Tweening; public class ToastHandler : MonoBehaviour { public Image image; public Text text; //初始化 public void InitToast(string str,System.Action callback) { text.text = str; int StrLenth = str.Length; int ToastWidth = 1; int ToastHeight = 1; if (StrLenth > 10) { ToastHeight = (StrLenth / 10)+1; ToastWidth = 10; } else { ToastWidth = StrLenth; } image.rectTransform.sizeDelta = new Vector2(50* ToastWidth + 100, 50* ToastHeight + 100); FadeOut(callback); } public void FadeOut(System.Action callback) { image.DOFade(0,2).OnComplete(()=> { callback.Invoke(); Destroy(gameObject); }); text.DOFade(0,2); } //堆叠向上移动 public void Move(float speed, int targetPos) { transform.DOLocalMoveY(targetPos * image.rectTransform.sizeDelta.y, speed); } }
然后需要一个Manager来创建和管理这些Toast预制体,使用单例模式方便其他地方调用,初始化预制体的时候要传一个回调,预制体淡出销毁前要从Manager的列表里面Remove掉
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ToastManager : MonoBehaviour { private static ToastManager Instance; public static ToastManager GetInstance() { return Instance; } private void Awake() { Instance = this; } public GameObject ToastPrefab; public List<ToastHandler> ToastList = new List<ToastHandler>(); private float Timer=0; public float Interval; public Transform Parent; //通过这里来创建Toast预制体 public void CreatToast(string str) { var Toa = Instantiate(ToastPrefab, Parent.transform.position, Parent.transform.rotation, Parent.transform); var comp = Toa.GetComponent<ToastHandler>(); ToastList.Insert(0, comp); comp.InitToast(str,()=> { ToastList.Remove(comp); }); Timer = 0; //有新的Toast出现,之前的Toast向上移动 ToastMove(0.2f); } public void ToastMove(float speed) { for (int i = 0; i < ToastList.Count; i++) { ToastList[i].Move(speed,i+1); } } }
效果如下: