那根據先前的測試
已經可以讓伺服器開機的時候自動啟用指定的腳本(py)
那某方面來說已經算是個有功能的伺服器了
接下來我們就是要來調整一下功能
讓我們的遊戲,也就是Client端可以進行連接(Client端對應Server端,也就是通常的使用者端)
稱呼的問題似乎在許多地方有不同的習慣,總之就是使用者通常能接觸到的部分
以遊戲來說就是玩遊戲的時候執行的那些應用程式,就歸類成client端
那我們接下來可以先把準備好的Unity專案打開了
當然這邊就是打開各自準備的Client端就好
即便是空的Unity專案也可以
而Unity的專案一般是透過C#來撰寫的,我這邊也會使用C#的範例
這邊單純的使用Unity預設的腳本內容來調整就好
在專案區域右鍵Create>MonoBehaviour Script
接下來取個合適的名稱來使用
由於功能單純就是傳資料給server並且收回應,所以可以取的SendMessage之類的
又或是你打算拿來登入傳訊息,也可以取的Login之類的
當然也可以當作遊戲管理器的一部分,取作GameManager
新增好C#腳本後點兩下打開
正常的話這邊專案就會替你打開Microsoft Visual Studio(如果有安裝的話)
那這邊就只是編輯軟體,所以可以打開自己習慣的編輯器就好(IDE)
如Vs code或是其它的
那Unity這邊就已經準備好了
接下來先回到伺服器那邊
跟上次類似,我們要先準備要寫入資料庫的表格
先進到我們要添加資料庫的路徑(登入對應User)
當然也可以使用先前提到的pgAdmin進行執行指令添加
例如我這邊添加的範例如下
CREATE TABLE players (
player_id SERIAL PRIMARY KEY,
username TEXT UNIQUE NOT NULL,
record1 TEXT NOT NULL,
record2 TEXT NOT NULL,
score1 BIGINT NOT NULL,
score2 BIGINT NOT NULL,
score3 BIGINT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
當然大家可以根據需求調整
主要就是表格名稱players等等會用到
那接下來就是回到先前的python腳本中開始進行撰寫
首先Sql連線,這部分也可以與上次相同就好,記得裡面的資料要替換成自己的
def get_db_connection():
return psycopg2.connect(
host="localhost",
database="use_db",
user="your_user",
password="your_password"
)
那上面該引入或是導入的也記得要補上,例如這些
from flask import Flask
import psycopg2
from datetime import datetime
接下來是我們主要的內容,也就是接收client端傳來的封包
暫定是使用POST,在我們主要的python檔案內加入以下程式碼
當然先前的sql連線也要有,那這邊要注意的也是/game_test這個雖然可以自己定義,但是等等會用到,所以要記好自己取什麼
@app.route("/game_test", methods=["POST"])
def start_player():
try:
data = request.get_json()
username = data.get("username")
record1 = data.get("record1")
record2 = data.get("record2")
score1 = data.get("score1")
score2 = data.get("score2")
score3 = data.get("score3")
created_at = datetime.now(taipei)
conn = get_db_connection()
with conn.cursor() as cur:
cur.execute(
"""
INSERT INTO players
(username, record1, record2, score1, score2, score3, created_at)
VALUES (%s, %s, %s,%s, %s, %s, %s)
ON CONFLICT (username) DO UPDATE SET
record1 = EXCLUDED.record1,
record2 = EXCLUDED.record2,
score1 = EXCLUDED.score1,
score2 = EXCLUDED.score2,
score3 = EXCLUDED.score3,
created_at = EXCLUDED.created_at
""",
(username, record1,record2, score1, score2, score3, created_at)
)
conn.commit()
conn.close()
return jsonify({"status": "success"}), 200
except Exception as e:
conn.rollback()
import traceback
traceback.print_exc()
return jsonify({"status": "error", "message":str(e)}), 500
主要我們這段程式碼就可以解析Client端傳來的資訊,並且把對應的欄位資料獲取
接下來我們要進行寫入資料庫的動作
這邊寫入則會判斷username是否存在,如果存在就"更新資料"
如果不存在,才寫入一筆新的資料
這邊添加好的python可以透過遠端丟到伺服器,用跟先前的方式更新執行,又或是新增一個新的服務來執行,或是單純用原始的方式python3去執行這個檔案
執行好之後,我們就可以回到Unity的專案這邊(Client端)
首先using的部分
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
先宣告自己網域名稱,後面連接剛剛在app.route後面接的名稱
private string serverUrl = "https://自己的網域/game_test";
接著在Start的地方加入
void Start()
{
StartCoroutine(SendStartInfo());
}
最後就是主要內容
IEnumerator SendStartInfo()
{
// 建立要送出的 JSON 字串
string jsonData =
JsonUtility.ToJson(new PlayerInfo()
{
username = "testName2",
record1 = "紀錄文字1",
record2 = "紀錄文字2",
score1 = 1234,
score2 = 2345,
score3 = 6789
});
using (UnityWebRequest www = new
UnityWebRequest(serverUrl, "POST"))
{
byte[] bodyRaw =
System.Text.Encoding.UTF8.GetBytes(jsonData);
www.uploadHandler = new
UploadHandlerRaw(bodyRaw);
www.downloadHandler = new
DownloadHandlerBuffer();
www.SetRequestHeader("Content-Type", "application/json");
yield return
www.SendWebRequest();
#if UNITY_2020_1_OR_NEWER
if (www.result ==
UnityWebRequest.Result.ConnectionError || www.result ==
UnityWebRequest.Result.ProtocolError)
#else
if (www.isNetworkError || www.isHttpError)
#endif
{
Debug.LogError("Error sending
data: " + www.error);
}
else
{
//Debug.Log("Response: " +
www.downloadHandler.text);
}
}
}
// 用來序列化成 JSON 的類別
[System.Serializable]
private class PlayerInfo
{
public string username;
public string record1;
public string record2;
public long score1;
public long score2;
public long score3;
}
那這樣我們腳本就存檔,完成
可以把它掛在任意場景物件上執行測試了~
這邊主要幾個注意的點,首先就是要用StartCoroutine來執行IEnumerator的function
另外要轉json的格式要記得加上可序列化
也就是[System.Serializable]
接下來就是看Unity執行後的結果
我們正常運作的話就可以看到在資料庫多寫入了一筆資料
並且是我們Unity裡面寫入的資料,這邊就可以替換任何大家想要讓Client端送給Server的資料
同樣的也能測試如果同一個玩家啟動第二次是否能正確覆寫資料
正確邏輯應該要會找到同一筆玩家的資料庫資料進行後面的資料更新
如果寫入了一筆新的資料則是邏輯有誤,可以回去檢查是不是哪邊有寫錯了~
這次就先分享到這邊,如果有疑問也可以直接發問,或是有什麼想要糾正的也歡迎留言~
留言
張貼留言