203 lines
3.8 KiB
C#
203 lines
3.8 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using DG.Tweening;
|
|
using System.Collections;
|
|
|
|
namespace TPSBR.UI
|
|
{
|
|
public interface IFeedData
|
|
{
|
|
}
|
|
|
|
public struct KillFeedData : IFeedData
|
|
{
|
|
public string Killer;
|
|
public string Victim;
|
|
public bool IsHeadshot;
|
|
public EHitType DamageType;
|
|
public bool KillerIsLocal;
|
|
public bool VictimIsLocal;
|
|
}
|
|
|
|
public struct JoinedLeftFeedData : IFeedData
|
|
{
|
|
public string Nickname;
|
|
public bool Joined;
|
|
}
|
|
|
|
public struct EliminationFeedData : IFeedData
|
|
{
|
|
public string Nickname;
|
|
public bool IsLocal;
|
|
}
|
|
|
|
public struct AnnouncementFeedData : IFeedData
|
|
{
|
|
public string Announcement;
|
|
public Color Color;
|
|
}
|
|
|
|
public class UIKillFeed : UIWidget
|
|
{
|
|
// PRIVATE MEMBERS
|
|
|
|
[SerializeField]
|
|
private float _minVisibilityTime;
|
|
[SerializeField]
|
|
private float _maxVisibilityTime;
|
|
[SerializeField]
|
|
private float _moveTime = 0.3f;
|
|
|
|
private UIKillFeedItem[] _items;
|
|
private Vector3[] _originalPositions;
|
|
private int _maxFeeds;
|
|
private Coroutine _moveRoutine;
|
|
|
|
private List<UIKillFeedItem> _itemsPool = new List<UIKillFeedItem>(16);
|
|
private List<UIKillFeedItem> _visibleFeeds = new List<UIKillFeedItem>(16);
|
|
private List<IFeedData> _pendingFeeds = new List<IFeedData>(16);
|
|
|
|
// PUBLIC METHODS
|
|
|
|
public void ShowFeed(IFeedData data)
|
|
{
|
|
_pendingFeeds.Add(data);
|
|
}
|
|
|
|
public void HideAll()
|
|
{
|
|
for (int i = 0; i < _maxFeeds; i++)
|
|
{
|
|
_items[i].SetActive(false);
|
|
}
|
|
|
|
_visibleFeeds.Clear();
|
|
_pendingFeeds.Clear();
|
|
|
|
_itemsPool.AddRange(_items);
|
|
|
|
_moveRoutine = null;
|
|
}
|
|
|
|
// UIWidget
|
|
|
|
protected override void OnInitialize()
|
|
{
|
|
base.OnInitialize();
|
|
|
|
_items = GetComponentsInChildren<UIKillFeedItem>();
|
|
_maxFeeds = _items.Length;
|
|
|
|
_itemsPool = new List<UIKillFeedItem>(_items);
|
|
|
|
_originalPositions = new Vector3[_maxFeeds];
|
|
|
|
for (int i = 0; i < _maxFeeds; i++)
|
|
{
|
|
var position = _items[i].transform.position;
|
|
|
|
position.x /= Screen.width;
|
|
position.y /= Screen.height;
|
|
|
|
_originalPositions[i] = position;
|
|
}
|
|
}
|
|
|
|
protected override void OnVisible()
|
|
{
|
|
base.OnVisible();
|
|
|
|
HideAll();
|
|
}
|
|
protected override void OnTick()
|
|
{
|
|
base.OnTick();
|
|
|
|
if (_moveRoutine != null)
|
|
return; // Do not add or remove feeds when moving
|
|
|
|
int visibleFeeds = _visibleFeeds.Count;
|
|
|
|
if (_pendingFeeds.Count > 0)
|
|
{
|
|
if (visibleFeeds == _maxFeeds)
|
|
{
|
|
if (_visibleFeeds[0].VisibilityTime < _minVisibilityTime)
|
|
return;
|
|
|
|
HideFeedItem(0);
|
|
return;
|
|
}
|
|
|
|
ShowFeedItem(_pendingFeeds[0]);
|
|
_pendingFeeds.RemoveAt(0);
|
|
return;
|
|
}
|
|
|
|
if (visibleFeeds > 0)
|
|
{
|
|
if (_visibleFeeds[0].VisibilityTime >= _maxVisibilityTime)
|
|
{
|
|
HideFeedItem(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
// PRIVATE METHODS
|
|
|
|
private void ShowFeedItem(IFeedData data)
|
|
{
|
|
int poolIndex = _itemsPool.Count - 1;
|
|
|
|
var item = _itemsPool[poolIndex];
|
|
_itemsPool.RemoveAt(poolIndex);
|
|
|
|
_visibleFeeds.Add(item);
|
|
|
|
item.SetData(data);
|
|
item.RectTransform.position = GetPosition(_visibleFeeds.Count - 1);
|
|
item.SetActive(true);
|
|
}
|
|
|
|
private void HideFeedItem(int index)
|
|
{
|
|
var feedItem = _visibleFeeds[index];
|
|
|
|
feedItem.SetActive(false);
|
|
_visibleFeeds.RemoveAt(index);
|
|
|
|
_itemsPool.Add(feedItem);
|
|
|
|
if (_visibleFeeds.Count > 0)
|
|
{
|
|
_moveRoutine = StartCoroutine(MoveFeeds_Coroutine());
|
|
}
|
|
}
|
|
|
|
private IEnumerator MoveFeeds_Coroutine()
|
|
{
|
|
for (int i = 0; i < _visibleFeeds.Count; i++)
|
|
{
|
|
var feedItem = _visibleFeeds[i];
|
|
|
|
DOTween.Kill(feedItem);
|
|
_visibleFeeds[i].RectTransform.DOMove(GetPosition(i), _moveTime);
|
|
}
|
|
|
|
yield return new WaitForSeconds(_moveTime);
|
|
|
|
_moveRoutine = null;
|
|
}
|
|
|
|
private Vector3 GetPosition(int index)
|
|
{
|
|
var position = _originalPositions[index];
|
|
|
|
position.x *= Screen.width;
|
|
position.y *= Screen.height;
|
|
|
|
return position;
|
|
}
|
|
}
|
|
}
|