当前位置:   article > 正文

关于Unity 中WebGL 与Http通信_unity webgl http

unity webgl http

1;什么是Unity webGL

webGL 的编译选项允许unity发布像使用了HTML5和webGL渲染API技术来使unity程序可以跑在浏览器中的javascript 程序。想要编译和测试WebGL程序,只需要在Build Playersetting里选择WebGL编译平台即可。 
2:unity是怎么样发布为webGl程序的 
为了运行webgl,需要我们的所有代码都是采用JavaScript编写,unity使用emscripten编译器工具链交叉编译unity运行时的代码(C和C++)为asm.js JavaScript,asm.js 是一个高度优化的JavaScript子集,并且可以采用javascript 的AOT编译引擎将asm.js代码变为高性能的代码。 如果代码采用C#编译,那么unity将使用Il2CPP技术将C#代码转换为相应的的C++源文件,然后编译器使用emscripten来使C++再转为JavaScript代码。当然,这里会存在兼容性的问题。unity的webGL 程序目前在大多数的桌面浏览器中都能支持,但是移动端的目前还无法支持。 
1:,Unity并不是所有的功能都能在webGl中支持, 
首先;由于JavaScript不支持多线程,所以多线程只适用在unity内部线程对程序的加速和一些托管DLL以及使用一些线程脚本代码 ,基本上System.Threading命名空间里的东西是不支持的。 
2:webGL还无法在VS和MonoDevelop里调试 
3:由于安全问题浏览器不能直接访问IP套接字。 
4:WebGL图形API相当于OpenGL ES 2,这具有一定的局限性。 
5:WebGL生成使用自定义后台音频,基于Web Audio API。这只支持基本的音频功能 
6:WebGL是一个AOT(静态编译)平台,所以它不允许动态生成的代码中使用system.reflection.emit。这是对所有其他il2cpp平台,如iOS,和大多数控制台是相同的。 
3:浏览器的兼容情况

桌面浏览器兼容情况 
Mozilla Firefox 42 Google Chrome 46 Apple Safari 9.0 MS Internet Explorer 11 MS Edge 13 
对运行unity的webGL内容的支持能力 X (1) X (1) X (Safari 8 and higher) X (IE 11 and higher) X 
Web Audio unity WebGL中的音频需要调用Web Audio API来播放 X X X - X 
全屏支持 X X - (2) X X 
鼠标锁定支持 X X - - - (3) 
Gamepad support X X - - X 
IndexedDB Required for local storage as used by the Data Caching feature, the PlayerPrefs class, and WWW.LoadFromCacheOrDownload. X (4) X X (4) X X 
WebSockets Required for Networking. X X X X X 
WebRTC Required by the WebCamTexture class. X X - - X 
WebGL 2.0 - (5) - - - - 
asm.js AOT compilation asm.js is a susbset of JavaScript for which a browser can specifically optimize. Browsers which implement asm.js support may be able to run Unity WebGL content faster, as Unity uses asm.js. X - - - X 
Notes (6) (7)

注释: 
1:WebGL可能不支持特定的老显卡。 
2:Safari浏览器支持HTML5全屏API,但全屏模式时没有键盘输入,所以unity在Safari中运行时将禁止全屏功能。 
3:Edge不支持鼠标锁定,Edge13可能会支持。 
4:Firefox和Safari上42版本不支持在一个iframe中运行的内容IndexedDB。火狐43或更高版本将修复问题。、 
5:Firefox 支持WebGL2.0,但它默认是禁用的,需要启用:配置。 
6:Chrome可能需要大量的内存来解析生成的JavaScript代码,当在32位版本浏览器中加载webgl内容时可能会导致内存错误或崩溃。 
7:IE浏览器不支持音频并且还太慢对于加载unity的webGL内容,出于这个原因,

unity将在使用Internet Explorer打开内容时显示使用不支持的浏览器的警告 
4:webGl的发布工作

 编译一个webGL 项目时,unity将会创建一些文件
  • 1
  • 2

