基于Unity+Vue3通信交互的WebGL项目发布实践

05-01 9415阅读 0评论

基于Unity+Vue3通信交互的WebGL项目发布实践

基于Unity+Vue3通信交互的WebGL项目发布实践 第1张

实践路线

    • 基于Unity+Vue3通信交互的WebGL项目发布实践
      • 问题背景
      • 准备工作
      • 解决方案
      • 项目实践
        • 小目标
        • 搭建Unity测试项目
        • 创建Vue3测试项目
        • 运行项目验证unity和vue通信功能
        • 总结与展望

          问题背景

          我们最近需要把unity开发的pc项目迁移到web端,因为unity支持发布webgl。所以按照以往的开发流程,都是项目开发完成就发布webgl部署到服务器。

          突然有一天,测试人员提出说为什么我们做的网页跟别人的不太一样呢?具体看下面两张图:

          1、unity使用ugui做的界面发布webgl渲染的出来的样子

          基于Unity+Vue3通信交互的WebGL项目发布实践 第2张

          2、别人前端采用vue开发的UI界面。

          基于Unity+Vue3通信交互的WebGL项目发布实践 第3张

          直观从这两个截图来看还是可以看出unity的ugui在网页端渲染出来比较糊,不清晰。而且从实际体验中ugui的输入框在网页中极其不好用,还有诸多ui上的问题…唉,比较unity的优势不在web端,而且本来它为了性能考虑,在渲染ui方面肯定是比不上这些原生应用的。

          所以,我们最终采用vue3开发前端UI界面的方案代替unity的UGUI界面。下面我们就一起来探讨一下Vue和Unity是怎么一起共同配合工作的吧!

          准备工作

          阅读下文之前,你除了需要具备Unity发布WebGL的知识之外,可能还需要具备一些前端方面的知识,比如"三剑客":Html、Css、JavaScript,当然如果能熟悉Vue方面的知识就更好了。这样你就能畅通无堵的阅读本文了。

          解决方案

          1、vue项目中安装unity-webgl插件。

          2、vue直接通过SendMessage方法向Unity发送消息。

          3、Unity通过jslib脚本中介向Vue发送消息。

          4、unity和vue双向通信流程如下:

          基于Unity+Vue3通信交互的WebGL项目发布实践 第4张

          项目实践

          小目标

          1、搭建Unity测试项目并发布WebGL部署到Vue项目中。

          2、验证Vue向Unity发送信息:通过前端UI控制Unity游戏物体的显隐和修改颜色。

          3、验证Unity向Vue发送信息:Unity监听键盘空格键按下触发前端提示框的显示。

          搭建Unity测试项目

          1、测试场景

          基于Unity+Vue3通信交互的WebGL项目发布实践 第5张

          2、创建用于Unity与Vue通信的两个重要脚本

          • MessageManager.cs

            基于Unity+Vue3通信交互的WebGL项目发布实践 第6张创建MessageManager游戏物体,挂载MessageManager脚本,脚本提供接口给vue调用。

            脚本内容如下:

            using UnityEngine;
            /// 
            /// Unity-Vue消息管理脚本
            /// 
            public class MessageManager : MonoBehaviour
            {
                /// 
                /// 测试cube游戏物体
                /// 
                public GameObject cube;
                /// 
                /// vue设置物体显隐
                /// 
                /// 
                public void Vue_SetVisible(string visible)
                {
                    if (cube != null)
                    {
                        cube.transform.localScale = visible == "0" ? Vector3.zero : Vector3.one;
                    }
                }
                /// 
                /// vue设置颜色
                /// 
                /// 
                public void Vue_SetColor(string htmlColor)
                {
                    if (cube != null)
                    {
                        if (ColorUtility.TryParseHtmlString(htmlColor,out Color color))
                        {
                            cube.GetComponent().material.color = color;
                        }
                    }
                }
            }
            
            • webgl.jslib

              注意📢 :Unity官方文档中有说明,请使用 .jslib扩展名将包含 JavaScript 代码的文件放置在 Assets 文件夹中的“Plugins”子文件夹下。所以一般的做法就是在Plugins下新建文本文档,然后改名字改后缀即可。该jslib文件需符合Js语法,否则发布webgl会报错。

              jslib脚本格式内容如下:

              mergeInto(LibraryManager.library, {
                ShowDialog: function (str) {
                  var tip = UTF8ToString(str);
                  // '__UnityLib__' 是插件提供的unity对象,相当于绑定了网页渲染出来的Unity容器
                  __UnityLib__.showDialog(tip);
                },
              });
              

              那么Unity怎么调用jslib中的方法呢?

              C#为我们提供了这个命名空间System.Runtime.InteropServices下的DllImport方法,允许引入非托管代码程序集,也就是说我们在Unity里可以通过DllImport方法调用外部程序集的方法。

              这里为了测试方便,我就直接将Unity调用jslib的方法写在MessageManager里面了。

              using UnityEngine;
              using System.Runtime.InteropServices;
              /// 
              /// Unity-Vue消息管理脚本
              /// 
              public class MessageManager : MonoBehaviour
              {
                  [DllImport("__Internal")]
                  private static extern void ShowDialog(string msg);//方法名需要jslib书写一致
                  private void Update()
                  {
                      if (Input.GetKeyDown(KeyCode.Space))
                      {
                          ShowDialog("来自Unity的消息");
                      }
                  }
              }
              

              至此完成Unity项目的搭建,将项目发布成webgl包,部署到vue项目中测试。

              基于Unity+Vue3通信交互的WebGL项目发布实践 第7张

              创建Vue3测试项目

              1、创建vue3项目,并安装unity-webgl插件

              创建vue3项目这里就不再赘述了,自行搜索相关教程,如有必要,后期再考虑出相关教程。

              使用npm安装unity-webgl插件,执行以下命令:
              

              npm install unity-webgl

              安装成功可在vue项目下node_modules看到unity-webgl。

              基于Unity+Vue3通信交互的WebGL项目发布实践 第8张

              2、创建vue3组件UnityGame.vue用于渲染unity画布

              vue组件一般我们就放在components文件夹下,vue默认的资源文件夹目录是public,所以我们在public下新建Unity文件夹用于部署unity发布出来的webgl包内容。

              UnityGame.vue内容如下:

                  
              
              
              import UnityWebgl from 'unity-webgl';
              import VueUnity from 'unity-webgl/vue';
              const unityContext = new UnityWebgl({
                  loaderUrl: '/Unity/UnityVue.loader.js',
                  dataUrl: '/Unity/UnityVue.data.gz',
                  frameworkUrl: '/Unity/UnityVue.framework.js.gz',
                  codeUrl: '/Unity/UnityVue.wasm.gz',
              })
              unityContext.on('mounted',() => console.log('Unity加载完成...'))
              
              

              注意📢 :配置项必须包含最基本的四个属性loaderUrl, dataUrl, frameworkUrl, codeUrl ,这四个属性都是初始化 Unity 应用程序所需的资源文件。

              我们还需要再App.vue注册并渲染UnityGame.vue组件:

                
              
              
              import UnityGame from './components/UnityGame.vue'
              
              

              这样我们使用vue部署unity项目的基本结构就完成了。

              基于Unity+Vue3通信交互的WebGL项目发布实践 第9张

              执行命令:npm run dev打开本地服务器地址:http://localhost:5173/,即可看到我们用vue部署的unity webgl项目。

              基于Unity+Vue3通信交互的WebGL项目发布实践 第10张

              3、vue中实现与unity通信的基础

              unity-webgl插件为我们提供了两个关键方法:

              • vue调用unity方法

                send(objectName: string, methodName: string, params?: any)

                ⭐️ 向Unity实例对象发送消息,调用一个公共方法。

                • objectName: Unity场景中对象的名称

                • methodName: Unity脚本中方法的名称

                • params: 传递的参数

                • unity调用vue方法

                  on(eventName: string, eventListener: Function)

                  ⭐️ 注册一个事件或方法,用于监听触发事件或供Unity脚本调用。

                  所以,我们需要在UnityGame组件里添加实现unity与vue通信交互的测试代码。

                  我们将通信的方法写在UnityGame.vue组件里。示例:

                      
                      
                  {{visible ? '隐藏':'显示'}}
                  import UnityWebgl from 'unity-webgl'; import VueUnity from 'unity-webgl/vue'; import {ref} from 'vue'; //构建unity实例对象 const unityContext = new UnityWebgl({ loaderUrl: '/Unity/UnityVue.loader.js', dataUrl: '/Unity/UnityVue.data.gz', frameworkUrl: '/Unity/UnityVue.framework.js.gz', codeUrl: '/Unity/UnityVue.wasm.gz', }) const visible = ref(true) unityContext.on('mounted',() => console.log('Unity加载完成...')) .on('showDialog',(tip)=> alert(tip))//监听unity调用的方法 //向Unity发送信息 function postUnityMessage(methodName, arg) { unityContext.send('MessageManager', methodName, arg) } //调用unity的方法 //设置cube显隐 function onShowCube(){ visible.value = !visible.value; postUnityMessage('Vue_SetVisible',visible.value ? "1" : "0") } //设置cube颜色 function onSetColor(event){ const button = event.target; const style = window.getComputedStyle(button); const htmlcolor = rgbtohex(style.backgroundColor.toString()); postUnityMessage('Vue_SetColor',htmlcolor); } function rgbtohex(rgb){ // rgby颜色值的正则 var reg = /^(rgb|RGB)/; // 判断是否为rgb格式 if(reg.test(rgb)){ // 将rgb的三个数值切割成数组 rgb(255,0,0) ——> ["255","0","0"] var colorArr = rgb.replace(/(?:rgb|RGB|\(|\))*/g,"").split(','); var hex = "#" + ((1 return rgb } } width: 50px; height: 50px; } .redButton{ background-color: red; width: 50px; height: 50px; } .yellowButton{ background-color: yellow; width: 50px; height: 50px; } .blueButton{ background-color: blue; width: 50px; height: 50px; }

免责声明
1、本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明。
2、本网站转载文章仅为传播更多信息之目的,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所
提供信息的准确性及可靠性,但不保证信息的正确性和完整性,且不对因信息的不正确或遗漏导致的任何
损失或损害承担责任。
3、任何透过本网站网页而链接及得到的资讯、产品及服务,本网站概不负责,亦不负任何法律责任。
4、本网站所刊发、转载的文章,其版权均归原作者所有,如其他媒体、网站或个人从本网下载使用,请在
转载有关文章时务必尊重该文章的著作权,保留本网注明的“稿件来源”,并白负版权等法律责任。

手机扫描二维码访问

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,9415人围观)

还没有评论,来说两句吧...

目录[+]