在上一篇公眾號文章《》中,我們已通過 Passport Login 實現了用戶登錄功能。本節教程將延續上一節的開發脈絡,基于已搭建的 Passport 服務器環境,繼續為你的游戲項目添加核心功能——從角色創建到角色管理的全流程實現。
從基礎功能搭建到角色體系擴展,一步步為你的游戲角色「建立完整身份檔案」,讓角色系統真正「立起來」!
教程視頻
項目工程獲取與學習指引
1. 初始項目工程下載
倉庫地址:
https://cnb.cool/unity/uos/Rush24Tutorial/-/tree/lesson1-start
分支名稱:lesson1-start 分支
分支說明:請先下載 lesson1-start 分支的項目工程,并確保您已經按照《》中的步驟,成功實現了用戶登錄功能。然后,再接著學習本節教程的內容。
倉庫地址:
https://cnb.cool/unity/uos/Rush24Tutorial/-/tree/lesson1-end
分支名稱:lesson1-end 分支
分支說明:lesson1-end 分支包含本節所有功能的完整實現代碼,建議在學習完成后參考或用于調試對照。
教程學習大綱
1.獲取 Passport 創建的域
2. 判斷域中是否已經創建過角色
3. 域中如果無角色,則創建新角色
4. 域中如果已有角色,則直接獲取已創建過的角色
5. 在玩家信息界面上同步更新顯示角色的昵稱
教程操作步驟
接下來我們來看看,如何創建并管理你的角色!
1. 獲取 Passport 創建的域
登錄完成后,可以創建一個角色進入游戲,需要先判斷指定的域下是否創建了角色。
域的概念:
域:對應游戲中區服的概念,可以根據開發者的需求來實現滾服或者合服。我們的游戲設計并不是強養成類型,不需要滾服,所以只需要創建一個默認的域(Realm)就可以滿足需求。
在 Identity.cs 腳本中添加代碼:
定義變量 _defaultRealmID 用于緩存用戶所屬的默認服務器的域 ID。
定義變量 CurrentPersona 表示用戶的身份信息,如用戶名、頭像等,用于全局訪問當前登錄用戶的身份數據。
添加方法 GetRealmID:在方法中,會先調用 PassportSDK 提供的 GetRealms 方法獲取已經創建的域的列表,然后從域列表中根據需要選擇一個域,在這里我們暫時先使用域列表的第一個域。大家也可以根據自己的需求,選擇你想要使用的某一個域。
using System.Linq;
using Passport;
using Unity.Passport.Runtime;
using System.Threading.Tasks;
namespace TwentyFour.Scripts.Features.Player
{
public class Identity
{
private static string _defaultRealmID = "";
public static Persona CurrentPersona;
public static async Task
GetRealmID() { if (!string.IsNullOrEmpty(_defaultRealmID)) return _defaultRealmID; var realms = await PassportSDK.Identity.GetRealms(); if (realms.Any()) { _defaultRealmID = realms[0].RealmID; } return _defaultRealmID; } } }
我們可以進入 UOS 網頁端 Passport 的「服務器」模塊,可以看到默認已經幫我們創建了一個域了。大家也可以點擊按鈕「創建新的域」來實現構建一個域。
2. 判斷域中是否創建過角色
在用戶進入主頁時,需要驗證用戶是否已創建角色。所以在 LoadGameData.cs 腳本中,先注釋掉 Start 中對 Init 方法的調用,然后創建協程方法 CheckPersona來判斷這個功能。
調用之前定義的 Identity 腳本類中的方法 GetRealmID,來異步獲取用戶所屬的默認域 ID,等待異步任務完成后,若獲取到有效的域 ID,則將其存入 realmID 變量,供下一步使用;
然后再調用 Passport SDK 的接口 GetPersonaByRealm,異步獲取指定域 ID 下用戶的角色信息,在使用 WaitUntil 確保獲取角色數據的任務完成后,輸出打印下獲取到的 Persona 是否為 null,用于調試。若為 null,說明用戶在該域下未創建角色。
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using TwentyFour.Scripts.Features.Save;
using TwentyFour.Scripts.Gameplay.GameMode.StageMode;
using Passport;
using Unity.Passport.Runtime;
using System.Threading.Tasks;
using System;
using TwentyFour.Scripts.Features.Player;
using Logger = TwentyFour.Scripts.Utilities.Logger;
namespace TwentyFour.Scripts.Gameplay.HomePage
{
public class LoadGameData : MonoBehaviour
{
public GameObject createPersonaDialog;
public Text progressTextTmp;
void Start()
{
StartCoroutine(CheckPersona());
}
IEnumerator CheckPersona()
{
string realmID = String.Empty;
Task
task = Identity.GetRealmID(); yield return new WaitUntil(()=>task.IsCompleted); if (!string.IsNullOrEmpty(task.Result)) realmID = task.Result; Task getPersonaTask = PassportSDK.Identity.GetPersonaByRealm(realmID); yield return new WaitUntil(()=>getPersonaTask.IsCompleted); Logger.Log("getPersonaTask.Result == null :" + (getPersonaTask.Result == null)); } //...... } }
運行項目后,可以在控制臺看到輸出的日志信息:Result 為 null,說明并沒有創建過角色。
3. 域中無角色,則創建新角色
3.1 激活創建角色的彈窗
如果 getPersonaTask.Result 為空,說明域中沒有角色,我們需要先激活創建角色的彈窗。
在 LoadGameData.cs 腳本的 CheckPersona 方法中,則先激活創建角色的彈框對象 createPersonaDialog 。
public class LoadGameData : MonoBehaviour
{
public GameObject createPersonaDialog;
public Text progressTextTmp;
//......
IEnumerator CheckPersona()
{
string realmID = String.Empty;
Task
task = Identity.GetRealmID(); yield return new WaitUntil(()=>task.IsCompleted); if (!string.IsNullOrEmpty(task.Result)) realmID = task.Result; Task getPersonaTask = PassportSDK.Identity.GetPersonaByRealm(realmID); yield return new WaitUntil(()=>getPersonaTask.IsCompleted); Logger.Log("getPersonaTask.Result == null :" + (getPersonaTask.Result == null)); if (getPersonaTask.Result == null) { Logger.Log("當前域無角色,請創建新角色"); createPersonaDialog.SetActive(true); } } }
在 Hierarchy 窗口中,找到 LoadGameData 對象,為其身上的腳本 LoadGameData.cs 中的變量 createPersonaDialog 賦值:
然后運行測試,在 Game 窗口中看到了 UI 的彈窗。
接著,我們要開始創建角色了。
3.2 定義委托表示角色創建完成的回調
在 LoginController.cs 腳本中定義一個委托,來實現當角色創建完成后,返回創建的角色的時候使用。
public class LoginController : MonoBehaviour
{
//......
public delegate void CreatePersonaCompleteCallback(Persona persona);
}
3.3 添加創建角色的腳本
在 Login 腳本文件夾下,再創建一個新的腳本 CreatePersona.cs,來實現創建角色的功能。
CreatePersona.cs 腳本代碼邏輯如下:
定義變量 personaNameText,指向 UI 中用戶輸入角色名稱的輸入框組件;
同時獲取下 LoginController.cs 腳本中的委托變量,用于觸發角色創建成功時的回調;
在 Create 方法中,先獲取到已經創建好的域,存儲在 realmID 變量中。然后調用 PassportSDK 提供的 CreatePersona 方法,在指定的域 realmID 中來創建一個角色,并賦值給 persona 變量;
角色創建成功后,將創建的角色 persona 通過委托返回;
同時會使用 try...catch... 捕獲 Passport 遇到的異常,并在 UI 界面上顯示出錯誤信息。
using Passport;
using Unity.Passport.Runtime;
using Unity.UOS.TwentyFour;
using UnityEngine.UI;
using UnityEngine;
using Unity.Passport.Runtime.UI;
namespace TwentyFour.Scripts.Features.Player
{
public class CreatePersona : MonoBehaviour
{
public InputField personaNameText;
public LoginController.CreatePersonaCompleteCallback OnCreatePersonaComplete;
///
/// 創建 Persona
///
public async void Create()
{
if (string.IsNullOrEmpty(personaNameText.text))
{
Debug.LogError("Empty Persona name");
}
try
{
var realmID = await Identity.GetRealmID();
Persona persona = await PassportSDK.Identity.CreatePersona(personaNameText.text, realmID);
Debug.Log("成功創建角色");
OnCreatePersonaComplete(persona);
}
catch (PassportException e)
{
Debug.Log(e.Code);
UIMessage.Show(e.ErrorMessage, MessageType.Error);
}
}
}
}
將 CreatePersona.cs 腳本拖拽給場景中的 CreatePersonaDialog 對象,并為面板上的 personaNameText 變量賦值:
找到創建角色的面板(CreatePersonaDialog)上的「確定」按鈕(Button_Ok):
給按鈕(Button_Ok)對象,綁定 CreatePersona.cs 腳本中的 Create 方法。
3.4 創建角色完成后加載游戲關卡
繼續在 LoadGameData.cs 腳本中添加代碼:
創建角色框對象激活顯示以后,獲取到它身上的 CreatePersona.cs 腳本組件,并將之前定義的委托對象綁定到當前腳本類中的 OnCreatePersonaComplete 方法;
在回調方法 OnCreatePersonaComplete 中,將全局身份管理類 Identity.cs 的 CurrentPersona 屬性,設置為新創建的角色;
同時,在角色創建完成的回調方法中,還會調用新添加的協程方法 SelectPersonaAndInit。并在方法內調用協程方法 Init() ,來加載關卡的數據進行闖關。
public class LoadGameData : MonoBehaviour
{
//......
IEnumerator CheckPersona()
{
//......
if (getPersonaTask.Result == null)
{
Logger.Log("當前域無角色,請創建新角色");
createPersonaDialog.SetActive(true);
var createPersonaController = createPersonaDialog.GetComponent ();
createPersonaController.OnCreatePersonaComplete = OnCreatePersonaComplete;
}
}
void OnCreatePersonaComplete(Persona p)
{
Identity.CurrentPersona = p;
Logger.LogInfo($"創建角色成功,角色ID:{Identity.CurrentPersona.PersonaID}");
StartCoroutine(SelectPersonaAndInit());
}
IEnumerator SelectPersonaAndInit()
{
yield return StartCoroutine(Init());
}
//......
}
3.5 運行游戲進行測試,開啟敏感詞檢測
在 Game 窗口創建角色的彈窗中,輸入角色的昵稱。
開通敏感詞檢測功能:
在 Passport 的「用戶管理」頁面,可以開啟角色對用戶名/角色名的敏感詞檢測。
開啟敏感詞檢測后,在輸入了敏感詞信息時,會在 Game 窗口和 Console 窗口看到提示的“無效的名字” 的錯誤,表明所輸入的名稱并未通過敏感詞檢測,可以重新輸入一個昵稱。
重新輸入昵稱點擊「確定」后,就可以進入游戲主頁面,選擇闖關了。
在 Passport 的「角色管理」頁面,可以看到創建過的名稱為 Player1 的角色。
4. 域中已有角色,則直接獲取已創建的角色
在 LoadGameData.cs 腳本中繼續添加判斷:
如果用戶已經創建過角色,則通過 getPersonaTask.Result 直接獲取創建好的角色;
然后調用協程方法 SelectPersonaAndInit,直接來跳轉到游戲闖關頁面。
public class LoadGameData : MonoBehaviour
{
//......
IEnumerator CheckPersona()
{
if (getPersonaTask.Result == null)
{
Logger.Log("當前域無角色,請創建新角色");
//......
}
else
{
Identity.CurrentPersona = getPersonaTask.Result;
yield return StartCoroutine(SelectPersonaAndInit());
Logger.Log($"當前角色為:{Identity.CurrentPersona.DisplayName}");
}
}
}
大家可以自行再次運行測試下,已經有角色后,是不會再彈出創建角色的輸入框的。
5. 在玩家信息界面上同步更新顯示角色的昵稱
在下圖所示的路徑下,創建一個新的文件夾 PlayerInfo,并在該文件夾下創建一個新的腳本 PlayerInfoPanel.cs,來實現將用戶創建的角色昵稱同步顯示在玩家的信息面板上。
腳本中 PlayerInfoPanel.cs 代碼如下:
定義變量 playerName,用來更新顯示昵稱;
新添加一個方法 GetPlayerInfo,將 Identity.cs 腳本中之前存儲的角色( CurrentPersona) 的昵稱顯示在 UI 文本框上;
同時,會在 PlayerInfoPanel 面板打開時自動調用的 OnEnable 方法中,調用 GetPlayerInfo 方法,來更新 UI 的顯示。
using System;
using UnityEngine;
using UnityEngine.UI;
namespace TwentyFour.Scripts.Features.Player
{
public class PlayerInfoPanel : MonoBehaviour
{
public Text playerName;
private void OnEnable()
{
GetPlayerInfo();
}
private void GetPlayerInfo()
{
playerName.text = Identity.CurrentPersona?.DisplayName;
}
}
}
找到 MainScene 場景中的 PlayerInfoPanel 對象,將腳本 PlayerInfoPanel.cs 拖拽到它身上,并為 Inspector 面板上的 playerName 變量賦值:
運行項目后,可以看到如下所示的效果,已經可以更新顯示用戶昵稱了。
管理創建過的角色
刪除角色
在 Passport 的「角色管理」頁面,可以看到所有已創建過的角色信息,以及該角色所屬的用戶 ID。如果想刪除某個角色的話,可以點擊角色信息最右側的「刪除角色」的按鈕。
大家在彈窗中,一定要仔細閱讀提示信息后,再點擊「確認刪除」按鈕哦!剛才選中的角色就被成功刪除了。
刪除用戶
接下來,大家先看下我選中的這條角色信息,可以看到 1000001004 角色是屬于 1000001002 用戶的。
在 Passport 的「用戶管理」頁面,可以看到登錄過的所有用戶。我們點擊「用戶管理」頁面上的 1000001002 用戶最右側的「刪除用戶」按鈕:
會有彈窗再次提醒大家,是否真的要刪除該用戶的。因為刪除用戶時,也會把該用戶剛才創建的角色一起刪除的。如果你確定要刪除,就點擊「確認刪除」的按鈕。
當我們成功刪除了指定用戶 1000001002 后,在「用戶管理」頁面已經沒有該用戶了,而且在「角色管理」頁面可以看到該用戶下的角色也已經一起被刪除了。
下節教程預告
教程主題——《火拼24》系列教程二:動態調控游戲關卡難度
《火拼24》下一篇教程,將聚焦使用 Remote Config 動態調控游戲關卡難度的實戰技巧,教你如何通過遠程配置靈活調整游戲關卡難度參數,無需發布新版本即可優化玩家體驗!
小貼士:為方便大家提前學習,教程二的分支代碼已同步更新,可提前下載查閱或本地調試。
教程二:初始項目工程(供學習參考)
https://cnb.cool/unity/uos/Rush24Tutorial/-/tree/lesson2-start
教程二:完整示例工程參考(可直接運行)
https://cnb.cool/unity/uos/Rush24Tutorial/-/tree/lesson2-end
Unity Online Services (UOS) 是一個專為游戲開發者設計的一站式游戲云服務平臺,提供覆蓋游戲全生命周期的開發、運營和推廣支持。
了解更多 UOS 相關信息:
官網:https://uos.unity.cn
技術交流 QQ 群:823878269
Unity 官方微信
第一時間了解Unity引擎動向,學習進階開發技能
每一個“點贊”、“在看”,都是我們前進的動力
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.