SanAndreasUnity/Assets/Scripts/Utilities/UI/OnScreenMessageManager.cs

109 lines
2.7 KiB
C#
Raw Normal View History

2020-05-18 22:57:16 +00:00
using UnityEngine;
using System.Collections.Generic;
2020-06-06 18:03:26 +00:00
using UnityEngine.UI;
2020-05-18 22:57:16 +00:00
namespace SanAndreasUnity.Utilities
{
public class OnScreenMessageManager : MonoBehaviour
{
2020-06-06 16:09:26 +00:00
public GameObject messagePrefab;
public RectTransform messagesContainer;
2020-06-06 17:02:43 +00:00
private readonly List<OnScreenMessage> m_onScreenMessages = new List<OnScreenMessage>();
2020-05-18 22:57:16 +00:00
public IReadOnlyList<OnScreenMessage> Messages => m_onScreenMessages;
2020-06-06 16:09:26 +00:00
public int messagePoolSize = 10;
2020-05-18 22:57:16 +00:00
2020-06-06 18:03:26 +00:00
private readonly Queue<OnScreenMessage> m_pooledOnScreenMessages = new Queue<OnScreenMessage>();
public int NumPooledMessages => m_pooledOnScreenMessages.Count;
2020-05-18 22:57:16 +00:00
public static OnScreenMessageManager Instance { get; private set; }
void Awake()
{
Instance = this;
}
void Update()
{
2020-06-06 18:03:26 +00:00
bool hasMessagesToRemove = false;
2020-06-06 16:09:26 +00:00
2020-06-06 17:02:43 +00:00
for (int i = 0; i < m_onScreenMessages.Count; i++)
2020-05-18 22:57:16 +00:00
{
2020-06-06 17:02:43 +00:00
var msg = m_onScreenMessages[i];
2020-06-06 18:03:26 +00:00
if (null == msg || !msg.gameObject.activeSelf)
2020-06-06 17:02:43 +00:00
{
2020-06-06 18:03:26 +00:00
hasMessagesToRemove = true;
2020-06-06 17:02:43 +00:00
continue;
}
if (msg.velocity != Vector2.zero)
msg.ScreenPos += msg.velocity * Time.deltaTime;
2020-05-18 22:57:16 +00:00
msg.timeLeft -= Time.deltaTime;
2020-06-06 16:09:26 +00:00
if (msg.timeLeft <= 0)
{
2020-06-06 18:03:26 +00:00
// try to pool this message
if (m_pooledOnScreenMessages.Count >= this.messagePoolSize)
{
// can't pool => destroy it
Object.Destroy(msg.gameObject);
}
else
{
hasMessagesToRemove = true;
msg.gameObject.SetActive(false);
m_pooledOnScreenMessages.Enqueue(msg);
}
2020-06-06 16:09:26 +00:00
}
2020-05-18 22:57:16 +00:00
}
2020-06-06 18:03:26 +00:00
if (hasMessagesToRemove)
2020-06-06 17:02:43 +00:00
{
// only remove dead objects if there are any, because this method allocates memory
2020-06-06 18:03:26 +00:00
m_onScreenMessages.RemoveAll(msg => null == msg || !msg.gameObject.activeSelf);
2020-06-06 17:02:43 +00:00
}
2020-05-18 22:57:16 +00:00
}
2020-06-06 16:09:26 +00:00
public OnScreenMessage CreateMessage()
2020-05-18 22:57:16 +00:00
{
2020-06-06 18:03:26 +00:00
var originalMessage = messagePrefab.GetComponentOrThrow<OnScreenMessage>();
if (m_pooledOnScreenMessages.Count > 0)
{
var originalTextComponent = originalMessage.GetComponentInChildren<Text>();
OnScreenMessage pooledMessage = m_pooledOnScreenMessages.Dequeue();
pooledMessage.gameObject.SetActive(true);
// reset parameters
pooledMessage.ScreenPos = originalMessage.ScreenPos;
pooledMessage.SizeOnScreen = originalMessage.SizeOnScreen;
pooledMessage.Text = originalTextComponent.text;
pooledMessage.TextColor = originalTextComponent.color;
pooledMessage.velocity = originalMessage.velocity;
pooledMessage.timeLeft = originalMessage.timeLeft;
m_onScreenMessages.Add(pooledMessage);
return pooledMessage;
}
2020-05-18 22:57:16 +00:00
2020-06-06 16:09:26 +00:00
GameObject messageGo = Object.Instantiate(messagePrefab);
messageGo.transform.SetParent(messagesContainer, false);
2020-05-18 22:57:16 +00:00
2020-06-06 16:09:26 +00:00
OnScreenMessage message = messageGo.GetComponent<OnScreenMessage>();
2020-05-18 22:57:16 +00:00
2020-06-06 16:09:26 +00:00
m_onScreenMessages.Add(message);
2020-05-18 22:57:16 +00:00
2020-06-06 16:09:26 +00:00
return message;
2020-05-18 22:57:16 +00:00
}
}
}