unity webgl联机游戏【2.Python与unity通过Websocket通信图文教程】

零、常用数据类型占用字节数

  • bool - 占用1个字节,用于存储真(true)或假(false)值。
  • byte - 占用1个字节,表示无符号的8位整数,范围从0到255。
  • char - 占用2个字节,表示一个Unicode字符。
  • short - 占用2个字节,表示有符号的16位整数,范围从-32,768到32,767。
  • int - 占用4个字节,表示有符号的32位整数,范围从-2,147,483,648到2,147,483,647。
  • long - 占用8个字节,表示有符号的64位整数,范围从-9,223,372,036,854,775,808到9,223,372,036,854,775,807。
  • float - 占用4个字节,表示单精度32位IEEE 754浮点数。
  • double - 占用8个字节,表示双精度64位IEEE 754浮点数。

一、Unity数据发送

1. String类

ws.Send(Encoding.UTF8.GetBytes("需要发的字符串"));

2. Int类

  • 如果你的Int数据有包含负数或>255,需要包含4个字节,即通过int32进行发送,这时候就要用到BitConverter
int data=1000;
byte[] sendData = BitConverter.GetBytes(data);
ws.Send(sendData);
  • 如果你要发送的Int始终不大于255,那可以节省一下,直接强制转化为byte
int data=1;
byte[] sendData = new byte[1];
sendData[0]=(byte)data;
ws.Send(sendData);

3. bool、float、double

  • 均可用BitConverter.GetBytes()进行序列化

4. 数据连接

Buffer.BlockCopy(A, 0, B,X,A.Length );
  • 这表示从B中的X位开始,把A添加到B上
  • 完整实例如下:
// 要发送的数据1
int intData=1000;
byte[] intDataByte= BitConverter.GetBytes(intData);

// 要发送的数据2
float floatData=100.0;
byte[] floatDataByte= BitConverter.GetBytes(floatData);

// 要发送的所有数据
byte[] sendData= new byte[8];
Buffer.BlockCopy(intDataByte, 0, sendData, 0, 4);
Buffer.BlockCopy(floatDataByte, 0, sendData, 4, 4);

ws.Send(sendData);

二、Python数据接收解码

import asyncio
import websockets
import struct

async def echo(websocket):
    try:
        async for data in websocket:
            print(data)
    except websockets.exceptions.ConnectionClosed:
        print("连接已关闭")
async def main():
    async with websockets.serve(echo, "0.0.0.0", 80):
        await asyncio.Future()
asyncio.run(main())


这是上一章中的代码,值得注意的是,这个代码是异步的,可以同时处理多个WebSocket连接。其中Data接收的是原始数据,需要对其进行反序列化。

  • python反序列化可以通过struct.unpack()实现
intData = struct.unpack('i', data[:4])[0]
  • 如上面这段代码对unity发送的数据进行了反序列化,具体功能是:取出数据包前四个字节,然后反序列化为int类型的数据
  • 其中的第一个参数是表示需要解包成什么数据,fmt表如下在这里插入图片描述
  • 当然如果你用单个字节传的数据,也可以直接强制转化,比如:假设我直接用byte传了个int类型的数据:PlayerId=1
PlayerId=int(data[0])

三、Python数据发送

通过await websocket.send()语句发送

1. 序列化

  • 和接收类似,直接用struct.pack()即可
  • 例如我要发送一个int类型的数据
data=1
sendData=struct.pack('i',data)
await websocket.send(sendData)

2. 数据连接

  • 如果你的数据存在一个数组内,可以通过.join直接连接发送
data=[b'1',b'2']
concatenated_data = b''.join(data)
await websocket.send(concatenated_data)
  • 如果不是,可以通过+=实现
data=b'1'
concatenated_data=b''
concatenated_data+=data
await websocket.send(concatenated_data)

四、unity接收

  • Unity的接收在 ws.OnMessage += (byte[] msg) =>{}内,msg就是收到的原始数据
  • 值得注意的是当msg没有被访问完时,又收到了下一帧数据,就会有报错:An exception has occurred during an OnMessage event.;而且这个时候你的回调里会有一些程序没有被执行,所以尽量不要在这个回调里做一些耗时运算,比如查找游戏对象等等;

反序列化

其中A表示从msg中的第几位开始读取

  • int型
int data=BitConverter.ToInt32(msg, A);

如果是用单字节传递的,也可以使用(int)

int data=(int)msg[A];
  • float型
float data=BitConverter.ToSingle(msg,A);
  • bool型
bool data=BitConverter.ToBoolean(msg,A);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小羊君爱摸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值