跳到主要內容

精選

遊戲伺服器2025年初架設與研究part14收送封包的Json格式與Unity內建JsonUtility相關的問題(支援性)

 上次針對如何在Unity的新版TMP Text中使用中文字 而這次則是來分享一下先前有提過的 Json文字轉換 的問題 首先我們知道Unity內建的Json轉換是 JsonUtility JsonUtility 在使用上有一些限制在 算是有優點也有缺點 優點是畢竟是寫在Unity底層的, 效能 比較好 如果功能沒有問題的情況下,可以比額外安裝的Json轉換插件效能要好上不少 甚至有些插件能差兩倍以上的執行效能 不過自然也是有缺點 就是它有不少 不支援 的型別 很多時候常常讓伺服器與遊戲端的人打架的其中一個原因,伺服器表示資料明明就有送,遊戲端則是表示我沒收到(伺服器傳的Json格式轉不出來的種種問題或是可能性) 詳細可以參考Unity的官方文件 https://docs.unity3d.com/6000.1/Documentation/Manual/json-serialization.html 那我這邊也把一些重點特別拿出來講 首先我們先前在聊天訊息回傳的時候,就已經有用到基本的功能 可以先看到我們伺服器端的程式碼(Python) 如以上這語法 這是我們先前使用的方式 那這邊因為是跟先前相同的 相同的部分我就用截圖來顯示(詳細程式碼在Part11有可以複製) 可以看到我們主要回傳的結構 json.dumps({"type": "chat", "message": msg}) 這段就是把後面的內容透過Json轉換成Json字串後傳給使用者(遊戲端) 而我們Unity接收的位置是這樣寫的 ServerPacket packet = JsonUtility.FromJson<ServerPacket>(json); 這行就是我們今天 主要 想討論的地方 並且假設大家想要使用額外安裝的Json套件,也幾乎就是替換這行就能達到想要的效果 接下來我們看到ServerPacket這個class 這邊可以看到關鍵是我們的class要 可序列化 也就是說要加上 [Serializable] 那雖然說是只要加上可序列化,就能轉換 但是也是因為這樣,有很多不能被Unity內建支援的型別,則會轉換不出來 而...

遊戲伺服器2025年初架設與研究part6透過POST簡單的實作類登入與驗證流程並回傳成功與否的相關資訊

 首先上次已經可以順利的把Unity中的資料送到伺服器的資料庫中

也算是簡單地把玩家的資料註冊到伺服器的資料庫中

那這次就是簡單的應用一下,透過類似登入的行為來演示一下雙方收送封包的過程

並且一樣使用先前利用過的POST來傳遞

首先我們先到Unity,到先前傳送POST的地方進行調整


using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

上面是using的部分


IEnumerator SendLoginRequest(string account, string password)
	{
		string svUrl = "https://自己的網域/game_test_login";
		// 組成 JSON 資料
		LoginRequest requestData = new LoginRequest
		{
			account = account,
			password = password
		};
		string json = JsonUtility.ToJson(requestData);

		// 建立 POST 請求
		UnityWebRequest www = new UnityWebRequest(svUrl, "POST");
		byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(json);
		www.uploadHandler = new UploadHandlerRaw(bodyRaw);
		www.downloadHandler = new DownloadHandlerBuffer();
		www.SetRequestHeader("Content-Type", "application/json");

		yield return www.SendWebRequest();

		// 檢查結果
		if (www.result == UnityWebRequest.Result.Success)
		{
			Debug.Log("登入成功,伺服器回應:" + www.downloadHandler.text);
		}
		else
		{
			Debug.LogWarning($"登入失敗,狀態碼: {www.responseCode}");

			switch (www.responseCode)
			{
				case 400:
					Debug.Log("請輸入帳號與密碼");
					break;
				case 401:
					Debug.Log("帳號或密碼錯誤");
					break;
				case 500:
					Debug.Log("伺服器錯誤");
					break;
				default:
					Debug.Log("未知錯誤");
					break;
			}
		}
	}

	[System.Serializable]
	public class LoginRequest
	{
		public string account;
		public string password;
	}
        private void Start()
	{
		StartCoroutine(SendLoginRequest("account", "password"));
	}


