iT邦幫忙

2026 iThome 鐵人賽

DAY 16
0
Vibe Coding

從課堂半成品到完整發布:獨立遊戲的30天重生記系列 第 16

【DAY16】Unity 2D 敘事遊戲開發:自動存檔埋點設計——AutoSavePoint 與協程時序控制避坑

  • 分享至 

  • xImage
  •  

一、前言:
昨天我們透過 SavePointManager 與 JSON 打造了穩固的底層存讀檔架構。但在實際開發敘事遊戲時,如果每一幕都要手動呼叫存檔會顯得非常笨拙。因此今天【Day 16】我們要實作「自動化關卡埋點機制(AutoSavePoint)」! 今天有兩大重點:
1. 自動觸發設計: 讓玩家推進到特定劇情幕數或關鍵互動節點時,自動抓取當前的金錢與聲譽並寫入存檔。
2. 協程時序控制: 透過 IEnumerator 延遲一幀執行,完美避開 Unity 腳本生命週期中管理器尚未初始化完成的時間差陷阱。

二、自動埋點系統設計架構:
為了讓存檔流程自動化且不出錯,系統需要滿足以下機制:
1. 生命週期自動化: 將觸發邏輯掛載於場景物件上,玩家一進入該幕就自動完成存檔登記。
2. 數值與狀態掛勾: 結合全域的 PlayerStatsManager,精準攔截當下的 money 與 reputation 數值,與當前場景名稱、自定義存檔名稱打包。

三、核心程式實作:自動存檔腳本 (AutoSavePoint.cs)
我們在各個劇情關卡的腳本中整合了自動觸發邏輯:

using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
public class AutoSavePoint : MonoBehaviour {
    [Header("紀錄點顯示名稱 (例如: 第五幕 廣告招牌決策)")]
    public string savePointDisplayName = "未命名紀錄點";
    private IEnumerator Start()  {
        // 延遲一幀,確保場景中所有 Managers(如 PlayerStatsManager)都已完成初始化
        yield return null;
        
        TriggerAutoSave();
    }
    public void TriggerAutoSave() {
        if (SavePointManager.Instance == null) return;
        int money = 0;
        int rep = 0;

        // 讀取當前玩家數值
        if (PlayerStatsManager.Instance != null) {
            money = PlayerStatsManager.Instance.money;
            rep = PlayerStatsManager.Instance.reputation;
        }
        string currentScene = SceneManager.GetActiveScene().name;
        SavePointManager.Instance.SaveAtCheckPoint(savePointDisplayName, currentScene, money, rep);
        Debug.Log($"[AutoSave] 背景自動存檔成功:{savePointDisplayName} ({currentScene}) [金錢: {money}, 聲譽: {rep}]");
    }
}

四、Unity 現場配置與關卡掛載:
在 Unity 中配置這個自動埋點非常直覺:

  1. 在各個幕數的 Scene 裡面(例如 Day05_Scene),建立一個空的 Game Object 並掛載 AutoSavePoint.cs。
  2. 在 Inspector 依據該幕的劇情填入對應的 savePointDisplayName(例如 #05 廣告招牌設置)。
  3. 當玩家從主選單或上一幕推進過來時,只要一進到這個 Scene,系統就會在背景默默把這一幕寫進 JSON 存檔中。
    https://ithelp.ithome.com.tw/upload/images/20260922/201840738Q8AkuDC5j.png
    圖一、在關卡場景(如 OfficeScene 5)中掛載 AutoSavePoint 腳本,即可直接於 Inspector 的「Save Point Display Name」欄位自定義該幕的存檔顯示名稱。

五、開發實戰經驗:初始化時序與防錯避坑
1. 生命週期初始化陷阱: 在早期的版本中,我們直接在 Start() 呼叫存檔,卻發現有時候玩家辛苦賺的錢會被存成 0。這是因為 AutoSavePoint 的 Start() 比數值管理器更早執行。透過改用 IEnumerator 協程並 yield return null,完美解決了初始化時間差的隱患!
2. 同名更新機制: 搭配底層 SavePointManager 的檢查邏輯,重複造訪同一幕時會自動更新數值與時間戳,不會在 JSON 內產生冗餘的垃圾存檔。

因為這兩天都在完善整個存檔機率與自動化流程,把它們放在同一個分支是最合理且有條理的做法。DAY 16 的內容(自動化關卡埋點與協程時序控制)就是昨天 JSON 存檔系統的直接延伸與應用!

1.檢查修改狀態
git status
2.加入暫存區並提交 Commit
git add .
git commit -m "feat: 實作 AutoSavePoint 自動埋點腳本,結合協程時序控制實現進場景自動存檔"
3.推送到遠端開發分支
git push origin feature/save-system


上一篇
【DAY15】Unity 2D 敘事遊戲開發:JSON 紀錄點 (Save Point) 存讀檔架構實作
系列文
從課堂半成品到完整發布:獨立遊戲的30天重生記16
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言