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

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

请添加图片描述

实践路线

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

问题背景

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

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

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

请添加图片描述
2、别人前端采用vue开发的UI界面。
请添加图片描述
直观从这两个截图来看还是可以看出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双向通信流程如下:

请添加图片描述

项目实践

小目标

1、搭建Unity测试项目并发布WebGL部署到Vue项目中。
2、验证Vue向Unity发送信息:通过前端UI控制Unity游戏物体的显隐和修改颜色。
3、验证Unity向Vue发送信息:Unity监听键盘空格键按下触发前端提示框的显示。

搭建Unity测试项目

1、测试场景
请添加图片描述
2、创建用于Unity与Vue通信的两个重要脚本

  • MessageManager.cs
    请添加图片描述创建MessageManager游戏物体,挂载MessageManager脚本,脚本提供接口给vue调用。

脚本内容如下:

using UnityEngine;

/// <summary>
/// Unity-Vue消息管理脚本
/// </summary>
public class MessageManager : MonoBehaviour
{
    /// <summary>
    /// 测试cube游戏物体
    /// </summary>
    public GameObject cube;


    /// <summary>
    /// vue设置物体显隐
    /// </summary>
    /// <param name="visible"></param>
    public void Vue_SetVisible(string visible)
    {
        if (cube != null)
        {
            cube.transform.localScale = visible == "0" ? Vector3.zero : Vector3.one;
        }
    }

    /// <summary>
    /// vue设置颜色
    /// </summary>
    /// <param name="htmlColor"></param>
    public void Vue_SetColor(string htmlColor)
    {
        if (cube != null)
        {
            if (ColorUtility.TryParseHtmlString(htmlColor,out Color color))
            {
                cube.GetComponent<MeshRenderer>().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;

/// <summary>
/// Unity-Vue消息管理脚本
/// </summary>
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项目中测试。
请添加图片描述

创建Vue3测试项目

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

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

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

npm install unity-webgl

安装成功可在vue项目下node_modules看到unity-webgl。
请添加图片描述

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

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

UnityGame.vue内容如下:

<template>
    <VueUnity :unity="unityContext" width="800" height="600"></VueUnity>
</template>

<script setup>
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加载完成...'))

</script>

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

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

<template>
  <UnityGame />
</template>

<script setup>
import UnityGame from './components/UnityGame.vue'
</script>

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

请添加图片描述

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

请添加图片描述

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组件里。示例:

<template>
    <VueUnity :unity="unityContext" width="800" height="600"></VueUnity>
    <div style="width: 50%; margin-left: auto; margin-right: auto;">
    <button @click="onShowCube" class="defaultButton">{{visible ? '隐藏':'显示'}}</button>
    <button @click="onSetColor" class="redButton"></button>
    <button @click="onSetColor" class="blueButton"></button>
    <button @click="onSetColor" class="yellowButton"></button>
    </div>
</template>

<script setup>
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 << 24) + (parseInt(colorArr[0]) << 16) + (parseInt(colorArr[1]) << 8) + parseInt(colorArr[2])).toString(16).slice(1);
     	return hex;
	}else{
		return rgb
	}
}

</script>

<style>
.defaultButton{
  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;
}

</style>

至此,vue测试通信unity项目构建完成。

请添加图片描述

运行项目验证unity和vue通信功能

1、unity打开vue的前端提示框。

请添加图片描述

2、vue前端UI按钮点击事件控制unity游戏物体的显隐和设置颜色。
请添加图片描述

ok,我们已经完成本次实践目标。

总结与展望

unity发布的webgl,使用UGUI在界面显示和处理用户输入方面存在体验差的问题。这些都可以用vue来解决。其实就是使用vue开发前端页面代替unity的UGUI界面,充分发挥了vue的优势,也保留了Unity渲染3d部分的优势。当前这就需要unity开发人员同时具备vue开发前端方面的知识了。

