我们可以使用Protobuf来实现游戏的客户端与服务端通信的数据结构定义。
编写好.proto后经过编译可以生成对应语言的代码。
然后在Unity中我们可以添加Google.protobuf
的nuget包,同时导入编译好的数据结构和ServerResponse
文件。
在服务端,不管是使用什么语言,只要能够使用protobuf
也可以实现和Unity C#通信交互。
以下为ChatGPT生成的示例
定义通信协议(.proto文件)
syntax = "proto3";
message PlayerAction {
int32 player_id = 1;
string action = 2;
float x = 3;
float y = 4;
}
message ServerResponse {
string message = 1;
}
编译.proto文件
protoc --csharp_out=./Generated PlayerAction.proto
protoc --cpp_out=./Generated PlayerAction.proto
客户端(Unity C#)实现
在Unity项目中,导入生成的Protobuf
C#文件和Google.Protobuf
库。
使用TcpClient
或WebSocket
类来建立与服务器的连接。
通过Protobuf
序列化和反序列化消息,发送和接收数据。
using Google.Protobuf;
using System.Net.Sockets;
public class GameClient : MonoBehaviour {
private TcpClient client;
private NetworkStream stream;
void Start() {
client = new TcpClient("server_ip", port);
stream = client.GetStream();
}
void SendPlayerAction(int playerId, string action, float x, float y) {
var playerAction = new PlayerAction {
PlayerId = playerId,
Action = action,
X = x,
Y = y
};
playerAction.WriteTo(stream);
}
void ReceiveServerResponse() {
var response = ServerResponse.Parser.ParseFrom(stream);
Debug.Log("Received from server: " + response.Message);
}
}
服务器端实现
在服务器端(例如使用C++或Go等),接收并解析来自Unity客户端的Protobuf
消息,并响应。
void handleClient(int clientSocket) {
PlayerAction playerAction;
playerAction.ParseFromIstream(&clientSocket);
std::cout << "Player " << playerAction.player_id() << " did " << playerAction.action() << std::endl;
ServerResponse response;
response.set_message("Action received");
response.SerializeToOstream(&clientSocket);
}
如果我们需要实现玩家本地局域网服务器的话可以将服务端内嵌到客户端中,具体实现方法可以是调用DLL文件,如果是Java可以用JNI。
使用JNI的话需要提前判断玩家的电脑中是否装有Java环境,如果没有可以提示玩家是否下载Jre,如果玩家不同意则不开放多人游戏即可。
同时你也可以将服务端打包为多个平台的可执行文件,使用System.Diagnostics.Process
启动服务器进程,但是不推荐这么干。