Unity发布WebGL使用JavaScript交互

  大家好,我是阿赵。
  Unity可以发布WebGL,发布后是一个HTML页面。这时候,Unity内部的内容,怎样和外部的HTML页面的内容进行交互呢?
  先说一下基础知识,Unity发布的WebGL,不能直接双击打开html文件的,必须通过服务器访问。所以如果没有服务器的话,可以自己在本机搭建一个wamp之类的服务器,就可以方便调试。

一、通过C#调用页面的JavaScript方法

1、基本调用

  如果想通过C#在Unity工程内部调用页面的JavaScript方法,比如DOM或者BOM的,需要做以下几个事情。

1. 建立jslib文件

  在Unity官方文档里面可以看到,官方支持在插件文件夹里面放置jslib文件来编写JavaScript:
在这里插入图片描述
  所以我们先在Unity工程的Assets文件夹里面建一个Plugins文件,然后在里面建一个后缀名为jslib的文件,文件名都可以,主要是后缀名一定要是jslib:
在这里插入图片描述

  然后在里面编写内容:

mergeInto(LibraryManager.library, {

  Hello: function () {
    window.alert("Hello, world!");
  },

  HelloString: function (str) {
    window.alert(UTF8ToString(str));
  },
});

  这里主要是写了2个方法,第一个Hello方法,是不带参数的,直接调用的是JavaScript的alert弹窗。第二个叫做HelloString的方法,需要传入一个字符串参数,然后调用alert弹窗时把字符串传进去。
  这里可以看到了第一个需要注意的地方,在把字符串传到JavaScript的时候,需要使用UTF8ToString方法进行转换,不然JavaScript那边会收到一串数字。

2. 在C#注册方法并且调用。

  在写好了JavaScript方法之后,就需要调用这些方法。写一个继承了MonoBehaviour的脚本挂到一个物体上,比如:
在这里插入图片描述

  如果只是发送消息,其实并不是必须这样做,但为了之后能接收到从页面发送的消息,是需要使用SendMessage的,所以需要一个GameObject作为一个接收的对象。
  在这个c#脚本里面,需要先把刚才写的2个JavaScript方法给注册声明一下:

[DllImport("__Internal")]
private static extern void Hello();

[DllImport("__Internal")]
private static extern void HelloString(string str);

  这样,在调用Hello方法和HelloString方法时,就会去查找jslib里面的方法并执行。
接下来简单写个测试:

private void OnGUI()
{
    if(GUILayout.Button("test1",GUILayout.Width(200),GUILayout.Height(100)))
    {
        Hello();
    }
    if (GUILayout.Button("test2", GUILayout.Width(200), GUILayout.Height(100)))
    {
        HelloString("Hello azhao");
    }
}

  发布WebGL,拷贝到服务器,然后运行,会看到:
在这里插入图片描述

  点击test1按钮,会看到:
在这里插入图片描述

  点击test2按钮,会看到:
在这里插入图片描述

  到这里,从C#调用JavaScript方法的基础操作就完成了。

2、 调用页面本身的JavaScript方法

  刚才的例子调用的是页面JavaScript的alert弹窗方法,如果是想在页面里面写JavaScript,然后从Unity里面调用,又需要怎样操作呢?
  打开Unity发布WebGL时自动生成的index.html文件,可以看到里面有这么一个可以调用的函数:
在这里插入图片描述

  这个函数的作用是显示一个提示信息框。我们就拿这个作为例子,看看是否能从Unity里面调用到页面的JavaScript函数。

1. 在jslib文件写方法

mergeInto(LibraryManager.library, {

  Hello: function () {
    window.alert("Hello, world!");
  },

  HelloString: function (str) {
    window.alert(UTF8ToString(str));
  },

  ShowBanner:function(str,t){
    unityShowBanner(UTF8ToString(str),UTF8ToString(t));
  }
});

  新增的是ShowBanner方法,里面的内容是直接调用了页面上的JavaScript的函数unityShowBanner。注意方法之间需要用逗号分隔。这个函数需要2个参数,第一个是显示内容,第二个是显示的类型。这两个参数就在后面C#传入了,记得注意要用UTF8ToString来转换一下字符串。

2. 在C#注册方法并调用

  在刚才的C#文件里面,增加一个方法的声明:

[DllImport("__Internal")]
private static extern void ShowBanner(string str,string t);

然后增加一个测试调用:

private void OnGUI()
{
    if(GUILayout.Button("test1",GUILayout.Width(200),GUILayout.Height(100)))
    {
        Hello();
    }
    if (GUILayout.Button("test2", GUILayout.Width(200), GUILayout.Height(100)))
    {
        HelloString("Hello azhao");
    }

    if (GUILayout.Button("test3", GUILayout.Width(200), GUILayout.Height(100)))
    {
        ShowBanner("这是一个来自Unity的提示信息", "warning");
    }

}

  主要是test3的按钮,会调用ShowBanner函数,并传入值。
  发布WebGL,拷贝文件到服务器,然后运行,会看到:
