using System.Collections.Generic; using AibisDream.Framework; using AibisDream.SaveSystem; using AibisDream.Utility; using TMPro; using UnityEngine; using UnityEngine.UI; using DG.Tweening; namespace AibisDream.FixSystem { public class TaskPanel : MonoBehaviour, ILineView { private const float HiddenLocalX = -10.32f; private const float ShownLocalX = -7.12f; #region 索引 [SerializeField] private Transform taskRoot; [SerializeField] private Transform taskListParent; private GameObject _taskItemPrefab; private readonly Dictionary _taskDict = new(); #endregion private void Awake() { _taskItemPrefab = ResourceKit.LoadAssetSync(ConstRef.TaskItemName); } public bool IsPanelVisible => Mathf.Approximately(taskRoot.localPosition.x, ShownLocalX); public void ShowPanel() { taskRoot.DOLocalMoveX(ShownLocalX, 1f); } /// 动画收起面板(与 ShowPanel 对称)。 public void HidePanel() { taskRoot.DOKill(); taskRoot.DOLocalMoveX(HiddenLocalX, 1f); } public void HidePanelImmediate() { taskRoot.DOKill(); SetPanelVisibleImmediate(false); } private bool _restoreVisibleAfterCollapse; /// 临时收起面板(如进入 Memory 模式),记录之前是否展开,供 RestoreCollapsedPanel 恢复。 public void CollapsePanelTemporary(bool immediate = false) { _restoreVisibleAfterCollapse = IsPanelVisible; if (!_restoreVisibleAfterCollapse) return; if (immediate) HidePanelImmediate(); else HidePanel(); } /// 按 CollapsePanelTemporary 记录的状态恢复面板(之前未展开则不做任何事)。 public void RestoreCollapsedPanel() { if (!_restoreVisibleAfterCollapse) return; _restoreVisibleAfterCollapse = false; ShowPanel(); } public void CompleteTask(string lineId) { if (_taskDict.Remove(lineId, out var taskItem)) { Destroy(taskItem); } } public void ClearTasks() { foreach (var task in _taskDict) { Destroy(task.Value); } _taskDict.Clear(); } public void RunLine(LineSyncToken token) { if (_taskDict.ContainsKey(token.lineInfo.lineId)) { EnumEventSystem.Global.Send(DialogEventEnum.LineShown); token.ForceAdvance(); return; } AddTaskItem(token.lineInfo.lineId, $"\u25cf {token.lineInfo.lineText}"); token.TextStart(); token.TextShown(); token.ForceAdvance(); } public void CaptureSnapshot(out bool isPanelVisible, List tasks) { isPanelVisible = IsPanelVisible; tasks.Clear(); foreach (var kv in _taskDict) { var text = kv.Value.GetComponent()?.text ?? string.Empty; tasks.Add(new TaskEntrySnapshotDto { lineId = kv.Key, text = text }); } } public void ApplySnapshot(bool isPanelVisible, List tasks, bool immediate) { ClearTasks(); if (tasks != null) { foreach (var entry in tasks) { if (string.IsNullOrEmpty(entry.lineId)) { continue; } AddTaskItem(entry.lineId, entry.text); } } if (immediate) { taskRoot.DOKill(); SetPanelVisibleImmediate(isPanelVisible); } else if (isPanelVisible) { ShowPanel(); } } private void AddTaskItem(string lineId, string text) { var taskItem = Instantiate(_taskItemPrefab, taskListParent); var task = taskItem.GetComponent(); task.text = text; _taskDict[lineId] = taskItem; LayoutRebuilder.ForceRebuildLayoutImmediate(taskListParent.GetComponent()); } private void SetPanelVisibleImmediate(bool visible) { var pos = taskRoot.localPosition; pos.x = visible ? ShownLocalX : HiddenLocalX; taskRoot.localPosition = pos; } } }