*一个index.html文件,这个文件可以直接使用浏览器打开,但是出于考虑,chrome限制用户从本地打开这种文件。 
*一个Development和 Release 文件夹, 这些是生成的输出文件,一个用于继续开发,一个是可以用于直接发布。 
*一个TemplateData文件夹,一些资源文件。 
发布时当勾选Development Build复选框时,unity将生成一个Development Build(带有分析器支持和错误控制台); 
此外,Development Build是非压缩的,所以生成的JavaScript是可读的并且保留了函数名(以便于你得到有用的错误堆栈跟踪)但是非常分散。 
使用Use pre-built Engine选项可用于加快开发迭代时间在开发过程中。启用此选项时,只有托管代码将被重建,然后与预构建Unity引擎动态链接,因此工程重新生成的速度会提升30%到40%。但是注意,这种编译只适合开的目的,因为这样会产生多余的引擎代码。此外,由于动态链接开销,这种编译的性能有点慢于正常编译。 
当你想配置你的unity webGL内容时必须勾选Autoconnect Profiler复选框,虽然在webGL上连接分析器使用WebSockets ,但是浏览器只允许从内容向外的连接,所以在WebGL使用Profiler的唯一方法是选中“自动连接分析器”有内容连接到编辑。 
5:webGl Graphics 
WebGL是一个浏览器的图形渲染引擎API,目前是基于OpenGL ES 2.0 图形库。Unity webGL目前只支持烘焙GL不支持实时GL,而且,仅仅支持非定向lightmaps,webGL在运行时也不支持过程化材质,过程化材质在编译时将被烘焙为普通材质。webGL 也不支持使用Movie Texture播放视频,但是你可以通过使用HTML元素在WebGL里高效的播放视频。 
6:WebGL的网络通信 
由于安全性的影响,JavaScript代码没有直接访问IP套接字来实现网络连接。因此,该.NET网络类(System.Net命名空间中的一切,特别是System.Net.Sockets)在WebGL中不能工作。UnityEngine.Network* 类也是这样,编译WebGL时将找不到这些类。如果你需要在WebGL使用网络通信,你现在可以选择使用unity的WWW 或UnityWebRequest 类或则支持webGL的新的Unity 网络通信特性。或在JavaScript中使用WebSockets或WebRTC实现你自己的网络通信。 
7:WWW 或WebRequest类的使用 
WebGl支持WWW和unitywebrequest类。他们在JavaScript里使用XMLHttpRequest类实现,使用浏览器来处理网络请求。这对访问跨域资源施加了一些安全限制。基本上对于服务器的任何WWW请求不同于托管服务器的是WebGL内容需要通过你试图访问的服务器授权。在WebGL的跨域访问WWW资源,您试图访问的服务器需要使用CORS授权。如果你使用WWW或unitywebreqest试图访问内容,但是远程服务器没有CORS系统设置或没有正确配置,你会在浏览器控制台看到类似这样的错误: 
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://myserver.com/. This can be fixed by moving the resource to the same domain or enabling CORS. 
CORS表示跨域资源共享。基本上,服务器需要向它发送的HTTP响应里添加一些访问控制头,这将告诉浏览器允许它访问服务器上的内容。这是一个控制头设置的例子,将允许unity WebGL访问来源于任何Web服务器资源,通过常见的请求头和使用HTTP GET,POST或OPTIONS方法: 
“Access-Control-Allow-Credentials”: “true”, 
“Access-Control-Allow-Headers”: “Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time”, 
“Access-Control-Allow-Methods”: “GET, POST, OPTIONS”, 
“Access-Control-Allow-Origin”: “*”,

注意,www.responseheaders限于实际响应标头的一个子集,根据7.1.1的CORS规范。还要注意XMLHttpRequest不允许使用数据流,因此WebGL的WWW类只会处理下载完成的数据(所以assestbundles不能像其他平台上那样解压和加载)。 
8:为什么需要通信 
当为web构建内容时,您可能需要与web页上的其他元素进行通信。或者您可能希望使用Unity当前不默认的Unity API来实现功能。在这两种情况下,您都需要直接与浏览器的JavaScript引擎对接。unity的WebGL提供不同的方法来实现这些。 
9:从Unity里调用JavaScript里的方法。 
你可以使用下面的代码从浏览器的JavaScript里调用unity里的方法: 
SendMessage (‘MyGameObject’, ‘MyFunction’, ‘foobar’); 
MyGameObject是场景内物体名称,MyFunction方法名,foobar是参数 
下面是个例子:

  1. <!--传值方法-->
  2. <script type="text/javascript">
  3. //按钮点击事件id为test()
  4. function test() {
  5. //获取ID名为storeID的Value的值,赋值给sparm
  6. var sparm= document.getElementById("storeID").value;
  7. //传参到U3D场景内GoName挂载脚本的MyFunc函数,参数为一个字符串
  8. SendMessage("GoName", "MyFunc", sparm);
  9. }
  10. </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

