关于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是参数 
下面是个例子:

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

unity端实例

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

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

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

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

unity里的方法为:

void MyFunc(string indata)
{

string[] words = indata.Split('-');

data1 = words[0];
moredata2 = words[1];
anotherpiece3 = words[2];

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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

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

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

<script type="text/javascript">
// 响应Unity的调用并接受"Hello World!" 做为参数
function MyFunction2( arg )
    {
     
        alert( arg );
    }
</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. }

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lwsas1/article/details/81033101

智能推荐

安卓系统开发下载和安装JRE-程序员宅基地

文章浏览阅读277次。在你下载和安装Eclipse之前,你必须确保在电脑上下载并安装了JavaRuntimeEnvironment(JRE)。因为Eclipse作为一个程序是由Java写成,它要求JRE来运行。如果JRE没有安装或被检测到,如果你..._安卓 安装jre环境

关于查看OCX控件接口和AdobeReader,FoxitReader在页面中展示PDF文件_foxitpdfreader control ocx-程序员宅基地

文章浏览阅读7.6k次,点赞2次,收藏3次。IE浏览器展示pdf,控件,FoxitReader,FoxitReaderOCX.ocx,classid_foxitpdfreader control ocx

hive 字符串拼接函数_hive 字符串拼接 窗口函数-程序员宅基地

文章浏览阅读10w+次,点赞4次,收藏22次。字符串拼接函数CONCAT()语法: CONCAT(string A, string B…)返回值: string说明:返回输入字符串连接后的结果,支持任意个输入字符串举例:Hive> select concat(‘abc’,'def’,'gh’) from lxw_dual;abcdefgh延伸:指定分割字符的拼接函数CONCAT_WS()_hive 字符串拼接 窗口函数

2017软考 | 正式的培训课开始之前,我该做些什么?-程序员宅基地

文章浏览阅读98次。转眼又到了2017年上半年的软考考试季(5月20日),攻克要塞(公众号ruankao580)与培训结构合作的课程马上就要开始,基于攻克要塞软考团队以往的面授经验,因此,我们就面授课正式开始之前的预习事宜给出若干建议。考点:必须知道,考试所涉及的知识点众多,因此,对考点要有一个综合性的了解,我们不建议马上打开书,而是先看知识点的分布图或翻看教程的目录,初步形成对考试范围..._培训课开始之前怎么说

计算机二级c语言考试真题及答案详解,全国计算机二级c语言考试题-程序员宅基地

文章浏览阅读1k次。在全国的计算机二级考试中,我们会遇到什么样的知识点题目呢?下面是学习啦小编给大家整理的计算机二级c语言考试题目及答案,供大家参阅!计算机二级c语言考试选择题1.下列数据结构中,属于非线性结构的是(  )。A.循环队列B.带链队列C.二叉树D.带链栈2.在面向对象方法中,实现信息隐蔽是依靠(  )。A.对象的继承B.对象的多态C.对象的封装D.对象的分类3.对于循环队列,下列叙述中正确的是(  )。..._下选项中,能用做用户标识符的是( ).【2009年9月】 [单选题] avoidb8_8c_0_d

VFH & VFH+ & VFH*—— Path Planning_matlab vfh算法 路径规划 矢量场直方图-程序员宅基地

文章浏览阅读4.3k次,点赞11次,收藏40次。版权声明:本文为博主原创博文,未经允许不得转载,若要转载,请说明出处并给出博文链接 最近在学习VFH算法,感觉蛮神奇,特意从维基百科扒来了资料,供学习研究。。。 在机器人技术中,Vector Field Histogram(VFH,向量场直方图)是Johann Borenstein和Yoram Koren在1991年提出的一种实时路径规划算法。VFH通过所谓的直方图网格利用机器人环境的统计表示,因此非常重视处理来自传感器和建模误差的不确定性。与..._matlab vfh算法 路径规划 矢量场直方图

随便推点

web 登录oracle数据库服务器,从数æ�库中è¿é— Web æœ�务-程序员宅基地

文章浏览阅读2.2k次。打开一个 DOS 窗å�£ï¼Œè¾ç½ CLASSPATH 环境å�˜é‡�,使其包括以下内å¹ï¼š%oracle_home%\jdbc\lib\ojdbc14.jar;%oracle_home%\jdbc\lib\orai18n.jar;%oracle_home%\sqlj\lib\translator.jar;%oracle..._è é— androeed.cn ¥ è é 6

IDEA中Debug的各种按钮怎么用_idea 新版调试框按钮变3个了-程序员宅基地

文章浏览阅读250次。IDEA中Debug的各种按钮怎么用对于我们的日常开发,很多时候都会用到debug这个功能,通过该功能我们可以看到代码的执行流程,看到每段代码的参数,同时该方法也有利于我们进行源码的阅读,不过对于小白来说,很多时候看不懂debug的标志本章使用的idea开发工具为2019.2.3版本Debug中的标志含义Debug的优化设置进行如下设置更加节省内存空间Setting -> Build,Execution,Deployment -> Debugger拓展知识在我们进行debug_idea 新版调试框按钮变3个了

RHCE考试--05、使用 Ansible Galaxy 安装角色_ansible-galaxy install -r requirements.yml-程序员宅基地

文章浏览阅读140次。使用 Ansible Galaxy 和要求文件 /home/greg/ansible/roles/requirements.yml。http://materials/haproxy.tar 此角色的名称应当为 balancer。http://materials/phpinfo.tar 此角色的名称应当为 phpinfo。_ansible-galaxy install -r requirements.yml

Spring中JDK动态代理和CGLIB动态代理的性能比较-程序员宅基地

文章浏览阅读141次。新项目开始之前领导让研究下公司原有的框架(基于struts1.2.9+spring2.0.6),比较古老了。读service基类时发现竟然将request穿透到了service层(request为BaseService的实例变量),这样service就变成了有状态Bean,使service层变成了非线程安全,导致用Spring容器管理service的时候不得不使用prototype的sco..._springboot 2.* 动态代理速度比较

window服务器环境将springboot项目 jar包注册成一个window服务自启动_springboot windows注册服务-程序员宅基地

文章浏览阅读1.6k次。window服务器环境将springboot项目 jar包安装成一个window服务自启动_springboot windows注册服务

北京科技大学计算机实践报告,北京科技大学计算机实践报告附加资料-Book5-程序员宅基地

文章浏览阅读115次。北京科技大学计算机实践报告附加资料Excel 文档学生期末考试成绩单学号 0001 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 最高分 最低分 平均分 姓名 name1 name2 name3 name4 name5 name6 name7 name8 ..._03:0004:0005:0006:0007:0008:0009:0010:0011:0012:0013:0014:0015:00十團