当我们开发前端的项目时,如果同时需要2d界面和3d场景交互时,如数字孪生、虚拟仿真等数据可视化项目,采用Unity+Vue3技术开发是个不错的选择!

本文对基于Unity+Vue3的WebGL项目发布实践做了一个测试demo演示unity与vue通过第三方插件unity-webgl通信的流程。需要对你有所帮助哦!创作不易,如果合你胃口,来个三连支持吧!我们一起加油!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/500372.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

文心一言 VS 讯飞星火 VS chatgpt (225)-- 算法导论16.3 7题

七、推广赫夫曼算法&#xff0c;使之能生成三进制的码字(即码字由符号0、1、2组成)&#xff0c;并证明你的算法能生成最优三进制码。如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; 推广赫夫曼算法以生成三进制码字需要对算法进行一定的修改&#xff0c;确保在每…

阿里云国际DDoS高防如何添加网站配置?

将网站域名配置到DDoS高防后&#xff0c;DDoS高防会为网站生成一个CNAME地址&#xff0c;您需要将网站域名的DNS解析指向高防CNAME地址&#xff0c;DDoS高防才能转发业务流量为网站防御DDoS攻击。本文介绍如何添加网站配置。 注意事项 接入DDoS高防&#xff08;中国内地&#…

WPF中获取TreeView以及ListView获取其本身滚动条进行滚动

实现自行调节scoll滚动的位置(可相应获取任何控件中的内部滚动条) TreeView:TreeViewAutomationPeer lvap new TreeViewAutomationPeer(treeView); var svap lvap.GetPattern(PatternInterface.Scroll) as ScrollViewerAutomationPeer; var scroll svap.Owner as ScrollVie…

2024最新软件测试20个基础面试题及答案

什么是软件测试&#xff1f; 答案&#xff1a;软件测试是指在预定的环境中运行程序&#xff0c;为了发现软件存在的错误、缺陷以及其他不符合要求的行为的过程。 软件测试的目的是什么&#xff1f; 答案&#xff1a;软件测试的主要目的是保证软件的质量&#xff0c;并尽可能大…

C# OpenCvSharp-HoughCircles(霍夫圆检测) 简单计数

目录 效果 项目 代码 下载 效果 项目 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using OpenCvSharp; using O…

基于Springboot的研究生调研管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的研究生调研管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结…

【基于springboot分析Quartz(v2.3.2)的启动流程】

基于springboot分析Quartz&#xff08;v2.3.2&#xff09;的启动流程 最近公司的定时任务使用了Quartz框架&#xff0c;在开发中经常出现定任务不执行了的问题&#xff0c;但是我又找不到原因所在&#xff0c;可把我愁坏了。于是我决定看看Quartz框架是怎么调度任务的。&#x…

基于单片机模糊算法温度控制系统设计

**单片机设计介绍&#xff0c; 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机模糊算法温度控制系统设计是一个综合性的项目&#xff0c;结合了单片机技术、传感器技术、模糊控制算法等多个方面。以下是对该设计的概要…

162.乐理基础-和声大调、旋律大调

内容参考于&#xff1a; 三分钟音乐社 上一个内容&#xff1a;161.音程、和弦板块总结、重点、建议 首先需要回忆一下18.调式、自然大调式&#xff08;C大调、D大调。。。&#xff09;与19.音阶是什么、有什么用&#xff0c;在18.调式、自然大调式&#xff08;C大调、D大调。…

openPLC_Editor C语言编程 在mp157 arm板上调用io等使用记录

1.编程界面比较简单&#xff0c;具备PLC开发编程的四种编程方式。梯形图语言LD &#xff0c;指令表语言IL&#xff0c;结构化文本语言ST&#xff0c;功能模块图语言FBD。 2.官方使用手册。学习资料实在是太少&#xff0c;目前都是自己比较费劲的研究。 3.2 Creating Your First…

UE5 SQLite笔记

