unity3D 对接 workerman 实现联机游戏

前言:Unity3D,相信很多人都知道是用来做游戏的 。网上也有很多这类视频的教程,我也试着学习过 。但是当要实现多人实时对战的教例比较少,而用 php 来做 Unity3d 的服务器端的就更少了 。
我在网上看了一个作者用 C# 做联机服务器端的文章后,就根据他的思路改了一个 PHP 版的 。例子只是多个方块在一个场景下移动,所有玩家可以实时看到 。以下就以几个小事例简单介绍一下 PHP 与 Unity3D 通信的实现吧 。(以下的环境只做参考,其他的版本也可以)

unity3D 对接 workerman 实现联机游戏

文章插图
 
环境:1. Unity Hub 3.3.0-c1
2. Unity3D 2019
3. PHP 7.3
4. Workman 4.1
 
Workman 介绍workerman 是一款开源高性能 PHP 应用容器,他除了用于互联网、即时通讯、App 开发、硬件通讯、智能家居、物联网等领域的开发外,也可以用于游戏服务器端的开发,之前实现的一个五子棋多人联机大战虽然用的是 Swoole 。但是实现思路类似,五子棋是给同房间内的玩家更新棋子的坐标,而这里也是用于实时传递玩家的位置 。
 
实现客户端是 C#,就简单先以和服务器端连接,发送,接收做例子,进一步就是方块移动,坐标传递 。
 
1. 简单通讯
客户端只是用面板画出一个输入框 (地址) 和显示区域 (接收服务端发送的内容),而服务器端是创建 TCP 服务,接收与发送 。
(1). 客户端连接
//连接public void Co.NETion(){//清理textrecvText.text = "";//Socketsocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);//Connectstring host = hostInput.text;int port = int.Parse(portInput.text);socket.Connect(host, port);clientText.text = "客户端地址1 " + socket.LocalEndPoint.ToString();//Recvsocket.BeginReceive(readBuff, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCb, null);}(2). 客户端接收
//接收回调private void ReceiveCb(IAsyncResult ar){try{//count是接收数据的大小int count = socket.EndReceive(ar);//数据处理string str = System.Text.Encoding.UTF8.GetString(readBuff, 0, count);if (recvStr.Length > 300) recvStr = "";recvStr += str + "n";recvText.text = "接收的消息 " + recvStr;Debug.LogError("接收的消息 "+ recvStr);//继续接收socket.BeginReceive(readBuff, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCb, null);}catch (Exception e){recvText.text += "链接已断开";socket.Close();}}(3). 客户端发送
//发送数据public void Send(){string str = textInput.text;byte[] bytes = System.Text.Encoding.Default.GetBytes("test:" + str);try{socket.Send(bytes);}catch { }}2. workerman 安装
(1). 新启一个项目,进入该目录,composer require workerman/workerman
unity3D 对接 workerman 实现联机游戏

文章插图
 
(2). 创建一个 start.php
<?phpuse WorkermanWorker;require_once __DIR__ . '/vendor/autoload.php';// #### 开启TCP服务 ####$worker = new Worker('tcp://0.0.0.0:1234');// 4 processes//$worker->count = 4;// 客户端连接回调$worker->onConnect = function ($connection) {echo "New Connectionn";};// 接收客户端消息$worker->onMessage = function ($connection, $data) use ($worker) {// Send data to clientecho json_encode($data) . "n";//$ip = $connection->getRemoteIp();foreach($worker->connections as $connection){$connection->send($data);}//$connection->send("Hello $data n");};// 客户端关闭回调$worker->onClose = function ($connection) {echo "Connection closedn";};Worker::runAll();?>(3). 启动,输入 php start.php start,成功如下
unity3D 对接 workerman 实现联机游戏

文章插图
 
(4). 打开客户端的 6asyn 场景并运行,输入 TCP 服务的地址和端口
unity3D 对接 workerman 实现联机游戏

文章插图
 
(5). 点击发送,就可以查看 workerman 接收到的信息 。
unity3D 对接 workerman 实现联机游戏

文章插图
 
2. 方块移动案例
方块移动服务器端几乎不用修改,在连接成功后,将多个客户端的坐标传递到服务器端,服务器处理后再给所有连接发送坐标,客户端再将数据绘制到场景中 。
(1). 前后端数据约定
unity3D 对接 workerman 实现联机游戏

文章插图
 
POS 用于标识行为,比如 POS 为坐标移动,同理聊天可以用 IM,登陆用 LOGIN 做标识等 (攻击) 。第二个为客户端连接标识,标识往后为坐标 X, Y, Z 。


推荐阅读