這邊分別有幾個注意的點

首先我們Function現在要模仿登入的過程,所以要傳入帳號跟密碼

當然這邊如果只是小遊戲,可以遊戲內部自己生成,並且儲存在client端就好

如果真的想要有創帳號過程則是另外的做法

不過現在多數手機遊戲依然比較傾向訪客遊玩的那種模式(同時串接例如google帳號登入等等)

那這邊也就是提供可以輕鬆調整的方式,訪客簡單的做法就是把帳號密碼改成自動生成

登入就透過自動生成的帳號去登入

這邊也有一個小提醒,就是以前常見的抓取e-mail帳號來替玩家登入的行為

現在已經是需要獲取權限才能做的事情了,所以如果想那樣做的話得注意一下

那目前的LoginRequest也就是我們server要讀取的資料

變數名稱要確保無誤,因為之後獲取數值會使用

另外網域名稱要記得填入自己的網域

接下來就可以到server的部分,我們先前創建的python檔案裏面進行調整


# 假帳號密碼(正式要改成查資料庫)
fake_users = {
    "testuser": "123456",
    "admin": "adminpass"
}

@app.route("/game_test_login", methods=["POST"])
def login():
    try:
        data = request.get_json()
        account = data.get("account")
        password = data.get("password")

        if not account or not password:
            return jsonify(success=False, message="帳號或密碼缺失"), 400

        if account in fake_users and fake_users[account] == password:
            return jsonify(success=True, message="登入成功")
        else:
            return jsonify(success=False, message="帳號或密碼錯誤"), 401

    except Exception as e:
        return jsonify(success=False, message=f"伺服器錯誤: {str(e)}"), 500



我們新增一個def login()用來處理登入

那當然正常必須從資料庫獲取真正的帳號密碼

這邊暫時先省略,我們重點先放在正確的判斷Client端給的資料,然後回傳訊息

再從Client端把資料正確的讀取出來並處理,看是要顯示給玩家看

又或是做什麼其它的處理

例如常見的登入失敗訊息,包含帳號密碼錯誤,又或是帳號不存在

看大家想要顯示什麼給玩家看

我這邊就是簡單的使用了jsonify並且帶了錯誤碼回去

可以看到我上面Unity的C#語法的部分

就是直接把www.responseCode的部分拿出來判斷

這邊就對應Server的後面帶的數值

可以很方便的去處理各種不同的狀況來顯示給玩家看

那兩邊都修改完之後我們就可以開始來測試了

主要就是執行python檔案就可以測試了

這邊看是要使用先前透過service的方式重啟,又或是直接執行python檔案都可以

sudo systemctl restart 你的服務名稱.service

又或是
python3 你的腳本名稱.py(好像要補上app.run的部分)
當然這邊要記得把你修改好的腳本同步到伺服器上
那接下來就可以進行Unity端的測試了
直接按下play
首先確認log訊息
應該就能看到目前執行登入會失敗
並且能收到帳號密碼錯誤的錯誤碼401
因為我們先前故意打錯了帳號密碼
可以回到上面看到C#程式碼的部分

StartCoroutine(SendLoginRequest("account", "password"));

這邊的account跟password就是要輸入帳號密碼的地方

接下來我們為了測試正確的結果

先把它改成正確的帳號密碼

正確的帳號密碼可以看到server的python檔案那邊

fake_users = {

    "testuser": "123456",

    "admin": "adminpass"

}

我們定義了這個

就可以看到目前有兩組正確的帳號密碼

可以隨便拿一組來用

所以就會變成這樣

StartCoroutine(SendLoginRequest("testuser", "123456"));


這樣子從unity那邊play測試

應該就能收到登入成功的訊息了~

那這次主要就分享到這邊,我們已經可以正確的透過POST封包到server進行處理了


感謝大家的觀看,如有疑問都可以發問,又或是有什麼講錯的地方請指正,感謝~




留言