vue项目结合unity webgl通信(亲身实践 Unity2022.3版本)

        在参考网上众多资料后,终于将Vue与Unity Webgl双向通信的功能完成。在此过程中遇到了很多问题,故记录下整体流程。

方案实现:

1.unity端实现一个jslib文件预定义函数作为桥接。

2.c#使用DllImport引入和调用预定义的函数。

3.web端使用js定义被调用函数。

1.Unity Webgl程序嵌入vue

2.Unity -> vue通信

3.vue -> Unity通信

1.Unity Webgl程序嵌入vue

1)在Unity打包生成webgl项目后,将webgl文件夹内容复制到vue项目目录下的static文件夹中

添加Web.Config文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<!--
  有关如何配置 ASP.NET 应用程序的详细信息,请访问
  https://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>  
  <system.webServer>
    <httpProtocol>
      <!-- 允许跨域配置 -->
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="X-Requested-With,Content-Type,Authorization" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE,OPTIONS" />
        <add name="Access-Control-Allow-Credentials" value="true" />
      </customHeaders>
    </httpProtocol>
        <staticContent>
            <remove fileExtension=".mem" />  
            <remove fileExtension=".data" />  
            <remove fileExtension=".unity3d" />  
            <remove fileExtension=".jsbr" />  
            <remove fileExtension=".membr" />  
            <remove fileExtension=".databr" />  
            <remove fileExtension=".unity3dbr" />  
            <remove fileExtension=".jsgz" />  
            <remove fileExtension=".memgz" />  
            <remove fileExtension=".datagz" />  
            <remove fileExtension=".unity3dgz" />  
            <remove fileExtension=".json" />  
            <remove fileExtension=".unityweb" />  
           
            <mimeMap fileExtension=".mem" mimeType="application/octet-stream" />  
            <mimeMap fileExtension=".data" mimeType="application/octet-stream" />  
            <mimeMap fileExtension=".unity3d" mimeType="application/octet-stream" />  
            <mimeMap fileExtension=".jsbr" mimeType="application/octet-stream" />  
            <mimeMap fileExtension=".membr" mimeType="application/octet-stream" />  
            <mimeMap fileExtension=".databr" mimeType="application/octet-stream" />  
            <mimeMap fileExtension=".unity3dbr" mimeType="application/octet-stream" />  
            <mimeMap fileExtension=".jsgz" mimeType="application/x-javascript; charset=UTF-8" />  
            <mimeMap fileExtension=".memgz" mimeType="application/octet-stream" />  
            <mimeMap fileExtension=".datagz" mimeType="application/octet-stream" />  
            <mimeMap fileExtension=".unity3dgz" mimeType="application/octet-stream" />  
            <mimeMap fileExtension=".json" mimeType="application/json; charset=UTF-8" />  
            <mimeMap fileExtension=".unityweb" mimeType="application/octet-stream" />  
        </staticContent>
  </system.webServer>
</configuration>

2)在vue项目中以iframe的方式调用

<iframe src="/static/Unity/index.html"
     ref="unityvue">
 </iframe>

2.Unity -> vue通信

1)在unity创建好项目后,在Assets目录下新建Plugins文件夹,创建一个jslib文件,可以用txt创建文件,文件名加后缀名为“xxx.jslib”,切记后缀名更改为jslib

jslib当作中间者,unity与它通信,前端也与它通信,在此基础上三者之间进行了通信对接

2)在刚刚创建的jslib文件里,添加以下代码:

mergeInto(LibraryManager.library,{   
    //Unity内自定义调用方法名 PostScore(string sceneName) 
    PostScore: function (sceneName) { 
     strs = Pointer_stringify(sceneName);   //字符串需用Pointer_stringify转换
     GetScore(strs);                        //前端自定义方法名GetScore(strs)
    },    
});

3)在unity中,新建一个脚本,添加命名空间using System.Runtime.InteropServices; 并添加以下C#代码:

[DllImport("__Internal")]
    private static extern void PostScore(string currentScene);  //当前场景

在unity中调用PostScore()方法,即调用jslib里的PostScore()方法

4)打包时在Player Settings->Player->Publishing Settings中将压缩格式禁用,平台选择Webgl

5)在unity打包程序后,在index.html中添加GetScore()方法

以上是unity基础的向前端通信方式。

此时我们在网页嵌入的Unity页面中点击交互按钮时即可触发PostScore(str)方法,将数据从Unity页面传输到前端html中。

3.vue -> Unity通信

 官方文档

前端页面向unity页面传值需用到unityInstance.SendMessage()函数,调用格式如下:

SendMessage(unityObject,unityMethodName,value)

unityObject——unity脚本挂载对象名

unityMethodName——unity脚本内调用方法名(需为public方法)

value——前端需要传出的值

1) 在Unity2022.3版本打包生成的webgl中不能直接找到unityInstance对象,需要在index.html页面作如下处理,自定义一个myGameInstance对象用于获取unityInstance

var myGameInstance = null;

createUnityInstance(document.querySelector("#unity-canvas"), {
        ...//省略代码
      }).then((unityInstance) => {
        myGameInstance = unityInstance;
      });

2)之后就能愉快的在vue页面调用该方法了~

const refreshAllItem = ()=>{
      console.log('当前unity对象', unityvue.value)
      unityvue.value.contentWindow.myGameInstance.SendMessage('WeatherControl', 'TransToAfternoon', "")
}

参考文档

在此感谢以下作者的参考资料~

网页传递参数到Unity WebGL ,WebGL传递参数到网页_webgl unityinstance_先生沉默先的博客-CSDN博客

WebGL给Unity传递参数问题1: Cannot read properties of undefined (reading ‘SendMessage‘)_先生沉默先的博客-CSDN博客

Unity(WebGL)与JS通讯2022最新姿势 - 知乎

web通信 - web 调用unity方法_哔哩哔哩_bilibili

Vue3项目中通常避免直接使用iframe引入Unity WebGL,因为iframe会增加页面的复杂性和SEO优化的难度。如果你想在Vue应用中集成WebGL游戏或交互内容,可以考虑以下几种替代方案: 1. **动态加载**:使用`<script>`标签异步加载Unity脚本,并通过JavaScript与Vue组件进行通信。这种方式允许你控制何时加载以及如何与Vue的其他部分整合。 ```html <script src="path/to/unity-loader.js"></script> <template> <div ref="unityContainer" @load="unityLoaded"></div> </template> <script> import UnityLoader from &#39;path/to/unity-loader&#39;; export default { methods: { unityLoaded() { const container = this.$refs.unityContainer; // 加载Unity game并初始化 UnityLoader.load().then((game) => { // 游戏实例化后的操作 }); } } } </script> ``` 2. **单文件组件(SFC)**:创建一个自定义的Vue组件,该组件封装了Unity游戏的运行环境。这样可以在组件内部渲染Unity内容,并通过props或事件传递数据和回调。 3. **使用WebGPU或WebXR**:如果Unity支持,还可以尝试利用现代浏览器的新特性,如WebGPU或WebXR,它们可以直接与DOM交互,无需iframe。 4. **预构建资源**:如果Unity支持,你可以将游戏预构建为静态HTML5或WebAssembly模块,然后像普通静态资源一样引入到Vue应用中。 无论哪种方法,关键在于将Unity的内容封装成与Vue更紧密结合的形式,以便更好地管理状态和用户交互。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值