跳到主要內容

精選

對於玩家們常會說的「懷念以前的遊戲」甚至覺得以前的遊戲比較好玩觀點與AI進行探討part1

 接下來針對一些玩家對於很多遊戲習慣會說的以前“ 遊戲比較好玩 ”這點來進行相關的提問 當然我知道我這提問只是一個面向,不過可以看看AI是如和回應的 問題: 有時候,對於遊戲玩家中很常見的一些說法,也覺得有點矛盾,感覺很多人似乎並不是真的理解自己在說些什麼。   像是常常有很多人都喜歡說什麼「懷念以前的遊戲」,或是覺得以前那樣在遊戲中可以做自己想做的事情,覺得很棒,認為現在的遊戲怎麼都只有唯一解,或是只有少數的流派之類的。   但是實際上拆解開來看,以前的遊戲,單純只是因為那時候大家沒有在查攻略玩遊戲而已,難道不是這樣嗎?如果你那時候去查了攻略,不就會發現更好練或是更強的方式,然後就會發現自己在做傻事,結果就是改變自己的玩法。   所以,只要你現在玩家玩新遊戲的時候也都不要查攻略,那你怎麼會覺得只有唯一解?這觀點本身就是有問題的啊。 就是因為你去查了攻略,發現有更好練或是更強的方法,才反而覺得是唯一解不是嗎?   因為照那樣的說法成立,其實現在的新遊戲就不應該開放大家討論,也不要有相關的討論版,任何問那個遊戲的文章都要刪掉,這樣大家就會回到以前那種遊玩模式。 但是,難道大家會想要這樣玩遊戲嗎? 其實現代的遊戲玩家根本就不想那樣玩遊戲啊,結果他們自己的行為根本就是矛盾的,卻整天只會做這種膚淺的言論來抱怨。   如果真的想要玩到更好玩的遊戲,我其實真的覺得,玩家自己本身也是可以提升,甚至帶動整個風氣一起提升不是嗎?而不是只會做那種膚淺的抱怨,卻完全沒說到真正的點上吧。 --- 回應: 「以前遊戲比較自由」這句話,問題出在哪? 你點到一個關鍵: 以前不是沒有唯一解,而是「大家不知道唯一解在哪」 。 為什麼以前看起來比較自由? 沒有現在這麼即時、完整的攻略 沒有 YouTube、Wiki、Discord 秒解 資訊流通慢,玩家彼此之間是「局部知識」 所以結果是: 每個人玩法都不一樣 很多「其實很爛但當下覺得OK」的玩法能存活 玩家會把「不知道更好的解法」誤認成「設計上的自由」 但只要 當年有完整攻略 ,會發生什麼事? 大家一樣會改玩法,一樣會往效率最高的方向靠。 你說得沒錯: 一旦你知道有更快、更強、更省的方式,繼續用...

遊戲伺服器2025年初架設與研究part5結合Unity的Client端發送POST來讓Server對應資料記錄到資料庫或更新資料庫

 那根據先前的測試

已經可以讓伺服器開機的時候自動啟用指定的腳本(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的資料
同樣的也能測試如果同一個玩家啟動第二次是否能正確覆寫資料
正確邏輯應該要會找到同一筆玩家的資料庫資料進行後面的資料更新
如果寫入了一筆新的資料則是邏輯有誤,可以回去檢查是不是哪邊有寫錯了~

這次就先分享到這邊,如果有疑問也可以直接發問,或是有什麼想要糾正的也歡迎留言~




留言