using System.Collections.Generic; using CSNetwork; using UnityEngine; using UnityEngine.Pool; using UnityEngine.UI; namespace BrewMonster.Scripts.ChatUI { public class ChatPanelUI : MonoBehaviour { [Header("UI")] public ScrollRect scrollRect; public RectTransform content; public ChatMessageView messagePrefab; //public GameObject newMessageIndicator; [Header("Config")] public int maxVisibleMessages = 30; public int maxStoredMessages = 2000; private List _messages = new(); private List _visibleViews = new(); private ObjectPool _pool; private bool _userAtBottom = true; void Awake() { EventBus.Subscribe( (x) => AddMessage(x.context)); _pool = new ObjectPool( CreateItem, OnGetItem, OnReleaseItem, OnDestroyItem, false, 10, 100 ); scrollRect.onValueChanged.AddListener(OnScrollChanged); } ChatMessageView CreateItem() { var item = Instantiate(messagePrefab); item.transform.SetParent(content, false); return item; } void OnGetItem(ChatMessageView item) { item.gameObject.SetActive(true); } void OnReleaseItem(ChatMessageView item) { item.gameObject.SetActive(false); } void OnDestroyItem(ChatMessageView item) { Destroy(item.gameObject); } void OnScrollChanged(Vector2 pos) { _userAtBottom = scrollRect.verticalNormalizedPosition <= 0.001f; if (_userAtBottom) { //newMessageIndicator.SetActive(false); } } bool IsAtBottom() { return scrollRect.verticalNormalizedPosition <= 0.001f; } public void AddMessage(string msg) { _messages.Add(msg); if (_messages.Count > maxStoredMessages) _messages.RemoveAt(0); RefreshVisible(); if (_userAtBottom) { ScrollToBottom(); } else { //newMessageIndicator.SetActive(true); } } void RefreshVisible() { foreach (var view in _visibleViews) _pool.Release(view); _visibleViews.Clear(); int start = Mathf.Max(0, _messages.Count - maxVisibleMessages); for (int i = start; i < _messages.Count; i++) { var view = _pool.Get(); view.transform.SetParent(content, false); view.Bind(_messages[i]); _visibleViews.Add(view); } Canvas.ForceUpdateCanvases(); } public void ScrollToBottom() { Canvas.ForceUpdateCanvases(); scrollRect.verticalNormalizedPosition = 0f; //newMessageIndicator.SetActive(false); } public void ClearChat() { foreach (var view in _visibleViews) _pool.Release(view); _visibleViews.Clear(); _messages.Clear(); } } }