在这里插入图片描述

  然后点击test3按钮,会看到:
在这里插入图片描述

  这里调用页面JavaScript里面的函数已经成功了。

3、 修改页面元素的内容和样式。

  通过Unity内部的C#控制页面的HTML元素内容和样式,可以在jslib里面写选择器来获取元素,然后赋值。

1. 修改jslib

mergeInto(LibraryManager.library, {

  Hello: function () {
    window.alert("Hello, world!");
  },

  HelloString: function (str) {
    window.alert(UTF8ToString(str));
  },

  ShowBanner:function(str,t){
    unityShowBanner(UTF8ToString(str),UTF8ToString(t));
  },

  ChangeBtn:function(str){
    let btn = document.getElementById("sendUnityBtn");
    btn.innerHTML = UTF8ToString(str);
  }
});

  主要是增加了最后的ChangeBtn方法。

2. 修改C#

  同样的先声明方法:

[DllImport("__Internal")]
private static extern void ChangeBtn(string str);

然后增加调用

if (GUILayout.Button("test4", GUILayout.Width(200), GUILayout.Height(100)))
{
    ChangeBtn("发送信息给Unity");
}

  发布WebGL,拷贝文件到服务器,由于增加了一个HTML上面的按钮标签,所以需要修改一下index.html文件:
在body里面加多一个按钮:

<button id="sendUnityBtn">传值给Unity</button>

在这里插入图片描述

在这里插入图片描述
  这样就可以通过id选择器来选中这个按钮了。
  拷贝到服务器,运行:
在这里插入图片描述

  会看到多了一个按钮,点击上面的test4按钮,会看到
在这里插入图片描述

  这个按钮上的字发生了变化了,所以我们从c#控制HTML标签内容已经成功了。

二、 通过JavaScript调用C#方法

  接下来要反过来,从JavaScript发送消息给Unity。和其他各种平台的原生交互一样,是通过SendMessage来实现这个功能的,SendMessage有3个参数,第一个是接收信息的GameObject对象的名字,第二个是方法名,第三个是需要传递的参数。
  一般来说需要调用SendMessage之前需要先获得Unity的单例,比如在WebGL的index.html里面就有:
在这里插入图片描述

  它这里是创建了一个Unity的单例。其实我们可以把它存起来备用。
  在上面的例子里面我们已经在HTML页面上面加了个按钮了,所以可以通过这个按钮来测试一下。
在这里插入图片描述

  这里传入的参数,第一个是JSCtrl,就之前挂c#脚本的GameObject名字了,然后第二个参数是方法名ChangeContent,所以我们需要在c#脚本里面加这个方法来让JavaScript调用:

private string content = "Hello world!";
private void OnGUI()
{
    if(GUILayout.Button("test1",GUILayout.Width(200),GUILayout.Height(100)))
    {
        Hello();
    }
    if (GUILayout.Button("test2", GUILayout.Width(200), GUILayout.Height(100)))
    {
        HelloString("Hello azhao");
    }
    if (GUILayout.Button("test3", GUILayout.Width(200), GUILayout.Height(100)))
    {
        ShowBanner("这是一个来自Unity的提示信息", "warning");
    }
    if (GUILayout.Button("test4", GUILayout.Width(200), GUILayout.Height(100)))
    {
        ChangeBtn("发送信息给Unity");
    }

    GUILayout.Label(content);
}

public void ChangeContent(string str)
{
    content = str;
}

  为了能让传入的值显示,所以用一个content变量来存储一个字符串,通过ChangeContent来改变这个content,然后用GUILayout.Label来显示这个字符串:
在这里插入图片描述

  可以看到,一开始这个字符串显示的是Hello world!,然后按“传值给Unity”的按钮,会看到:
在这里插入图片描述

  显示的字符已经变成了从HTML传进去的“Hello azhao”字符串了。

三、WebGL模板

  刚才在制作这些例子的过程中,发现一个问题,就是每次重新编译之后,生成的index.html文件都会变回默认的,而我们在index.html里面做了的修改就会丢失了,又要一次次的重新修改。
  其实Unity是可以修改发布WebGL的模版的。
在这里插入图片描述

  在设置——Player——WebGL页签里面,会找到WebGL Template选项,这里就是选择发布WebGL的模版的地方。默认有3个模板可以选择。
  这个模板也是可以自定义的,在Assets文件夹下新建一个WebGLTemplates文件夹,然后在里面建立你需要的模板的文件,比如我建立了一个叫做azhao的模板。里面再放2个文件,第一个文件是thumbnail.png图片,是用于显示在WebGL Template里面可选项的图标。第二个文件就是你需要的模版index.html文件了。
在这里插入图片描述

  把文件放好后,可以再次回到设置里面:
在这里插入图片描述

  会发现多了一个模板的选项。选中它,这样这个工程再发布WebGL的时候,就会使用刚才我们放进去的index.html文件了,我们可以修改这个文件,把自己需要的功能放进去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值