侧边栏壁纸
  • 累计撰写 30 篇文章
  • 累计创建 40 个标签
  • 累计收到 4 条评论

Unity 2022.3.4 生成WebGL与Vue进行通信

kiko
2023-04-21 / 0 评论 / 0 点赞 / 286 阅读 / 991 字
温馨提示:
本文最后更新于 2023-04-25,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

前言:Unity 不知从什么时候开始,生成的WebGL中不包含Json和UnityLoader.js文件了,百度搜了一大堆资料,只有两篇文章是用新版本的。这里结合这两篇文章进行一个解释说明。记录一下我研究了一礼拜的结果。。

Vue发送消息给WebGL

image-1682055303679

1. Unity新建脚本

using UnityEngine;
using System.Runtime.InteropServices;
using UnityEngine.UI;
public class CommunicationManager : MonoBehaviour
{
    [DllImport("__Internal")]
    private static extern void RegisterUnityInstance(CommunicationManager instance);

    void Start()
    {
        RegisterUnityInstance(this);
    }
public Text text;
    public void ReceiveDataFromVue(string data)
    {
        Debug.Log("Data received from Vue: " + data);
        // 这里处理你的数据
        text.text = data;
    }
}

2. Unity生成WebGL

image-1682055531708
image-1682055513518

新版Unity生成的WebGL目录结构

image-1682055661934

3. Vue函数发送消息

a. 把WebUL放进Vue的static目录下。

image-1682055621706

b. 新建Vue文件

先贴上完整代码

<template>
  <div>
    <button @click="sendData">点击通信</button>
    <iframe id="unity-container" ref="iframe" src="../static/Unity/index.html" width="1920" height="900"
            webkitallowfullscreen="true" mozallowfullscreen="true" allowfullscreen="true" frameborder="0">
    </iframe>
  </div>
</template>
<script>
export default {
  name: "App",
  data() {
    return {
      num: 0
    }
  },
  mounted() {

  },
  created() {

  },
  methods: {
    sendData() {
      this.num++;
      const data = this.num.toString();
      document.getElementById("unity-container").contentWindow.postMessage(
        {type: "sendDataToUnity", data: data},
        "*"
      );
    }
  },
};
</script>

4. 修改WebGL的index.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 | SmartFarmProject</title>
</head>
<body style="text-align: center">
<canvas id="unity-canvas" width=1290 height=722 style="width: 1290px; height: 722px; background: #231F20"></canvas>
<script src="Build/Unity.loader.js"></script>
<script>
  if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
    // Mobile device style: fill the whole browser client area with the game canvas:
    var meta = document.createElement('meta');
    meta.name = 'viewport';
    meta.content = 'width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes';
    document.getElementsByTagName('head')[0].appendChild(meta);
  }

  const loader = null;
  createUnityInstance(document.querySelector("#unity-canvas"), {
    dataUrl: "Build/WebGL.data.unityweb",
    frameworkUrl: "Build/WebGL.framework.js.unityweb",
    codeUrl: "Build/WebGL.wasm.unityweb",
    streamingAssetsUrl: "StreamingAssets",
    companyName: "DefaultCompany",
    productName: "SmartFarmProject",
    productVersion: "0.1",
    // matchWebGLToCanvasSize: false, // Uncomment this to separately control WebGL canvas render size and DOM element size.
    // devicePixelRatio: 1, // Uncomment this to override low DPI rendering on high DPI displays.
  }).then((unityInstance) => {
    this.loader = unityInstance
  }).catch((message) => {
    alert(message);
  });

  // 监听Vue的事件
  window.addEventListener("message", function (event) {
    if (event.data.type === "sendDataToUnity") {
      sendDataToUnity(event.data.data);   //调用下面的函数
    }
  });
	
  function sendDataToUnity(data) {
    if (this.loader != null) {
      this.loader.SendMessage("通信", "ReceiveDataFromVue", data);
  		// 此处”通信“是Unity中GameObject的名称,ReceiveDataFromVue是函数名,data是数据
    }
  }

</script>
</body>
</html>

最主要的是用下面的代码与index进行通信。
unity.vue

document.getElementById("unity-container").contentWindow.postMessage(
        {type: "sendDataToUnity", data: data},

index.html

  window.addEventListener("message", function (event) {
    if (event.data.type === "sendDataToUnity") {
      sendDataToUnity(event.data.data);
    }
  });

  function sendDataToUnity(data) {
    if (this.loader != null) {
      this.loader.SendMessage("testObject", "ReceiveDataFromVue", data);
      // testObject Unity对象
      // ReceiveDataFromVue 脚本里的函数
      // data 传入数据
    }
  }

WebGL发送消息给Vue

image-1682412558593
我这里有一个案例,WebGL的开关控制风扇,向Vue发送数据

1. 先创建一个xxx.jslib文件,放在Assest/Plungs文件夹

mergeInto(LibraryManager.library, {
    FanControl: function (flag) {  // .cs 对应函数
        FanStatus(UTF8ToString(flag))  // .js对应函数
    },
})

2. 创建Unity脚本文件 xxx.cs

GameObject绑定这个脚本中的函数

using UnityEngine;
using System.Runtime.InteropServices;

public class web : MonoBehaviour
{
    [DllImport("__Internal")]
    private static extern void FanControl(string flag);
    
    // 打开风扇
    public void TurnOnFan()
    {
        FanControl("true");
    }

    // 关闭风扇
    public void TurnOffFan()
    {
        FanControl("false");
    }
}

3. WebGL中的index.html文件进行监听

<script>
 function FanStatus(flag) {
        window.parent.postMessage({event: "FanStatus",data: flag}, "*") // {}中的数据是发送给Vue的数据
      }
</script>

4. Vue中建通html发送的事件

 mounted() {
    window.addEventListener('message', this.unityWatch)
  },
  methods: {
    /**监听方法**/
    unityWatch(e) {
      console.log(e)
      if (e.data.event === 'FanStatus') {
        this.openFan(e.data.data);
      }
    },
    openFan(flag) {
      // 执行打开风扇的操作
      console.log("风扇操作:" + flag);
    }
  },

大功告成。

0

评论区