WebGL关于网页端与U3D互动的传值方法

WebGL关于网页端与U3D互动的传值方法

本帖最后由 sconi 于 2017-2-16 09:47 编辑

因工作需要,所以对WEBGL进行了研究,期间遇到了挺多坑。所以针对我所遇到的坑,来做个总结。

这是我第一次发布教程类文章,所以如果有遗漏或没说清楚的地方,请留言告诉我。我也是刚刚研究,所以我无法讲清楚其中原理,所以只能写一些解决的方法,和心得体会。

测试环境:

系统:Windows7旗舰版SP1
HTTP服务器:Nodejs //可选服务器,浏览器也可直接运行。
U3D版本:.5.0f3
浏览器:火狐51.0.1 (32 位)
语言:c# javascript html

一个DEMO:
http://hecom.in/lab/webgl-chat/

实现方法:
首先发布Webgl,需要下载的支持组件,自动下载。
WebGL关于网页端与U3D互动的传值方法_第1张图片

123.gif (90.54 KB, 下载次数: 0)

下载附件  保存到相册

2017-2-15 18:22 上传



安装完毕后,即可发布WebGL版本了。
我第一次发布的时候遇到了错误,没有查询到有用的资料,后来谷歌也无果。无奈,就将所有脚本剪切出项目,排除脚本问题,发现可以发布,于是再将脚本分批导入,排查。发现在原项目中使用了Forms控件,应该是Windows控件造成的。using System.Windows.Forms;//控件本身没有问题,注释相关函数即可生成WebGL。
这是遇到第一个问题,原因应该是U3D的WebGL不支持Forms控件,想想也对。

发布是很简单的,但原项目Mysql不能读取,国内无法获取到有用的信息,谷歌查找资料,发现WEBGL不支持直连数据库,这耗费了我一天的时间。
查找资料的结果是要通过WEB端获取数据库的值,传值给U3D执行。
大致的流程是 Mysql->Web->Javascript-> 。
通过谷歌找到一个日本开发者的博客,非常详实的介绍了WebGL
博客地址:http://tips.hecomi.com/entry/2014/12/08/002719

解决的办法:
这是WEB端的代码,通过JavaScript传值给U3D。
在U3D生成的index.html复制一份,改个名字,这样新生成的就不会覆盖修改后的了。
WEB端代码(基本是最小WEBGL框架了):

[HTML] 纯文本查看 复制代码
?
 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
< html >
 
     < head >
         < meta charset = "UTF-8" >
         < title >测试Uweb title >
         < script src = "TemplateData/UnityProgress.js" > script >
         < link rel = "stylesheet" href = "TemplateData/style.css" >
         < link rel = "shortcut icon" href = "TemplateData/favicon.ico" />
         < style type = "text/css" >
             .Main {
                 width: 100%;
                 height: 100%;
             }
             
             .MainLeft {
                 width: 200px;
                 float: left;
             }
             
             .MainRight {
                 width: 800px;
                 height: 600px;
                 float: right;
             }
         style >
     head >
 
     < body >
        
         < div class = "Main" >
             < div style = "font-size: 18px;text-align: center;" >
                 < h3 >WebGL-测试 h3 >
             div >
             < div class = "MainLeft" >
                 < div >
                     < form >
                         < div >
                             < label >字符串数据 label >
                             < input type = "text" value = "1" id = "storeID" placeholder = "测试数据" >
                         div >
                         < button type = "button" >提交 button >
                     form >
                 div >
             div >
             < div class = "MainRight" >
                 < canvas class = "emscripten" id = "canvas" style = " height: 500px;width: 600px;margin: 0;padding: 0;display: block;" > canvas >
             div >
         div >
         < div style = "font-size: 18px;text-align: center;" >
             < h3 >By Code Sconi h3 >
         div >
         div >
     body >
    
     < script type = "text/javascript" >
         //按钮点击事件id为print()
         function print() {
             //获取ID名为storeID的Value的值,赋值给sID
             var sID = document.getElementById("storeID").value;
             console.log(sID);
             //传参到U3D场景内Button挂载脚本的OnClickText函数,参数为一个字符串
             SendMessage("Button", "OnClickText", sID);
         }
     script >
    
     < script type = 'text/javascript' >
         var Module = {
             TOTAL_MEMORY: 268435456,
             errorhandler: null, // arguments: err, url, line. This function must return 'true' if the error is handled, otherwise 'false'
             compatibilitycheck: null,
             backgroundColor: "#ffffff",
             splashStyle: "Light",
             dataUrl: "Development/public.data",
             codeUrl: "Development/public.js",
             asmUrl: "Development/public.asm.js",
             memUrl: "Development/public.mem",
         };
     script >
    
     < script src = "Development/UnityLoader.js" > script >
 
