基于Unity通过WebSocket实现WebGL驱动手模型

一、基础知识介绍

1、WebGL基础知识

WebGL 项目打包之后,会生成如下文件结构:
  • index.html
  • TemplateData - 包括logo、加载进度条,只有模板选择 Default 时才有)
  • StreamingAssets - 项目中的 StreamingAssets 文件夹(WebGL平台下 Application.streamingAssetsPath 的值为  http://youer_host_url:port/StreamingAssets )
  • Build
    • UnityLoader.js - 加载 unity 内容的脚本
    • myproject .json - PlayerSetting 中的部分设置以及其他资源的 Url,给 UnityLoader 用的
    • myproject .wasm.framework.unityweb - JavaScript 运行时和插件
    • myproject .wasm.code.unityweb - 编译完成的 WebAssembly
    • myproject .wasm.memory.unityweb -
    • myproject .data.unityweb - 项目中的资源和场景
Build 文件夹下载 *.unityweb 文件,可能是压缩文件,由 PlayerSetting/publishing setting/Compression Format 设置。
生成完毕之后,可以用浏览器打开 index.html 文件,由于 Chrome 不允许运行本地文件,因此需要将生成文件放到 Web 服务器,或者通过 unity 的 Build And Run,unity 会在编译完成之后启动一个本机 web 服务器。

2、WebSocket基础知识

①WebSocket与http区别:
websocket 通信可由服务器发起,也可以由客户端发起。可以实现客户端与服务端长连接
http 通信只能由客户端发起。
② WebSocket 是基于TCP实现的一种协议,服务器可以主动发送给客户端数据。
③ ws为其协议简称,wss为安全的WebSocket

二、具体功能

  1. Unity接受网络传输的数据来驱动手模型

  2. 利用WebSocket协议

  3. 利用在WebGL展示

三、使用方式

1、开启WeSocket服务端(实现方式参考Server工程),端口:9091(可自定义)

2、利用网页打开WebGL,在输入框输入WeSocket服务端URL(如ws://10.79.104.187:9291/),然后点击StartWsClient开启通讯,再次点击关闭通讯。

基于Unity通过WebSocket实现WebGL驱动手模型

3、Server端发送的数据格式定义举例

将手指与手掌的数据合并为一帧数据发送,即每帧同时发送两行数据。

(详细可参考附件里的Server工程的方式,已测试ok)

例:第一帧:1 .....(手指数据) 1 .......(手掌数据)

第二帧:1 .....(手指数据) 1 .......(手掌数据)

......

四、详细实现方案

1、利用Python开启本地局域网服务器

①搭建Python开发环境

可能是全网最详细的 Python 安装教程(windows) - 知乎

按照此教程可以完美无错搭建Python开发环境

②直接利用Python命令行开启本地局域网服务器

Python 3 如何使用自带的HTTP Server-百度经验

按照此教程可以完美无错开启

命令行:ptyhon -m http.server

③开启服务器后即可登录浏览器进行登录

http://本地IP地址:8000    或者  http://localhost:8000

2、编写开启WebSocket服务端功能软件

  • GitHub - sta/websocket-sharp: A C# implementation of the WebSocket protocol client and server,里面的使用方式说得很清楚,甚至可以解决WebGL无法使用WeSocket服务端问题(关于ssl验证以及使用http代理服务器连接),参考此插件的Example实现
  • VS端利用NuGet获取WebSocketSharp插件,可引用WebSocketSharp、WebSocketSharp.Server命名空间
  • 服务端开启必须加上WebSocketService服务,此服务可以添加对应的服务路径的WebSocket服务
  • 服务端服务类必须要继承WebSocketBehavior

3、Unity编写开启WebSocket客户端功能软件

五、踩坑日志,需注意

1、由于平台限制,有些功能在 WebGL 上是不支持的:

  • 不支持多线程,因为 JavaScript 不支持多线程,所以 System.Threading 命名空间下的类不要使用;

  • 不能在 VS 中进行断点调试,可将Debug信息打印在Chrome里的调试界面查看;

  • 不能直接使用 Socket,包括 System.Net下的任何类型,以及 System.Net.Sockets 下的部分类型,以及 UnityEngine.Network,如果需要在 WebGL 平台使用网络功能,可以使用 WWW或者 UnityWebRequest这些都是基于 Http协议的实现,如要需要高实时性,可以选择 WebSockets或者 WebRTC;

2、WebSocket的服务端在WebGL上实现会有导致通讯不上,出现错误问题如下:

Windows SocketException: mono-io-layer-error (0) at System.Net.Sockets.Socket..ctor (System.Net.Sockets.AddressFamily addressFamily, System.Net.Sockets.SocketType socketType, System.Net.Sockets.ProtocolType protocolType) [0x00000] in <00000000000000000000000000000000>:0

  • 网上解决方案(比较复杂):

https://www.reddit.com/r/Unity3D/comments/kjwp55/first_time_with_unity_3d_webgl_using_clientserver/

  • 目前解决方案:将WebSocket的客户端在WebGL上实现,服务端在本机实现,这样可进行自由通讯

3、服务端通讯数据需以byte[]数据形式传送,否则Client无法正常收到。

4、为了在WebGL上实现网络通讯,先后使用过Thrift以及UnityWebRequest网络协议实现,最终都以能够在本机上正常通讯展示手模,而无法在WebGL正常实现需求而放弃。具体原因如下:

  1. Thrift需要通过线程实现,否则无法正常运行Unity工程,而WebGL不支持多线程功能。

  2. UnityWebRequest是Http短连接,而要进行手势数据实时通讯需要进行IO操作,在WebGL上实现不仅会出现IO冲突问题,而且WebGL不支持IO操作。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Unity是一款广泛使用的游戏引擎,它允许开发者将游戏导出为WebGL格式,从而可以通过浏览器进行游玩。而WebGL是一种基于JavaScript的API,可以在浏览器中渲染3D及2D图形。 WebSocket是一种在浏览器和服务器之间建立实时双向通信的协议。它使得网页可以实时地更新数据,而无需使用传统的HTTP轮询。 在使用Unity开发WebGL游戏时,可能会遇到WebSocket粘包的问题。这种情况通常发生在网络传输数据时,数据包没有被完整地传输到接收端,导致数据被拆分或者合并,从而影响游戏的表现。 为了解决WebSocket粘包的问题,可以通过以下几种方式: 1. 增加缓冲区大小:可以通过增加WebSocket的缓冲区大小来减少WebSocket粘包的发生率。 2. 将数据包分割成小块:可以将较大的数据包拆分成多个小块进行传输,这样可以减少数据包的大小,从而降低粘包的概率。 3. 使用特定的协议:开发者可以使用一些特定的协议或者框架,如protobuf或者MsgPack,这些协议可以将数据格式化,从而减少数据包的大小,同时也可以降低WebSocket粘包的概率。 综上所述,WebSocket粘包是Unity WebGL游戏开发的一个常见问题,但可以通过增加缓冲区大小、将数据包分割成小块或者使用特定的协议来解决。 ### 回答2: Unity WebGL是一种基于Web的游戏引擎,它使用WebGL技术使游戏能够在Web浏览器中运行。WebSocket是一种HTML5提供的网络通信协议,与HTTP不同的是,WebSocket建立的是一个持久化的连接,可以实现双向通信。 但是,在使用Unity WebGLWebSocket进行通信时,可能会出现粘包现象。粘包指的是在传输过程中,多个数据包被合并成一个较大的数据包,而接收端却只能对这一个较大的数据包进行处理,导致数据解析错误或出现数据丢失。 粘包的出现是由于WebSocket是基于TCP协议的,而TCP协议具有流式传输的特点,即没有边界限制。因此,在发送端连续发送多个数据包时,它们可能会依次被组成一个大数据包发送至接收端,而接收端则需要进行额外的解析和处理,才能正确获取每个数据包的信息。 解决粘包问题需要在程序设计上进行优化,可以在发送端添加边界符或长度前缀来区分每个数据包,以便接收端能够正确读取每个数据包。此外,也可以通过加密、压缩等技术来减小数据包的大小,从而减少粘包情况的发生。最好的解决方法还是在网络通信的设计过程中对TCP协议有深入的理解并且进行有效优化。 总之,对于Unity WebGLWebSocket的开发者,需要注意粘包问题的可能性,设计时应该尽可能避免此类问题的发生。 ### 回答3: Unity WebGl游戏在使用websocket时常常会出现粘包现象。websocket是一种双向通信的网络协议,与HTTP协议相比,具有更快的速度和更低的延迟,因此在实时性要求较高的游戏开发中得到了广泛应用。 WebSocket粘包是指两个或更多个数据包被粘成一个数据包,导致数据混乱或数据丢失的现象。在Unity WebGl中,Unity引擎使用websocket协议与服务器通信时,如果两个消息同时到达,则可能会发生粘包。这会导致接收方解析数据时出现意外的数据,并可能会导致游戏异常或崩溃。 为了解决这个问题,可以在每个消息之前添加一个消息头以标识消息的长度。这样一来,在接收websocket消息时,就可以首先读取消息头,得到消息的长度,然后按照消息长度读取数据,以避免粘包的问题。 另外,在编写游戏网络通信代码时,也需要注意一些细节问题,如尽量避免长时间等待服务器响应、适量分包发送数据等,这样可以有效降低websocket粘包发生的概率,提高游戏网络通信的效率和稳定性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值