凌峰创科服务平台

Unity3D如何用Python搭建服务器?

客户端-服务器模型

这个架构的核心思想是:

Unity3D如何用Python搭建服务器?-图1
(图片来源网络,侵删)
  • Unity 客户端 (C#): 负责所有的游戏逻辑、渲染、用户交互,它作为“客户端”,主动向“服务器”发起请求(登录、获取排行榜、上传玩家行为数据)或接收服务器的推送(实时聊天、排行榜更新)。
  • Python 服务器: 负责处理业务逻辑、数据持久化、数据库交互、运行复杂的 AI/ML 模型等,它不关心图形渲染,只专注于数据和逻辑。

两者之间通过网络进行通信,使用一种“语言”来互相传递消息,这种语言就是 API (Application Programming Interface),最常用的是 HTTP APIWebSocket


第一步:选择通信协议

根据你的游戏需求,选择合适的协议至关重要。

HTTP / REST API (最常用)

这是最传统、最标准的通信方式,适用于 请求-响应 模型,即客户端发一个请求,服务器处理完后再返回一个响应。

  • 优点:
    • 简单易懂: 非常成熟,有大量工具和文档。
    • 无状态: 每个请求都是独立的,易于扩展。
    • 穿透性强: 几乎所有防火墙都允许 HTTP/HTTPS 流量。
  • 缺点:
    • 非实时: 服务器无法主动向客户端推送消息,客户端必须不断地轮询服务器来获取更新,效率低下。
  • 适用场景:
    • 玩家登录/注册
    • 获取静态数据 (如:游戏配置、物品列表)
    • 提交分数/保存游戏进度
    • 排行榜 (定时更新)
    • 排行榜 (实时更新)

WebSocket (实时通信)

WebSocket 在连接建立后,会保持一个全双工的通信通道,这意味着服务器和客户端可以 随时向对方主动发送消息,无需客户端轮询。

Unity3D如何用Python搭建服务器?-图2
(图片来源网络,侵删)
  • 优点:
    • 真正的实时: 低延迟,服务器可以即时推送消息。
    • 高效: 避免了 HTTP 的头部开销,持续连接适合频繁数据交换。
  • 缺点:
    • 复杂度较高: 需要维护一个长连接,处理连接的建立、断开、重连等逻辑。
    • 穿透性: HTTP/HTTPS 端口没问题,但有些企业防火墙可能会阻止非标准的 WebSocket 端口。
  • 适用场景:
    • 实时多人游戏 (如:位置同步、状态同步)
    • 实时聊天系统
    • 实时排行榜更新
    • 在线对战

第二步:技术选型与实现

我们将分别针对 HTTP 和 WebSocket,给出 Unity 和 Python 的具体实现方案。

HTTP / REST API

Unity (C#) 客户端

Unity 有多种方式发送 HTTP 请求,推荐使用现代的 UnityWebRequest

安装依赖 (推荐): 为了更方便地处理 JSON,建议使用 Newtonsoft.Json (也叫 Json.NET)。

  • 在 Unity 中,打开 Package Manager (Window > Package Manager)。
  • 点击 号,选择 Add package from git URL...,输入 com.unity.newtonsoft-json 并安装。

创建一个简单的 API 客户端工具类:

Unity3D如何用Python搭建服务器?-图3
(图片来源网络,侵删)
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using Newtonsoft.Json; // 需要先安装 Newtonsoft.Json
public class ApiClient : MonoBehaviour
{
    // 服务器的地址
    private string baseUrl = "http://localhost:5000/api"; // 假设Python服务器运行在本地5000端口
    // 示例:获取玩家数据
    public void GetPlayerData(string playerId, System.Action<PlayerData> callback)
    {
        StartCoroutine(GetPlayerDataRoutine(playerId, callback));
    }
    private IEnumerator GetPlayerDataRoutine(string playerId, System.Action<PlayerData> callback)
    {
        string url = $"{baseUrl}/players/{playerId}";
        using (UnityWebRequest request = UnityWebRequest.Get(url))
        {
            yield return request.SendWebRequest();
            if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
            {
                Debug.LogError($"Error: {request.error}");
                callback(null);
            }
            else
            {
                // 将返回的JSON字符串反序列化为C#对象
                string json = request.downloadHandler.text;
                PlayerData data = JsonConvert.DeserializeObject<PlayerData>(json);
                callback(data);
            }
        }
    }
    // 示例:上传玩家分数
    public void PostScore(string playerId, int score, System.Action<bool> callback)
    {
        StartCoroutine(PostScoreRoutine(playerId, score, callback));
    }
    private IEnumerator PostScoreRoutine(string playerId, int score, System.Action<bool> callback)
    {
        string url = $"{baseUrl}/scores";
        // 创建一个包含数据的对象
        var scoreData = new { player_id = playerId, points = score };
        string json = JsonConvert.SerializeObject(scoreData);
        using (UnityWebRequest request = UnityWebRequest.Post(url, json, "application/json"))
        {
            yield return request.SendWebRequest();
            if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
            {
                Debug.LogError($"Error: {request.error}");
                callback(false);
            }
            else
            {
                Debug.Log("Score posted successfully!");
                callback(true);
            }
        }
    }
}
// 用于接收JSON数据的C#类
[System.Serializable]
public class PlayerData
{
    public string id;
    public string name;
    public int level;
}

Python 服务器

Python 有非常流行的 Web 框架,如 Flask (轻量级) 和 FastAPI (现代、高性能),这里推荐 FastAPI,因为它:

  • 性能极高 (基于 Starlette)
  • 自动生成交互式 API 文档 (Swagger UI)
  • 内置数据验证和序列化 (使用 Pydantic)

安装 FastAPI 和 Uvicorn:

pip install fastapi "uvicorn[standard]"

创建一个简单的服务器 server.py:

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Optional
# 创建 FastAPI 应用实例
app = FastAPI()
# --- 数据模型 ---
# Pydantic 模型用于请求数据的验证和响应的序列化
class PlayerData(BaseModel):
    id: str
    name: str
    level: int
class Score(BaseModel):
    player_id: str
    points: int
# 模拟一个数据库
players_db = {
    "player1": PlayerData(id="player1", name="Alice", level=10),
    "player2": PlayerData(id="player2", name="Bob", level=5)
}
scores_db = []
# --- API 端点 ---
# GET /api/players/{player_id} - 获取单个玩家数据
@app.get("/api/players/{player_id}", response_model=Optional[PlayerData])
async def get_player(player_id: str):
    if player_id in players_db:
        return players_db[player_id]
    raise HTTPException(status_code=404, detail="Player not found")
# POST /api/scores - 提交分数
@app.post("/api/scores")
async def post_score(score: Score):
    # 在真实应用中,这里会保存到数据库
    scores_db.append(score)
    print(f"Received score: Player {score.player_id} scored {score.points} points.")
    return {"message": "Score posted successfully!"}
# 运行服务器:
# 在终端执行: uvicorn server:app --reload
# --reload 参数会在代码改变时自动重启服务器

运行服务器: 在终端中,进入 server.py 所在目录,运行:

uvicorn server:app --reload --host 0.0.0.0

--host 0.0.0.0 允许局域网内的其他设备(如你的手机或另一台电脑)访问服务器。


WebSocket

Unity (C#) 客户端

Unity 没有内置的 WebSocket 客户端,需要使用第三方库,推荐使用 WebSocket-SharpNativeWebSocket

安装 NativeWebSocket (推荐,更现代):

  • 在 Unity Package Manager 中,点击 -> Add package from git URL...,输入 com.neuecc.unirx (先安装 UniRx,NativeWebSocket 依赖它)。
  • 再添加 com.neuecc.nativewebsocket

创建 WebSocket 客户端脚本:

using UnityEngine;
using UniRx;
using NativeWebSocket;
public class WebSocketClient : MonoBehaviour
{
    private WebSocket websocket;
    async void Start()
分享:
扫描分享到社交APP
上一篇
下一篇