html >

SendMessage是WEBGL的通信方法,其结构为:SendMessage(“场景内物体名”,”挂载脚本内函数名”,参数);。

这样就将Input输入的内容传值到,U3D场景内的一个名称为“Button”的游戏物体,挂载的脚本内名为“OnClickText”函数,其参数为Input的值。

如果不写参数,那么会直接执行指定的函数。

Html和JavaScript的教程可以到:http://www.runoob.com/ 菜鸟教程网站获取。


接下来是U3D端的代码:

[C#] 纯文本查看 复制代码
?
 
01
02
03
04
05
06
07
08
09
10
11
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class TestClickShell : MonoBehaviour {
     public Text WebText;
     public void OnClickText( string abc)
     {
         WebText.text = abc;  //在U3D的ugui的WebText上显示传值进来的字符串
     }
}

这样就将abc的值传递到U3D的函数内,并执行函数了。就可以通过WEB端的按钮来控制u3d场景的变化。

但我要做到的是要传递多个参数到U3D,所以这个方法要扩展一下,不假思索我首先尝试了这个:
[JavaScript] 纯文本查看 复制代码
?
 
SendMessage( "Button" , "OnClickText" ,abc,12);

和这个:
[JavaScript] 纯文本查看 复制代码
?
 
SendMessage( "Button" , "OnClickText" ,abc+12);

U3D:
[C#] 纯文本查看 复制代码
?
 
public void OnClickText( string abc, int number);

提示如下错误:
Failed to call function OnClickText of class TestClickShell Calling function OnClickText With1 parameter but the function requires 2.
函数需要2个参数,只传递了一个参数,错误;

又试了好多方法,都不行。

如果成功就见鬼了,所以我没搞清原理,就想当然了,于是翻山越岭找到一篇美帝的博客:http://www.feedingedge.co.uk/blog/2011/03/09/browser-to-unity3d-communication-and-back-again/

文章说,U3D只接受一个字符串(我试了Int也行),但只接收一个。

该博文还介绍了如何用分隔符来获取多个数值,找到宝藏了,于是修改为:

Javascript的传值方法:(替换HTML内的js代码,值的获取对照复制即可)
[JavaScript] 纯文本查看 复制代码
?
 
SendMessage( "Button" , "OnClickText" ,abc+ '~' +abc+ '~' +abc);
通过建立分割符来分割不同参数,用连接串将不同参数连接起来。

U3D的接收方法:
U3D的c#函数只能接收一个字符串参数。
通过建立数组,使用自建分隔符str.Split(‘~’); 来,获取到多个数值。

[C#] 纯文本查看 复制代码
?
 
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class TestClickShell : MonoBehaviour {
public Text textGo;
public Text intGo;
public Text floatGo;
public void OnClickText( string str)
    {
      string [] words = str.Split( '~' );
      textGo.text = words[0];
      intGo.text = words[1];
      floatGo.text = words[2];
    }
}


OK这样,多值传递也可以了,这的确用了我几天的时间,也是非常有乐趣的几天。

这实现起来是很简单的,只是官方手册和国内资料,不够详尽,始终无法理解透彻,所以我翻山越岭总算解决了这些小问题。
这是我的第一篇,希望是个好的开端,我认为我说的一些可能不那么专业,但我尽力了。

你可能感兴趣的:(技术方案)