最近项目上用unity发布webgl,有连接数据库的要求。webgl在连接数据库方面不太友好,开始思路是写一个webservice后台服务接口进行读写数据库,然后webgl调用,,这个方法虽然实现了,但是在布置到服务器时问题比较多(同源策略等),还需要占用服务器两个端口发布两次。之后在网上搜索了一番,总结出了以下asp网页+JavaScript+webgl的一体化解决方案。本文就是介绍asp网页JavaScript、webgl三者如何实现相互通讯。
1、webgl调用JavaScript
unity原先用Application.ExternalCall()直接在代码中就可以调用 网页中JavaScript脚本,新版改版后弃用改为使用jslib文件。
使用方法,用txt创建文件,文件名为MyJs(名字自己随意),后缀名为jslib。然后这个文件必须放在Unity项目的Plugins文件夹下!
MyJs.jslib代码如下:
mergeInto(LibraryManager.library,
{
Hello: function ()
{
window.alert("Hello, world!");
},
HelloString: function (str)
{
//传入字符串要Pointer_stringify处理
window.alert(Pointer_stringify(str));
},
HelloFloat: function ()
{
return 1;
},
HelloString2: function (str)
{
//返回字符串要按以下处理
var returnStr = Pointer_stringify(str);
var bufferSize = lengthBytesUTF8(returnStr) + 1;
var buffer = _malloc(bufferSize);
stringToUTF8(returnStr, buffer, bufferSize);
return buffer;
},
});
接下来我们创建c#调用代码test.cs,把脚本挂在GameObject上
test.cs代码:
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
public class test : MonoBehaviour
{ // Use this for initialization
[DllImport("__Internal")]
private static extern void Hello();
[DllImport("__Internal")]
private static extern void HelloString(string str);
[DllImport("__Internal")]
private static extern float HelloFloat();
[DllImport("__Internal")]
private static extern string HelloString2(string str);
void Start()
{
Hello();
HelloString("Hello ");
float f= HelloFloat();
string t= HelloString2("unity string");
}
}
特别注意:
unity传到jslib的string要经过Pointer_stringify()处理才能正常使用;
jslib返回unity的string也要经过下面代码处理才能正常返回:
var returnStr = Pointer_stringify(str);
var bufferSize = lengthBytesUTF8(returnStr) + 1;
var buffer = _malloc(bufferSize);
stringToUTF8(returnStr, buffer, bufferSize);
return buffer;
2、JavaScript调用webgl
jslib不能直接调用webgl中的方法,要通过HTML中的JavaScript函数调用
jslib代码:
mergeInto(LibraryManager.library, {
Hello: function () {
TestSend("Hello, world!");//html文件中的js函数
},
});
html代码:
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Unity WebGL Player | XXX</title>
<link rel="shortcut icon" href="TemplateData/favicon.ico">
<link rel="stylesheet" href="TemplateData/style.css">
<script src="TemplateData/UnityProgress.js"></script>
<script src="Build/UnityLoader.js"></script>
<script>
var gameInstance = UnityLoader.instantiate("gameContainer", "Build/XXX.json", {onProgress: UnityProgress});
function TestSend(s){
gameInstance.SendMessage("Scripts","TestMethod",s);
}
</script>
</head>
<body>
<div class="webgl-content">
<div id="gameContainer" style="width: 960px; height: 600px"></div>
<div class="footer">
<div class="webgl-logo"></div>
<div class="fullscreen" onclick="gameInstance.SetFullscreen(1)"></div>
<div class="title">XXX</div>
</div>
</div>
</body>
</html>
webgl 3d物体Scripts上的代码:
using UnityEngine;
using UnityEngine.UI;
using System.Runtime.InteropServices;
public class WebCommunication : MonoBehaviour
{
//引用jslib的Hello()方法
[DllImport("__Internal")]
private static extern void Hello();
//测试UI,我们的目的是用jslib的Hello()方法调用网页的js方法。然后用js方法调用Unity方法。
//这样就完成了Unity和网页中的方法互相调用。最后MyText会显示Hello, world!
public Text MyText;
void Start()
{
//我们程序一开始就调用jslib的方法Hello()
Hello();
}
//测试 网页调用此方法
public void TestMethod(string text) {
MyText.text = text;
}
}
以上三个文件配合使用,实现过程为webgl调用jslib中的Hello()方法->html中的TestSend()->webgl物体代码中的TestMethod(string text);最终MyText显示"Hello, world!"。
以上参考原文链接:
3、asp后台调用JavaScript
把webgl包含到asp中,方法参见Unity3D发布WebGL(网页)到IIS服务器并加入ASP.NET页面中 html代码:
<head runat="server">
<script type="text/javascript" >
function test(str)
{
alert(str);
}
</script>
</head>
在asp网页中加一个按钮,添加事件代码:
protected void Button1_Click(object sender, EventArgs e)
{
//调用html中test
Page.ClientScript.RegisterStartupScript(this.Page.GetType(), "", "<script language='javascript'>test('string');</script>", false);
}
参考原文链接:Asp.Net 如何调用js中的函数function ?
4、JavaScript调用asp后台函数
JavaScript调用ASP.Net页面中的方法 :创建一个公有方法test(string str)声明为static,添加【WebMethod】属性,页面中添加ScriptManager控件并把EnablePageMethods属性设置为true,用 PageMethods.方法名(param1,param2,…,callbackFunction)调用该方法,js函数需要指定callbackFunction回调方法。
js代码:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<script type="text/javascript">
function ShowName(str) {
PageMethods.test(str, onSayHelloSucceeded);
}
function onSayHelloSucceeded(result)//绑定的回调函数
{
alert( result);
}
</script>
<div style="width: auto; height:auto; margin: 0px 0px 0px 0px;background-image:url('02.jpg');background-repeat:no-repeat; ">
<input type="button" runat="server" onclick="ShowName('555')">点我!</input>
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="True"></asp:ScriptManager>
</div>
</body>
</html>
c#代码:
using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Web.Services;//添加web服务引用
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod]//标示为web服务方法属性
public static string test(string str)//只能是静态的
{
return str;
}
}
在blic static string test(string str)函数中我们就可以实现对数据库,页面cookie,session等webgl无法实现的功能进行实现了。
参考原文链接:C#和JavaScript交互(asp.net前台和后台互调)总结