using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using TMPro; using TheIsland.Network; using TheIsland.Models; namespace TheIsland.UI { /// /// 事件日志面板 - 显示游戏事件历史 /// public class EventLog : MonoBehaviour { private static EventLog _instance; public static EventLog Instance => _instance; // 自动创建 EventLog 实例 [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] private static void AutoCreate() { if (_instance == null) { var go = new GameObject("EventLog"); go.AddComponent(); DontDestroyOnLoad(go); Debug.Log("[EventLog] 自动创建实例"); } } // UI 组件 private Canvas _canvas; private GameObject _panel; private ScrollRect _scrollRect; private RectTransform _content; private Button _toggleBtn; private TextMeshProUGUI _toggleText; private List _entries = new List(); private bool _visible = true; private int _unread = 0; private bool _ready = false; private void Awake() { if (_instance != null && _instance != this) { Destroy(gameObject); return; } _instance = this; } private void Start() { Debug.Log("[EventLog] Start - 开始初始化"); StartCoroutine(InitCoroutine()); } private System.Collections.IEnumerator InitCoroutine() { // 等待一帧确保 Canvas 准备好 yield return null; _canvas = FindAnyObjectByType(); if (_canvas == null) { Debug.LogError("[EventLog] 找不到 Canvas"); yield break; } Debug.Log($"[EventLog] 找到 Canvas: {_canvas.name}"); BuildUI(); // 等待 NetworkManager int retries = 0; while (NetworkManager.Instance == null && retries < 20) { Debug.Log("[EventLog] 等待 NetworkManager..."); yield return new WaitForSeconds(0.25f); retries++; } if (NetworkManager.Instance != null) { SubscribeEvents(); _ready = true; AddLog("事件日志已就绪", Color.yellow); Debug.Log("[EventLog] 初始化完成"); } else { Debug.LogError("[EventLog] NetworkManager 超时"); } } private void OnDestroy() { if (NetworkManager.Instance != null) { var n = NetworkManager.Instance; n.OnConnected -= OnConnected; n.OnAgentSpeak -= OnSpeak; n.OnSocialInteraction -= OnSocial; n.OnAgentDied -= OnDeath; n.OnFeed -= OnFeed; n.OnHeal -= OnHeal; n.OnEncourage -= OnEncourage; n.OnRevive -= OnRevive; n.OnTalk -= OnTalk; n.OnSystemMessage -= OnSystem; n.OnWeatherChange -= OnWeather; n.OnPhaseChange -= OnPhase; n.OnDayChange -= OnDay; } } private void SubscribeEvents() { var n = NetworkManager.Instance; n.OnConnected += OnConnected; n.OnAgentSpeak += OnSpeak; n.OnSocialInteraction += OnSocial; n.OnAgentDied += OnDeath; n.OnFeed += OnFeed; n.OnHeal += OnHeal; n.OnEncourage += OnEncourage; n.OnRevive += OnRevive; n.OnTalk += OnTalk; n.OnSystemMessage += OnSystem; n.OnWeatherChange += OnWeather; n.OnPhaseChange += OnPhase; n.OnDayChange += OnDay; Debug.Log("[EventLog] 事件订阅完成"); } // 事件处理 private void OnConnected() => AddLog("已连接服务器", Color.green); private void OnSpeak(AgentSpeakData d) => AddLog($"{d.agent_name}: \"{d.text}\"", Color.white); private void OnSocial(SocialInteractionData d) => AddLog($"{d.initiator_name} -> {d.target_name}: {d.dialogue}", new Color(0.6f, 0.9f, 1f)); private void OnDeath(AgentDiedData d) => AddLog($"{d.agent_name} 死亡!", Color.red); private void OnFeed(FeedEventData d) => AddLog($"{d.user} 喂食 {d.agent_name}", new Color(0.5f, 1f, 0.5f)); private void OnHeal(HealEventData d) => AddLog($"{d.user} 治疗 {d.agent_name}", new Color(0.5f, 1f, 0.5f)); private void OnEncourage(EncourageEventData d) => AddLog($"{d.user} 鼓励 {d.agent_name}", new Color(0.5f, 1f, 0.5f)); private void OnRevive(ReviveEventData d) => AddLog($"{d.user} 复活 {d.agent_name}", Color.cyan); private void OnTalk(TalkEventData d) => AddLog($"{d.agent_name}: \"{d.response}\"", Color.white); private void OnSystem(SystemEventData d) => AddLog(d.message, Color.yellow); private void OnWeather(WeatherChangeData d) => AddLog($"天气: {d.new_weather}", new Color(0.7f, 0.85f, 1f)); private void OnPhase(PhaseChangeData d) => AddLog($"时间: {d.new_phase}", new Color(1f, 0.9f, 0.7f)); private void OnDay(DayChangeData d) => AddLog($"第 {d.day} 天!", new Color(1f, 0.9f, 0.7f)); private void BuildUI() { // 切换按钮 var toggleObj = new GameObject("LogToggle"); toggleObj.transform.SetParent(_canvas.transform, false); var toggleRect = toggleObj.AddComponent(); toggleRect.anchorMin = new Vector2(0, 1); toggleRect.anchorMax = new Vector2(0, 1); toggleRect.pivot = new Vector2(0, 1); toggleRect.anchoredPosition = new Vector2(10, -75); toggleRect.sizeDelta = new Vector2(90, 24); var toggleImg = toggleObj.AddComponent(); toggleImg.color = new Color(0.2f, 0.35f, 0.5f, 0.9f); _toggleBtn = toggleObj.AddComponent