一、前言:
在昨天的內容中,我們成功實現了基於 ScrollView 與 Prefab 的動態存檔清單生成,並確保畫面上只會顯示玩家實際踩點觸發過的真實進度。但有了清單後,隨之而來的新問題是:「玩家要怎麼隨時叫出或關閉這個面板?而且當遊戲進行中發生自動存檔時,面板裡的資料會不會過期?」
今天【Day 18】我們就要在昨天的基礎上,透過疊加的方式為 SaveSelectPanelController 補上兩大重要功能:
1. Toggle 雙向開關控制: 實現按一下開啟、再按一下關閉的直覺切換,並加入智慧防呆。
2. 生命週期自動化(OnEnable): 確保面板每次被呼叫顯示的瞬間,都會自動呼叫昨天的 RefreshSaveList() ,徹底解決資料不同步的痛點。
三、逐步疊加:為控制器補上開關與生命週期防呆
我們延續昨天的 SaveSelectPanelController.cs 架構,在類別中追加以下這幾個關鍵方法與生命週期監聽:
[Header("面板開關設定")]
public GameObject panelRoot; // 欲控制開關的面板本體
public Button closeButton; // 關閉按鈕 (選擇性綁定)
private void Start() {
// 遊戲啟動時若面板預設為開啟,強制刷一次列表
if (gameObject.activeSelf) {
RefreshSaveList();
}
}
private void OnEnable() {
// 【關鍵生命週期】每次面板被 SetActive(true) 時,自動觸發重新整理
RefreshSaveList();
}
/// 狀態切換:按一下打開、再按一下關閉 (Toggle)
public void TogglePanel() {
// 防呆設計:若沒指定 panelRoot,則預設以自身作為開關目標
GameObject target = panelRoot != null ? panelRoot : gameObject;
bool nextState = !target.activeSelf;
target.SetActive(nextState);
// 註:當 target.SetActive(true) 觸發時,Unity 會自動執行 OnEnable(),
// 因此它會順便呼叫 RefreshSaveList(),不需要額外手動寫兩次!
}
/// 手動關閉面板
public void ClosePanel() {
GameObject target = panelRoot != null ? panelRoot : gameObject;
target.SetActive(false);
}
三、架構防呆與互動亮點:
1. 巧妙利用生命週期連鎖: 你會發現當 TogglePanel() 把面板設為 true 時,Unity 自身的 OnEnable() 機制就會自動被喚醒並執行 RefreshSaveList()。這形成了一個漂亮的自動化閉環,完全不怕漏掉資料更新。
2. panelRoot 彈性防呆: 利用 GameObject target = panelRoot != null ? panelRoot : gameObject; 確保就算開發者在 Inspector 忘記拉物件,程式也不會噴出 NullReferenceException 斷開魂結。
圖一、GAME初始畫面

圖二、點擊SAVE後列表出現
Tip:面板初始狀態設定
記得在 Unity 編輯器中,將 SaveSelectPanel 物件最上方的啟用勾勾(Active)預設取消(如圖三所示)。這樣遊戲剛啟動時面板才不會直接蓋在畫面中央,必須等到玩家點擊「SAVE」按鈕觸發 TogglePanel() 後,才會彈出來!
圖三、操作示意圖
四、今日成果與小結
DAY 18 的內容是延續昨天(Day 17)的 SaveSelectPanelController.cs,為存檔選單補上 Toggle 雙向開關控制以及利用 OnEnable() 實現生命週期自動重新整理的防呆機制。因為這依然是在完善整個存讀檔選單與 UI 互動的相同模組,所以它完全屬於同一個分支:
1.檢查修改狀態
git status
2.加入暫存區並提交 Commit
git add .
git commit -m "feat: 擴充 SaveSelectPanelController,實作 TogglePanel 開關切換與 OnEnable 生命週期自動刷新列表機制"
3.推送到遠端開發分支
git push origin feature/save-system