《火拼24》系列教程第二章內容來襲!在首章教程的基礎上,本節將深度揭秘如何運用 UOS 的 Remote Config 服務,實現游戲關卡難度的動態調控——手把手教你通過遠程配置靈活修改關卡參數,無需迭代新版本即可實時優化玩家體驗,讓游戲平衡性調整更高效、更智能!
教程視頻
項目工程獲取與學習指引
1. 初始項目工程下載
倉庫地址:
https://cnb.cool/unity/uos/Rush24Tutorial/-/tree/lesson2-start
分支名稱:lesson2-start 分支
分支說明:請先下載 lesson2-start 分支的項目工程,該分支是本節學習的起點。
倉庫地址:
https://cnb.cool/unity/uos/Rush24Tutorial/-/tree/lesson2-end
分支名稱:lesson2-end 分支
分支說明:lesson2-end 分支包含本節所有功能的完整實現代碼,建議在學習完成后參考或用于調試對照。
教程學習大綱
1. 使用 Remote Config 在服務端配置關卡數據
2. 封裝獲取遠程配置數據的腳本工具類
3. 使用 Remote Config 的數據來動態調控游戲關卡難度
教程操作步驟
接下來我們要開始本節課的學習啦!
1. 使用 Remote Config 在服務端配置關卡數據
1.1 下載并打開項目工程
請先通過上面提供的 git 倉庫鏈接,下載初始狀態(lesson2-start 分支)的項目工程。
然后通過 Unity Hub,打開剛剛下載好的項目工程。在教程中,我們是使用Unity 2022.3.42 f1c1版本來打開項目工程的,該教程同樣適用于團結引擎,請大家自行選擇想要使用的版本來開始你的學習。
打開項目工程以后,首先確保你的項目已經綁定了第一章節教程中設置過的同一個UOS App,因為那個 UOS App 中已經開通過 Passport 服務了。
我們會在第一節教程的功能的基礎上,繼續來添加如何實現在服務端動態調整游戲關卡難度!
1.2什么是 Remote Config
Remote Config 是可以和任意 UOS 應用搭配使用的遠程配置模塊,支持開發者動態更改游戲配置,以減少不必要的打包發版次數。
一些使用Remote Config的例子如下:
A/B Testing 和新功能上線;
可集成 CDN 進行灰度測試;
提前設定好時間的節日推廣/限時活動;
白名單/黑名單,或根據玩家標簽(Tag)提供差異化體驗。
1.3 開通Remote Config 服務并安裝 SDK
在 UOS Launcher 的下拉服務窗口列表中,找到「Remote Config」,點擊「Enable」開啟服務。
然后點擊「Install SDK」,安裝 Remote Config SDK。
1.4 配置關卡數據
1.4.1 配置(Config)的概念
配置(Config)是面向游戲開發者的概念,是傳統的 Config 形式,以 key-value 的形式存儲在云端,游戲開發者有權對 Config 進行管理,其中更改是實時生效的。
1.4.2 配置 Remote Config
在 UOS 網頁端,進入「Remote Config ->配置管理」頁面,點擊「配置(CONFIG)」下面的「立即創建」按鈕:
在彈出窗口中,輸入配置的key、類型和對應的值:
名稱:我們輸入 AllStageLevels,表示該配置是游戲關卡的數據。對于同一 UOS App 來說,名稱(key)是不能重復的。
類型:字段類型有 int、float、long、bool、string、json 六個選項,在這里我們使用 string 類型。
值:暫時輸入 5,6,7,8 2,3,4,5。表示第一關的四張牌的數據是 5,6,7,8,第二關的四張牌的數據是 2,3,4,5。在這里輸入關卡數據的格式是:兩道題目之間用「空格」分隔,同一道題的四個數值之間用「英文逗號」分隔。
配置完數據之后,點擊「添加」按鈕,就可以看到配置好的數據了。
1.4.3 覆蓋 ( Override)的概念
我們可以看到在「配置管理」頁面,還有一個覆蓋(Override)的配置,等后面用到 Override 時再詳細講解它的用法。
先來了解下覆蓋(Override)的概念:
覆蓋(Override)也是面向游戲開發者(Developer)的概念,為了在 Config 之上進行更加靈活的特異性配置,包括應用百分比、生效開始時間、過期時間等。只有游戲開發者可以對 Override 進行管理。
2. 封裝獲取遠程配置數據的腳本工具類
配置好了數據以后,我們來看看代碼中,具體的是如何實現加載 RemoteConfig 中的數據的!
2.1 創建腳本來存放配置的 key
在下圖所示的路徑下,創建一個新的腳本文件夾 RemoteConfig,并在該文件夾下創建一個新的腳本 RemoteConfigKeys.cs。
靜態類RemoteConfigKeys,用于存放遠程配置的鍵名常量。
定義一個常量字符串 AllStageLevels,表示所有關卡的配置鍵名。
namespace TwentyFour.Scripts.Features.RemoteConfig
{
// 定義一個靜態類,用于存放遠程配置的鍵名常量
public static class RemoteConfigKeys
{
// 定義一個常量字符串,表示所有關卡的配置鍵名
public const string AllStageLevels = "AllStageLevels";
}
}
它的值要和剛才 RemoteConfig 網頁段配置的 key 名稱保持一致。
2.2 創建獲取遠程配置的輔助類
在 RemoteConfig 文件夾下,再創建一個新的腳本 RemoteConfigHelper.cs。
該腳本中的代碼實現了一個遠程配置輔助工具類,用于從遠程服務器獲取和管理游戲的配置數據,方便游戲根據遠程參數靈活調整功能和表現。
2.2.1 初始化 Remote Config SDK
創建 Init 方法,作為整個遠程配置功能的初始化入口。在方法內先調用 Initialize 來初始化 RemoteConfig SDK。在初始化過程中如果發生了錯誤,我們會通過 try...catch... 捕獲異常,并打印記錄的錯誤信息,便于代碼調試。
using System;
using System.Threading.Tasks;
using Unity.UOS.Config;
using Logger = TwentyFour.Scripts.Utilities.Logger;
namespace TwentyFour.Scripts.Features.RemoteConfig
{
// 定義遠程配置輔助類
public class RemoteConfigHelper
{
// 初始化遠程配置的異步方法
public static async Task Init()
{
try
{
// 初始化遠程配置SDK
RemoteConfigSDK.Initialize();
}
catch (Exception e)
{
// 捕獲異常并記錄錯誤日志
Logger.LogError($"RemoteConfigHelper Init Error:{e}");
}
}
}
}
2.2.2 獲取 Remote Config 配置過的數據
在初始化方法Init中,調用封裝的GetDefaultRemoteConfig方法,來異步獲取玩家的默認遠程配置,以便游戲運行時動態調整行為。
首先定義字典 _remoteConfigData ,用于本地存儲遠程配置數據,方便后續快速讀取,無需每次都訪問服務器;
然后調用 SDK 提供的 GetPlayerSettingsAsync 函數,向服務器發起一個異步網絡請求,以獲取為當前玩家準備的配置。
網絡請求完成后,如果成功了:
通過 settings.data 從返回結果中獲取響應數據,存在變量 response 中;
然后將從服務器收到的配置列表(response.Settings)轉換成一個字典,并將其賦值給剛才定義過的字典 _remoteConfigData;
接下來為了調試和監控,遍歷所有獲取到的配置項(response.Settings),用 StringBuilder 高效地構建了一個完整的字符串,然后通過 Logger.Log(sb) 將所有配置項打印到日志中,方便開發者查看拉取到的數據是否正確。
網絡請求完成后,如果失敗了:
如果網絡請求或服務器處理失敗,就在日志中記錄一條錯誤信息,方便排查問題。
無論成功與否,最后都將獲取到的玩家默認的配置結果(settings)返回。
using System;
using System.Threading.Tasks;
using Unity.UOS.Config;
using Logger = TwentyFour.Scripts.Utilities.Logger;
using Cloud;
using Unity.UOS.Config.Model;
using System.Linq;
using System.Text;
namespace TwentyFour.Scripts.Features.RemoteConfig
{
// 定義遠程配置輔助類
public class RemoteConfigHelper
{
// 用于存儲遠程配置數據的靜態字典,鍵為配置名,值為Setting對象
private static Dictionary
_remoteConfigData = new Dictionary
(); // 初始化遠程配置的異步方法 public static async Task Init() { try { // 初始化遠程配置SDK RemoteConfigSDK.Initialize(); await GetDefaultRemoteConfig(); // 獲取默認遠程配置 } catch (Exception e) { // 捕獲異常并記錄錯誤日志 Logger.LogError($"RemoteConfigHelper Init Error:{e}"); } } // 異步獲取默認遠程配置的方法 public static async Task > GetDefaultRemoteConfig() { // 發送請求獲取玩家默認設置 var settings = await RemoteConfigSDK.GetPlayerSettingsAsync(new GetPlayerSettingsRequest()); if (settings.IsSuccess()) { // 獲取響應數據 GetPlayerSettingsResponse response = settings.data; // 將設置轉換為字典并保存 _remoteConfigData = response.Settings.ToDictionary(x => x.Key, x => x.Value); var sb = new StringBuilder(); // 遍歷所有設置,拼接日志信息 foreach (var entry in response.Settings) { sb.AppendLine($"Remote Config: {entry.Key} - {entry.Value} ,type: {entry.Value.Type}"); } // 記錄日志 Logger.Log(sb); } else { // 獲取失敗時記錄錯誤日志 Logger.LogError($"RemoteConfigHelper GetDefaultRemoteConfig Error"); } // 返回結果 return settings; } } }
2.2.3 封裝讀取配置數據的接口
封裝方法GetString(key),用于從遠程配置緩存中獲取字符串類型的配置值。后續如果配置了其它數據類型,用到的時候,會再詳細講解其它類型的數據如何讀取。
方法中傳入你想要獲取的配置項的名稱(key);
然后嘗試從 _remoteConfigData 字典中查找是否存在指定 key 的配置項,如果找到了并且該配置項的類型是 string 類型,則返回配置項的值。如果找不到,則返回一個空字符串。
namespace TwentyFour.Scripts.Features.RemoteConfig
{
// 定義遠程配置輔助類
public class RemoteConfigHelper
{
//......
// 獲取遠程配置的字符串類型的數據的方法
public static string GetString(string key)
{
// 嘗試從字典中獲取指定key的值,并判斷類型是否為String
if (_remoteConfigData.TryGetValue(key, out var value) && value.Type == ConfigType.String)
{
// 返回字符串值
return value.Value;
}
// 未獲取到則返回空字符串
return string.Empty;
}
}
}
3. 使用 Remote Config 的數據來動態調控游戲關卡難度
3.1 調用初始化遠程配置的方法
在游戲啟動時,我們將按順序完成遠程配置、關卡、存檔的初始化,最后再進入主場景。
因此,先找到腳本 LoadGameData.cs,在協程方法 Init() 中,實現在成功創建角色之后,先調用初始化遠程配置數據的方法 InitRemoteConfig。
在 InitRemoteConfig 方法中,調用之前封裝好的 RemoteConfigHelper.cs 腳本中的 Init 方法,實現遠程配置的初始化;
然后使用 WaitUntil 等待這個異步任務完成。
using TwentyFour.Scripts.Features.RemoteConfig;
namespace TwentyFour.Scripts.Gameplay.HomePage
{
public class LoadGameData : MonoBehaviour
{
//......
// Start is called before the first frame update
IEnumerator Init()
{
yield return StartCoroutine(InitRemoteConfig());
yield return StartCoroutine(InitStage());
yield return StartCoroutine(InitSave());
GameRouter.LoadHomeSceneFirst();
}
//......
IEnumerator InitRemoteConfig()
{
var t = RemoteConfigHelper.Init();
yield return new WaitUntil(()=>t.IsCompleted);
yield return null;
}
}
}
接著運行游戲進行測試,可以看到 Console 控制臺打印的日志信息。說明已經加載到了遠程配置的關卡數據了,但是發現 Game 窗口中的關卡數據還沒有發生變化。
原因是:在 StageManager.cs 腳本的 LoadAllStagesFromRemoteConfig 方法中,看到目前使用的還是本地的 Resources 文件夾下的 levels.txt 文件中的關卡數據。
public static class StageManager
{
//......
public static void LoadAllStagesFromRemoteConfig()
{
var file = Resources.Load ( "levels").text;
HandleFileContent(file);
}
}
Resources 文件夾下的 levels.txt 文件中的關卡數據如下:
3.2 使用從 RemoteConfig 加載到的關卡數據
現在我們修改下代碼,實現從遠程配置(RemoteConfig )來加載所有關卡的數據。
打開StageManager.cs 腳本:
在原來的方法 HandleFileContent 中,處理的是從 levels.txt 獲取到的字符串,每一行的分隔符號是「\n」,現在的每一行題目的分隔符是「空格」,修改代碼 fileString.Split('\n',' ') 中的分隔符號,這里可以使用可變參數類型,所以一次性可以傳入多個字符分隔符;
該方法的作用主要是:將一段特定格式的字符串,也就是剛才遠程配置過的數據「5,6,7,8 2,3,4,5」,解析成關卡對象(Stage),并存儲到 _allStages 列表中。
namespace TwentyFour.Scripts.Gameplay.GameMode.StageMode
{
public static class StageManager
{
//......
private static void HandleFileContent(string text)
{
_allStages = new List ();
string fileString = text.Replace("\r", "");
string[] lines = fileString.Split('\n',' ');
//......
}
}
}
然后在 LoadAllStagesFromRemoteConfig 方法中,調用 RemoteConfigHelper.cs 腳本中封裝的 GetString 方法,實現從服務器的遠程配置中獲取配置好的字符串類型的關卡數據,存放到變量 file 中,然后判斷以下兩種情況:
如果遠程配置有數據(即字符串不為空),則使用遠程配置的關卡數據;
如果遠程沒有獲取到數據(即字符串為空),則使用本地 Resources 文件夾中名為 levels.txt 的文本資源,作為關卡數據;
兩種情況下,最終都會調用 HandleFileContent 方法來對關卡數據的字符串進行解析的。
using TwentyFour.Scripts.Features.RemoteConfig;
namespace TwentyFour.Scripts.Gameplay.GameMode.StageMode
{
public static class StageManager
{
//......
public static void LoadAllStagesFromRemoteConfig()
{
//獲取 RemoteConfig 中配置的關卡數據
var file = RemoteConfigHelper.GetString(RemoteConfigKeys.AllStageLevels);
if (string.IsNullOrEmpty(file))
{
//使用本地 Resources 文件夾中名為 levels.txt 的文本資源,作為關卡數據
file = Resources.Load ( "levels").text;
}
//解析存放關卡數據的字符串
HandleFileContent(file);
}
}
}
再次運行測試,可以看到 Game 窗口中闖關界面關卡數只有兩關了,說明數據已經從配置的 RemoteConfig 中獲取到了。
接著,大家可以自行再次修改 UOS 網頁端 RemoteConfig 中配置的關卡數據,然后登出賬號后重新登錄,就會自動加載新的關卡數據了。
下節教程預告
教程主題——《火拼24》系列教程三:游戲闖關進度的云端存檔
《火拼24》下一篇教程,將揭秘基于 CRUD Save 打造的游戲闖關進度云端存檔功能。它能實現當前登錄用戶闖關進度的云端保存,讓用戶退出游戲后再次進入仍可無縫銜接,精彩不容錯過!
小貼士:為方便大家提前學習,教程三的分支代碼已同步更新,可提前下載查閱或本地調試。
教程三:初始項目工程(供學習參考)
https://cnb.cool/unity/uos/Rush24Tutorial/-/tree/lesson3-start
教程三:完整示例工程參考(可直接運行)
https://cnb.cool/unity/uos/Rush24Tutorial/-/tree/lesson3-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.