一、基础知识介绍
1、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 - 项目中的资源和场景
-
2、WebSocket基础知识
二、具体功能
-
Unity接受网络传输的数据来驱动手模型
-
利用WebSocket协议
-
利用在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服务
![](https://i-blog.csdnimg.cn/blog_migrate/740bf678893b3d848b0f4c73856788e4.png)
-
服务端服务类必须要继承WebSocketBehavior
![](https://i-blog.csdnimg.cn/blog_migrate/3b603f047d47115b223ed7c68d045ddc.png)
3、Unity编写开启WebSocket客户端功能软件
![](https://i-blog.csdnimg.cn/blog_migrate/99a30c0c09331d301aab2fcdf7a6d8f0.png)
五、踩坑日志,需注意
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正常实现需求而放弃。具体原因如下:
-
Thrift需要通过线程实现,否则无法正常运行Unity工程,而WebGL不支持多线程功能。
-
UnityWebRequest是Http短连接,而要进行手势数据实时通讯需要进行IO操作,在WebGL上实现不仅会出现IO冲突问题,而且WebGL不支持IO操作。