iT邦幫忙

2026 iThome 鐵人賽

DAY 12
0
Vibe Coding

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

【DAY12】Unity 2D 敘事遊戲開發:開局玩家自定義姓名系統與 PlayerPrefs 跨場景傳遞

  • 分享至 

  • xImage
  •  

一、前言與技術補充:
在前面的文章中,我們多次在對話系統裡用到 [NAME] 這個標籤來動態替換玩家暱稱。當時我們聚焦在「對話系統如何讀取並顯示姓名」,而今天我們要回過頭把這套機制的源頭補齊——「玩家究竟是在哪裡輸入自己的名字?又是如何儲存下來的?」
今天我們要實裝遊戲第一幕(FirstScene 1幕)的 「玩家自定義名稱輸入介面(Name Input System)」,講解如何利用 TMP_InputFieldInputNameManager 腳本讓玩家親自輸入暱稱,並透過協程(Coroutine)安全地寫入 PlayerPrefs 做到跨場景持久化傳遞!

二、開局名稱輸入與資料傳遞需求
在 2D 敘事或文字冒險遊戲中,讓玩家能自訂暱稱並在後續劇情中被角色呼喚,是建立第一人稱代入感的核心機制。系統需要滿足以下要求:
1. 開局 UI 輸入介面(FirstScene 1幕): 在遊戲啟動第一幕提供直覺的文字輸入框(TMP_InputField)與 Confirm 確認按鈕。
2. 輸入防呆判斷: 使用 .Trim() 切除無效空格,若玩家未輸入任何內容則中斷流程(return),提示玩家輸入有效名字。
3. 持久化協程安全寫入 (SaveAndLoadScene): 點擊 Confirm 後將名字寫入 PlayerPrefs,並透過協程 yield return null 等待一幀,確保磁碟寫入完成後才執行場景跳轉。
4. 自動跳轉至目標場景 (nextSceneName): 完成存檔後,自動切換至 Inspector 設定的目標場景(如 MenuScene)。

三、核心程式實作:InputNameManager.cs 開局名稱存取與協程控制
我們使用 InputNameManager.cs 腳本,專門處理輸入框檢驗、寫入磁碟與協程切換場景:
1. ConfirmName() 與 SaveAndLoadScene() 完整原始碼:

using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.SceneManagement;
using System.Collections;
public class InputNameManager : MonoBehaviour {
    // 在 Inspector 中拖曳您的 TMP_InputField 到此欄位
    public TMP_InputField nameInputField; 
    // 設置您下一個場景的名字
    public string nextSceneName = "MenuScene"; 
    public void ConfirmName() {
        string playerName = nameInputField.text.Trim(); // .Trim() 去除頭尾空格
        if (string.IsNullOrEmpty(playerName)) {
            Debug.Log("請輸入一個有效的名字!");
            // 可選:在這裡顯示一個錯誤訊息給用戶
            return; 
        }
        // 儲存到遊戲永久資料
        PlayerPrefs.SetString("PlayerName", playerName);
        // 啟動協程來安全地儲存並切換場景
        StartCoroutine(SaveAndLoadScene());
    }
    private IEnumerator SaveAndLoadScene() {
        // 1. 強制寫入數據,確保名字不會丟失
        PlayerPrefs.Save(); 
        
        // 2. 等待一幀,確保寫入操作有時間完成 (這是最佳實踐)
        yield return null; 
        // 3. 執行場景切換
        if (!string.IsNullOrEmpty(nextSceneName)) {
            SceneManager.LoadScene(nextSceneName);
        }
        else {
            Debug.LogError("Next Scene Name 欄位是空的!請在 Inspector 中設置。");
        }
    }
}

2. 對話端讀取鏈接回顧
儲存完成後,後續場景中的對話腳本(如 TypewriterEffect.cs 或 StorySceneManager.cs)就能在 Start() 時輕鬆抓取:

