전제 조건: DOTween 플러그인이 포함되어 있어야 합니다.물론 이징 애니메이션용 플러그인을 사용하지 않는 경우 애니메이션 애니메이션을 사용하여 해당 이징 효과를 사용자 정의할 수도 있습니다. 효과: 사실 이것은 매우 간단합니다.
두 개의
대기열(그 중 하나는 여전히 목록을 사용하고 있음)을 사용하여 하나는 메시지 표시 대기열이고 다른 하나는 메시지 캐시 개체 풀(숨겨짐)입니다. 나는 사용자 정의 메시지 애니메이션 레이어(캔버스)인
Resources.Load에 의해 로드된 prefab _layer를 사용합니다.
코드는 비교적 간단하므로 자세히 설명하지 않겠습니다.
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using view;
public class MessageMgr : MonoSingleton<MessageMgr>
{
//消息本体
private Text itemText;
/// <summary>
/// 消息列表
/// </summary>
private List<MessageItem> ItemList;
/// <summary>
/// 回收列表
/// </summary>
private Queue<MessageItem> QueText;
private GameObject _layer;
private Vector2 StartPos;
//文本高度
public float texHeight;
public float MessLine;
private int maxMsg;
private void Awake()
{
itemText = Resources.Load<Text>(UrlUntil.Instance.getUIPath() + "MessItem");
ItemList = new List<MessageItem>();
QueText = new Queue<MessageItem>();
//5添加到消息层
_layer = UIMgr.Instance.getGameObjectType(UIType.MESSAGE);
//StartPos = new Vector2(App.Instance.ScreenW / 2, App.Instance.ScreenH / 2);
StartPos = new Vector2(0, 0);
texHeight = 30;
//消息间隔
MessLine = 15;
//最多显示消息
maxMsg = 10;
}
private MessageItem GetItem()
{
MessageItem item = null;
//如果队列中有就返回出去
if (QueText.Count > 0)
{
item = QueText.Dequeue();
}
//没有就复制一个
else
{
//超过限制就取最上面的一个
if (ItemList.Count >= maxMsg)
{
item = ItemList[0];
ItemList.RemoveAt(0);
}
else
{
item = new MessageItem(Instantiate(itemText));
}
}
item.transform.gameObject.SetActive(true);
ItemList.Add(item);
return item;
}
/// <summary>
/// 显示相对应的消息
/// </summary>
/// <param name="message"></param>
/// <param name="color"></param>
public void showMessage(string message,Color color=default(Color))
{
MessageItem item = GetItem();
if (item == null) return;
if (item.transform.parent == null)
{
item.transform.SetParent(_layer.transform,false);
}
//Debug.Log(item.transform.localPosition + "---" + StartPos);
item.transform.localPosition = StartPos;
item.show(message, QueText, ItemList, color);
updataMsgY();
}
/// <summary>
/// 坐标移动
/// </summary>
private void updataMsgY()
{
for (int i = 0; i < ItemList.Count; i++)
{
float pos = StartPos.y + texHeight * (ItemList.Count - i) + MessLine;
ItemList[i].UpDataY(pos, i);
}
}
}
항목 메시지 클래스:
이징 애니메이션을 재생하기 전에 애니메이션을 종료하고 애니메이션 대기열을 지워야 합니다.
내부의 일부 매개변수는 필요에 따라 멤버 변수로 승격될 수 있습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
public class MessageItem
{
public string msgKey;
Text text;
public Sequence twQue;
public MessageItem(Text tex)
{
text = tex;
}
public Transform transform
{
get { return text.transform; }
}
/// <summary>
/// 更新Y坐标
/// </summary>
/// <param name="movY"></param>
public void UpDataY(float movY,int id)
{
//移动前必须杀死动画
text.transform.DOKill();
text.transform.DOLocalMoveY(movY, 0.5f);
}
/// <summary>
/// 3秒隐身
/// </summary>
public void show(string msg, Queue<MessageItem> que, List<MessageItem> list,Color color)
{
setMsg(msg, color);
text.color = new Color(text.color.r, text.color.g, text.color.b, 1);
Color tagcol = text.color * new Color(1, 1, 1, 0);
//动画队列
//DOTween.Kill(twQue);
twQue.Kill();
twQue = DOTween.Sequence();
//twQue.SetId(list.IndexOf(this));
//间隔3秒隐身
twQue.AppendInterval(3);
twQue.Append(text.DOColor(tagcol, 0.5f));
//隐身后添加到队列
twQue.AppendCallback(() =>
{
Debug.Log("DOTween动画播放完");
text.gameObject.SetActive(false);
if (!que.Contains(this))
{
que.Enqueue(this);
list.Remove(this);
}
});
}
/// <summary>
/// 设置文本信息
/// </summary>
/// <param name="msg"></param>
private void setMsg(string msg,Color color)
{
this.text.text = msg;
this.text.color = color;
}
}