一、前言與技術補充:
在前面的文章中,我們多次在對話系統裡用到 [NAME] 這個標籤來動態替換玩家暱稱。當時我們聚焦在「對話系統如何讀取並顯示姓名」,而今天我們要回過頭把這套機制的源頭補齊——「玩家究竟是在哪裡輸入自己的名字?又是如何儲存下來的?」
今天我們要實裝遊戲第一幕(FirstScene 1幕)的 「玩家自定義名稱輸入介面(Name Input System)」,講解如何利用 TMP_InputField 與 InputNameManager 腳本讓玩家親自輸入暱稱,並透過協程(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 按鈕。
圖一、FirstScene 1幕 的 Game 視窗截圖(自定義主角名稱介面)
2. Inspector 腳本與事件綁定
選取 Hierarchy 上的 InputNameManager 物件,將 Canvas 上的 InputField (TMP_InputField) 拖入 Name Input Field 欄位,並在 Next Scene Name 輸入目標場景名稱(如 MenuScene)。最後將 Confirm 按鈕的 OnClick() 事件綁定至 InputNameManager.ConfirmName。最後就能輸入玩家想取的主角名!
圖二、點選 Hierarchy 中 InputNameManager 物件時的 Inspector 截圖

圖三、事件綁定腳本後即可輸入自定義名稱(例:英雄)
五、開發實戰經驗:協程平滑存檔與 .Trim() 清除空白
1. yield return null 協程等待一幀的最佳實踐: 在執行 PlayerPrefs.Save() 時,資料同步寫入本地檔案需要極微小的耗時。如果在同一幀內立刻調用 SceneManager.LoadScene(),偶爾會因為場景資源載入佔用 CPU 導致存檔未完全落盤。透過協程等待一幀(yield return null;),能保證存檔資料完美寫入磁碟後再跳轉!
2. 善用 .Trim() 清理無效空格: 玩家有時會不小心輸入純空白鍵(例如 " ")。使用 .Trim() 切除頭尾空格後,搭配 string.IsNullOrEmpty() 判斷,能有效阻擋無效名稱,確保存入 PlayerPrefs 的都是乾淨有效的字串。
六、今日成果與小結
最後一樣傳到GitHub做紀錄,由於這是屬於圍繞在遊戲核心架構與資料流轉的範疇,所以將它放在繼續放在 feature/story-flow:
1.檢查修改狀態
git status
2.加入暫存區並提交 Commit
git add .
git commit -m "feat: 實作 InputNameManager 開局玩家名稱輸入與協程安全存檔 (PlayerPrefs) 機制"
3.推送到遠端開發分支
git push origin feature/story-flow