diff --git a/Assets/Scripts/FixSystemNew/BodyModule/BodyModuleSystem.cs b/Assets/Scripts/FixSystemNew/BodyModule/BodyModuleSystem.cs
index 1513bd7da..38104e494 100644
--- a/Assets/Scripts/FixSystemNew/BodyModule/BodyModuleSystem.cs
+++ b/Assets/Scripts/FixSystemNew/BodyModule/BodyModuleSystem.cs
@@ -72,7 +72,7 @@ namespace AibisDream.FixSystem
RepairSystemManager.Register(this);
}
- /// 捕获插线模块持久状态(分组 + UF + Chip)。
+ /// 捕获插线模块持久状态(分组 + UF + Chip + 高亮/报警)。
public BodyModuleSnapshotDto CaptureBodyModuleSnapshot()
{
var dto = new BodyModuleSnapshotDto
@@ -86,6 +86,13 @@ namespace AibisDream.FixSystem
var chipModule = FindBodyModuleByName("Color")?.GetComponent();
chipModule?.CaptureState(dto);
+ foreach (var module in EnumerateAllBodyModules())
+ {
+ var name = module.data.moduleName;
+ if (module.IsHighlighted) dto.highlightedModules.Add(name);
+ if (module.IsAlarmed) dto.alarmedModules.Add(name);
+ }
+
return dto;
}
@@ -105,6 +112,31 @@ namespace AibisDream.FixSystem
var chipModule = FindBodyModuleByName("Color")?.GetComponent();
chipModule?.ApplyState(dto);
+
+ var highlighted = new HashSet(dto.highlightedModules ?? Enumerable.Empty());
+ var alarmed = new HashSet(dto.alarmedModules ?? Enumerable.Empty());
+
+ foreach (var module in EnumerateAllBodyModules())
+ {
+ var name = module.data.moduleName;
+ module.Highlight(highlighted.Contains(name));
+ module.Alarm(alarmed.Contains(name));
+ }
+ }
+
+ private IEnumerable EnumerateAllBodyModules()
+ {
+ if (_bodyModuleGroup != null)
+ {
+ foreach (var module in _bodyModuleGroup.GetComponentsInChildren(true))
+ yield return module;
+ }
+
+ if (_headModuleGroup != null)
+ {
+ foreach (var module in _headModuleGroup.GetComponentsInChildren(true))
+ yield return module;
+ }
}
///
diff --git a/Assets/Scripts/FixSystemNew/BodyModule/Modules/BodyModule.cs b/Assets/Scripts/FixSystemNew/BodyModule/Modules/BodyModule.cs
index 99f81bad1..de429d3d8 100644
--- a/Assets/Scripts/FixSystemNew/BodyModule/Modules/BodyModule.cs
+++ b/Assets/Scripts/FixSystemNew/BodyModule/Modules/BodyModule.cs
@@ -28,6 +28,10 @@ namespace AibisDream.FixSystem
/// Yarn 可能在 Start 里异步加载材质完成前就调用 ModuleHightLight,需记下来待加载后再套材质。
///
private bool _wantsHighlight;
+ private bool _wantsAlarm;
+
+ public bool IsHighlighted => _wantsHighlight;
+ public bool IsAlarmed => _wantsAlarm;
[SerializeField]
private SpriteRenderer targetSpriteRenderer; // 目标的 SpriteRenderer
@@ -99,7 +103,7 @@ namespace AibisDream.FixSystem
else
Debug.LogError("[BodyModule] Failed to load AlarmMaterial");
- ApplyHighlightVisual();
+ ApplyModuleVisual();
}
#region 插槽功能
@@ -165,23 +169,25 @@ namespace AibisDream.FixSystem
public void Highlight(bool enable)
{
_wantsHighlight = enable;
- ApplyHighlightVisual();
- }
-
- private void ApplyHighlightVisual()
- {
- if (targetSpriteRenderer == null || _highlightMaterial == null) return;
- if (_alarmMaterial != null && targetSpriteRenderer.material == _alarmMaterial) return;
-
- targetSpriteRenderer.material = _wantsHighlight ? _highlightMaterial : _originalMaterial;
+ ApplyModuleVisual();
}
public void Alarm(bool enable)
{
- if (targetSpriteRenderer != null && _alarmMaterial != null)
- {
- targetSpriteRenderer.material = enable ? _alarmMaterial : _originalMaterial;
- }
+ _wantsAlarm = enable;
+ ApplyModuleVisual();
+ }
+
+ private void ApplyModuleVisual()
+ {
+ if (targetSpriteRenderer == null) return;
+
+ if (_wantsAlarm && _alarmMaterial != null)
+ targetSpriteRenderer.material = _alarmMaterial;
+ else if (_wantsHighlight && _highlightMaterial != null)
+ targetSpriteRenderer.material = _highlightMaterial;
+ else
+ targetSpriteRenderer.material = _originalMaterial;
}
#endregion
diff --git a/Assets/Scripts/FixSystemNew/FixSystemCenter.cs b/Assets/Scripts/FixSystemNew/FixSystemCenter.cs
index 55e963fcc..00b37dfe1 100644
--- a/Assets/Scripts/FixSystemNew/FixSystemCenter.cs
+++ b/Assets/Scripts/FixSystemNew/FixSystemCenter.cs
@@ -22,6 +22,15 @@ namespace AibisDream.FixSystem
SystemDic ??= new IOCContainer();
Context = new FixSceneContext(SystemDic);
Director = new FixSceneDirector();
+ }
+
+ private void Start()
+ {
+ if (SaveRestoreOrchestrator.IsRestoring)
+ {
+ return;
+ }
+
StartCoroutine(Director.Init(defaultMode));
}
diff --git a/Assets/Scripts/FixSystemNew/Screen System/Core/FixPanelSystem.cs b/Assets/Scripts/FixSystemNew/Screen System/Core/FixPanelSystem.cs
index aca70f4a1..c05fc6ace 100644
--- a/Assets/Scripts/FixSystemNew/Screen System/Core/FixPanelSystem.cs
+++ b/Assets/Scripts/FixSystemNew/Screen System/Core/FixPanelSystem.cs
@@ -149,6 +149,11 @@ namespace AibisDream.FixSystem
dto.pluggedModuleName = null;
}
+ if (taskPanel != null)
+ {
+ taskPanel.CaptureSnapshot(out dto.isTaskPanelVisible, dto.tasks);
+ }
+
return dto;
}
@@ -164,6 +169,8 @@ namespace AibisDream.FixSystem
}
GetRepairPanel()?.ApplyCableSnapshot(dto.isCableRetracted, dto.pluggedModuleName);
+
+ taskPanel?.ApplySnapshot(dto.isTaskPanelVisible, dto.tasks, immediate: true);
}
/// 读档终态:跳过 StartAllSystems 动画,直接写面板壳层状态。
diff --git a/Assets/Scripts/FixSystemNew/Screen System/FixPanel/CablePanel.cs b/Assets/Scripts/FixSystemNew/Screen System/FixPanel/CablePanel.cs
index e5b753437..21a4b5aac 100644
--- a/Assets/Scripts/FixSystemNew/Screen System/FixPanel/CablePanel.cs
+++ b/Assets/Scripts/FixSystemNew/Screen System/FixPanel/CablePanel.cs
@@ -111,6 +111,17 @@ namespace AibisDream.FixSystem
if (retracted)
{
+ if (ShouldSkipRetractOnRestore())
+ {
+ if (isCableRetracted)
+ {
+ DropDownCableImmediate();
+ }
+
+ curSocket = null;
+ return;
+ }
+
SetRetractCable();
curSocket = null;
return;
@@ -153,6 +164,7 @@ namespace AibisDream.FixSystem
var socketPos = module.GetSocketPos();
PlugRef.RestoreInsertedAt(socketPos);
CableRef.SetEndPos(socketPos);
+ SetCableMode(CableMode.Visual);
BodyModuleSystem.CloseModuleSlots(null);
}
@@ -166,6 +178,13 @@ namespace AibisDream.FixSystem
PlugRef.SetSpriteVisible(true);
}
+ private static bool ShouldSkipRetractOnRestore()
+ {
+ return FixSystemCenter.Instance != null
+ && FixSystemCenter.Director.HasMode
+ && FixSystemCenter.Director.CurrentMode == FixSceneMode.BodyModule;
+ }
+
private void Update()
{
// 获取线缆方向并更新转盘旋转
@@ -177,10 +196,14 @@ namespace AibisDream.FixSystem
public void ResetPlug()
{
- // 不在初始插孔里,就从当前插孔拔出来,插回初始插孔
- PlugRef.PullUpSocket();
+ if (IsPlugInSocket())
+ {
+ PlugRef.PullUpSocket();
+ }
+
BodyModuleSystem.CloseModuleSlots(null);
- PlugRef.ReturnToStartPosition();
+ DropDownCableImmediate();
+
AudioManager.Instance.PlaySfx("event:/ActionFB/mods_close");
AudioManager.Instance.PlaySfx("event:/FollowInput/plugdrop");
}
diff --git a/Assets/Scripts/FixSystemNew/Screen System/FixPanel/TaskPanel.cs b/Assets/Scripts/FixSystemNew/Screen System/FixPanel/TaskPanel.cs
index 0b6d0602e..d81ebe74c 100644
--- a/Assets/Scripts/FixSystemNew/Screen System/FixPanel/TaskPanel.cs
+++ b/Assets/Scripts/FixSystemNew/Screen System/FixPanel/TaskPanel.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using AibisDream.Framework;
+using AibisDream.SaveSystem;
using AibisDream.Utility;
using TMPro;
using UnityEngine;
@@ -10,6 +11,9 @@ 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;
@@ -26,8 +30,9 @@ namespace AibisDream.FixSystem
public void ShowPanel()
{
- taskRoot.DOLocalMoveX(-7.12f, 1f);
+ taskRoot.DOLocalMoveX(ShownLocalX, 1f);
}
+
public void CompleteTask(string lineId)
{
if (_taskDict.Remove(lineId, out var taskItem))
@@ -54,15 +59,70 @@ namespace AibisDream.FixSystem
return;
}
- var taskItem = Instantiate(_taskItemPrefab, taskListParent);
- var task = taskItem.GetComponent();
- task.text = $"\u25cf {token.lineInfo.lineText}";
+ AddTaskItem(token.lineInfo.lineId, $"\u25cf {token.lineInfo.lineText}");
token.TextStart();
-
- _taskDict[token.lineInfo.lineId] = taskItem;
token.TextShown();
token.ForceAdvance();
+ }
+
+ public void CaptureSnapshot(out bool isPanelVisible, List tasks)
+ {
+ isPanelVisible = Mathf.Approximately(taskRoot.localPosition.x, ShownLocalX);
+ 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;
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Assets/Scripts/SaveSystem/Providers/FixPanelSnapshotProvider.cs b/Assets/Scripts/SaveSystem/Providers/FixPanelSnapshotProvider.cs
index ebdb5dc2e..f2abdf0e3 100644
--- a/Assets/Scripts/SaveSystem/Providers/FixPanelSnapshotProvider.cs
+++ b/Assets/Scripts/SaveSystem/Providers/FixPanelSnapshotProvider.cs
@@ -1,9 +1,9 @@
-using UnityEngine;
+using UnityEngine;
namespace AibisDream.SaveSystem
{
///
- /// sections["fixPanel"]:FixPanel 壳层 + 线缆/插头。RestoreOrder=66,在 fix 之后、bodyModule 之前。
+ /// sections["fixPanel"]:FixPanel 壳层 + 线缆/插头 + TaskPanel。RestoreOrder=66,在 fix(65) 之后写回面板/线缆/任务快照。
///
public class FixPanelSnapshotProvider : ISyncSnapshotProvider
{