开发环境&#xff1a; 系统&#xff1a;Windows 10 64 bit 引擎&#xff1a;Unreal Engine 5.1.1 IDE&#xff1a;JetBrains Rider 2023.2.1 语言&#xff1a;C 工具&#xff1a;DB Browser for SQLite SQLite数据类型&#xff1a; //INTEGER TEXT BLOB REAL NUMERIC/*integer…

家庭网络防御系统搭建-配置流量镜像到NDR系统

由于需要将家庭网络中的全部流量送到NDR分析系统进行分析&#xff0c;因此需要一个具备流量镜像功能的交换机或者路由器。在前面文章所提及的家庭网络架构中&#xff0c;需要一台交换机即可拷贝东西向流量以及南北向流量。当然如果家庭中的路由器或者其他设备具备交换机镜像功能…

EXCEL通过VBA字典快速分类求和

EXCEL通过VBA字典快速分类求和 汇总截图 Option ExplicitOption Explicit Sub answer3() Dim wb As Workbook Dim sht As Worksheet Set wb ThisWorkbook Set sht wb.Worksheets(2) Dim ss1 As Integer Dim ss2 As Integer Dim i As Integer Dim j As Integer j 1Dim aa()…

Moonbeam 开发工具集合:打造 Web3 开发游乐场

原文&#xff1a;https://moonbeam.network/blog/moonbeam-developer-tooling-ecosystem/ 作者&#xff1a;Moonbeam 团队 编译&#xff1a;OneBlock Moonbeam 一直以来都在支持以太坊和 Dotsama 生态系统中的构建者和开发者。它特别为 Solidity 开发者提供了熟悉的工具&…

vue2处理跨域问题

vue中访问springboot中的RestController中的服务 &#xff08;vue.config.js不生效-CSDN博客&#xff09; 1、创建项目 使用vue init webpack my_frontend 创建vue项目 在HelloWorld.vue文件中添加内容&#xff1a; HelloWorld.vue 文件内容&#xff1a; <template>&…

react Audio 倒计时5秒,每秒播放一次音频

文章目录 1. react 倒计时 每秒播放一次音频简单demo代码2. 问题及处理方式2.1 Audio 引入出现的报错2.2 解决方法 1. react 倒计时 每秒播放一次音频简单demo代码 import React, { useState,useRef } from react; import redBagMp3 from /branch/assets/mp3/redBag.mp3 const…

Swift:“逻辑运算子“与“比较运算符“

1. 逻辑非 ! 逻辑非运算符 ! 是用于对布尔值取反的。当操作数为 true 时&#xff0c;! 将返回 false&#xff0c;而当操作数为 false 时&#xff0c;! 将返回 true。 let isTrue true let isFalse !isTrue // isFalse 现在是 false 2. 逻辑与 && 逻辑与运算符 &a…

spring-boot之接口文档Swagger配置使用

Swagger 前后端分离 Vue SpringBoot 后端时代:前端只用管理静态页面; html> 后端。模板引擎JSP >后端是主力 前后端分离式时代: ●后端:后端控制层&#xff0c;服务层,数据访问层[后端团队] ●前端:前端控制层&#xff0c;视图层[前端团队] 。伪造后端数据&#xff0c;…

Oracle Cloud公布 | 每小时 126 亿次 SQL 数据库查询

广而告之&#xff1a;2024 年数据技术嘉年华大会将于 4 月12-13 日在北京召开&#xff0c;春暖花开之际&#xff0c;数据库行业蓬勃发展之时&#xff0c;广邀天下豪杰&#xff0c;相聚北京&#xff0c;共论数据库技术发展的创新与未来。 注册&#xff1a;https://www.modb.pro/…

链表合集(easy难度)

合并两个有序链表 双指针法 由于list1和list2都是递增的&#xff0c;可以想到用双指针法。假如当前list1这个指针指向的节点被收入完成&#xff0c;那就list1&#xff1b;如果是list2被收入&#xff0c;那就list2。 具体是list1和节点被收入还是list2的节点被收入&#xff…