// 後續對話腳本讀取暱稱範例
playerName = PlayerPrefs.GetString("PlayerName", "英雄");
string processedText = rawDialogueText.Replace("[NAME]", playerName);

四、Unity Inspector 設定與 UI 綁定
在 Unity 介面中,我們將輸入框與 InputNameManager 腳本進行連結:

1. 開局自訂名稱 UI 配置 (FirstScene 1幕)
在 FirstScene 1幕 場景的 Canvas 下建立輸入面板,包含提示文字「Please enter your name:」、TMP_InputField(Enter Name...)以及 Confirm 按鈕。
https://ithelp.ithome.com.tw/upload/images/20260919/20184073VHYQJrVAuI.png
圖一、FirstScene 1幕 的 Game 視窗截圖(自定義主角名稱介面)

2. Inspector 腳本與事件綁定
選取 Hierarchy 上的 InputNameManager 物件,將 Canvas 上的 InputField (TMP_InputField) 拖入 Name Input Field 欄位,並在 Next Scene Name 輸入目標場景名稱(如 MenuScene)。最後將 Confirm 按鈕的 OnClick() 事件綁定至 InputNameManager.ConfirmName。最後就能輸入玩家想取的主角名!
https://ithelp.ithome.com.tw/upload/images/20260919/20184073J8zceyZLFJ.png
圖二、點選 Hierarchy 中 InputNameManager 物件時的 Inspector 截圖

https://ithelp.ithome.com.tw/upload/images/20260919/2018407314mdi4MufB.png
圖三、事件綁定腳本後即可輸入自定義名稱(例:英雄)

五、開發實戰經驗:協程平滑存檔與 .Trim() 清除空白
1. yield return null 協程等待一幀的最佳實踐: 在執行 PlayerPrefs.Save() 時,資料同步寫入本地檔案需要極微小的耗時。如果在同一幀內立刻調用 SceneManager.LoadScene(),偶爾會因為場景資源載入佔用 CPU 導致存檔未完全落盤。透過協程等待一幀(yield return null;),能保證存檔資料完美寫入磁碟後再跳轉!
2. 善用 .Trim() 清理無效空格: 玩家有時會不小心輸入純空白鍵(例如 " ")。使用 .Trim() 切除頭尾空格後,搭配 string.IsNullOrEmpty() 判斷,能有效阻擋無效名稱,確保存入 PlayerPrefs 的都是乾淨有效的字串。

六、今日成果與小結

  • 開局名稱輸入介面: 完成了 FirstScene 1幕 的 TMP_InputField UI 與 InputNameManager 腳本架構。
  • 協程安全存檔: 實裝了 ConfirmName() 與 SaveAndLoadScene() 協程,確保 PlayerPrefs 穩定落盤。
  • 遊戲起點無縫串接: 實現從輸入姓名 ➔ 點擊 Confirm 檢驗 ➔ 協程安全存檔 ➔ 自動跳轉進入目標場景(MenuScene)的完整開局流程!

最後一樣傳到GitHub做紀錄,由於這是屬於圍繞在遊戲核心架構與資料流轉的範疇,所以將它放在繼續放在 feature/story-flow:

1.檢查修改狀態
git status

2.加入暫存區並提交 Commit
git add .
git commit -m "feat: 實作 InputNameManager 開局玩家名稱輸入與協程安全存檔 (PlayerPrefs) 機制"

3.推送到遠端開發分支
git push origin feature/story-flow


上一篇
【DAY11】Unity 2D 敘事遊戲開發: Unity 2D 敘事遊戲開發:跨場景資料持久化 — PlayerStatsManager 單例與 DontDestroyOnLoad 狀態同步
下一篇
【DAY13】Unity 2D 敘事遊戲開發:跨場景玩家暱稱繼承與黑屏旁白打字機效果 (TypewriterEffect)
系列文
從課堂半成品到完整發布:獨立遊戲的30天重生記16
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言