unity端实例

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. public class Test : MonoBehaviour {
  6. public Text WebText;
  7. public void MyFunc(string abc)
  8. {
  9. WebText.text = abc; //在U3D的ugui的WebText上显示传值进来的字符串
  10. }
  11. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

10:如何通过SendMessage传递多个参数 
我们知道unity的SendMessage只接受一个字符串参数,但是我们的项目经常会用到多参数,这样就很尴尬了,关于这个,目前我还没找到好的方式,只是看到大家都在使用连接多个string参数为一个字符串的形式,当然,这样也只是能传递个string参数。

  1. <!--传值方法-->
  2. <script type="text/javascript">
  3. function test() {
  4. var Parm_1= "Parm_1";
  5. var Parm_2= "Parm_2";
  6. var Parm_3= "Parm_3";
  7. //传参到U3D场景内GoName挂载脚本的MyFunc函数,参数为一个字符串
  8. SendMessage("GoName","MyFunc",Parm_1+'-'+Parm_2+'-'+Parm_3);
  9. }
  10. </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

unity里的方法为:

  1. void MyFunc(string indata)
  2. {
  3. string[] words = indata.Split('-');
  4. data1 = words[0];
  5. moredata2 = words[1];
  6. anotherpiece3 = words[2];
  7. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

11:从Unity里调用网页里的方法 
你可以使用Application.ExternalCall()和 Application.ExternalEval()函数调用嵌入网页的名为functionName的JavaScript函数,并传递给定的参数。支持原始的数据类型(string, int, float, char)和这些类型的数字。如何其他的对象被转化为字符串(使用ToString方法)并作为字符串传递。这个函数调用时不会被阻塞,即ExternalCall立即返回的功能而不必等待被完成。传递的参数数量是可变的。

  1. // 调用网页上的MyFunction1并不使用参数。
  2. Application.ExternalCall ("MyFunction1");
  3. //调用网页上的MyFunction2并使用字符串参数。
  4. Application.ExternalCall ("MyFunction2", "Hello World!");
  5. //调用网页上的MyFunction3并使用几个不同类型的参数。
  6. Application.ExternalCall ("MyFunction3", "str", 3, 5.0);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

被调用的在HTML中的函数只需要使用标准的语法即可,例如:

  1. <script type="text/javascript">
  2. // 响应Unity的调用并接受"Hello World!" 做为参数
  3. function MyFunction2( arg )
  4. {
  5. alert( arg );
  6. }
  7. </script>

Get方式:

  1. private IEnumerator SendUrl(string url)
  2. {
  3. using (UnityWebRequest www = UnityWebRequest.Get(url))
  4. {
  5. yield return www.Send();
  6. if (www.error != null)
  7. {
  8. Debug.Log(www.error);
  9. }
  10. else
  11. {
  12. if (www.responseCode == 200) //200表示接受成功
  13. {
  14. Debug.Log(www.downloadHandler.text);
  15. }
  16. }
  17. }
  18. }

Post方式:

  1. public IEnumerator PostUrl(string url, string postData)
  2. {
  3. using (UnityWebRequest www = new UnityWebRequest(url, "POST"))
  4. {
  5. byte[] postBytes = System.Text.Encoding.UTF8.GetBytes(postData);
  6. www.uploadHandler = (UploadHandler) new UploadHandlerRaw(postBytes);
  7. www.downloadHandler = (DownloadHandler) new DownloadHandlerBuffer();
  8. www.SetRequestHeader( "Content-Type", "application/json");
  9. yield return www.Send();
  10. if (www.isError)
  11. {
  12. Debug.Log(www.error);
  13. }
  14. else
  15. {
  16. // Show results as text
  17. if (www.responseCode == 200)
  18. {
  19. Debug.Log(www.downloadHandler.text);
  20. }
  21. }
  22. }
  23. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/90182?site
推荐阅读
相关标签
  

闽ICP备14008679号