基于Unity+Vue3通信交互的WebGL項目發(fā)布實踐
問題背景
我們最近需要把unity開發(fā)的pc項目遷移到web端,因為unity支持發(fā)布webgl。所以按照以往的開發(fā)流程,都是項目開發(fā)完成就發(fā)布webgl部署到服務(wù)器。
突然有一天,測試人員提出說為什么我們做的網(wǎng)頁跟別人的不太一樣呢?具體看下面兩張圖:
1、unity使用ugui做的界面發(fā)布webgl渲染的出來的樣子
2、別人前端采用vue開發(fā)的UI界面。
直觀從這兩個截圖來看還是可以看出unity的ugui在網(wǎng)頁端渲染出來比較糊,不清晰。而且從實際體驗中ugui的輸入框在網(wǎng)頁中極其不好用,還有諸多ui上的問題…唉,比較unity的優(yōu)勢不在web端,而且本來它為了性能考慮,在渲染ui方面肯定是比不上這些原生應(yīng)用的。
所以,我們最終采用vue3開發(fā)前端UI界面的方案代替unity的UGUI界面。下面我們就一起來探討一下Vue和Unity是怎么一起共同配合工作的吧!
準備工作
閱讀下文之前,你除了需要具備Unity發(fā)布WebGL的知識之外,可能還需要具備一些前端方面的知識,比如"三劍客":Html、Css、JavaScript,當(dāng)然如果能熟悉Vue方面的知識就更好了。這樣你就能暢通無堵的閱讀本文了。
解決方案
1、vue項目中安裝unity-webgl插件。
2、vue直接通過SendMessage方法向Unity發(fā)送消息。
3、Unity通過jslib腳本中介向Vue發(fā)送消息。
4、unity和vue雙向通信流程如下:
項目實踐
小目標
1、搭建Unity測試項目并發(fā)布WebGL部署到Vue項目中。
2、驗證Vue向Unity發(fā)送信息:通過前端UI控制Unity游戲物體的顯隱和修改顏色。
3、驗證Unity向Vue發(fā)送信息:Unity監(jiān)聽鍵盤空格鍵按下觸發(fā)前端提示框的顯示。
搭建Unity測試項目
1、測試場景
2、創(chuàng)建用于Unity與Vue通信的兩個重要腳本
-
MessageManager.cs
創(chuàng)建MessageManager游戲物體,掛載MessageManager腳本,腳本提供接口給vue調(diào)用。
腳本內(nèi)容如下:
using UnityEngine;
/// <summary>
/// Unity-Vue消息管理腳本
/// </summary>
public class MessageManager : MonoBehaviour
{
/// <summary>
/// 測試cube游戲物體
/// </summary>
public GameObject cube;
/// <summary>
/// vue設(shè)置物體顯隱
/// </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設(shè)置顏色
/// </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語法,否則發(fā)布webgl會報錯。
jslib腳本格式內(nèi)容如下:
mergeInto(LibraryManager.library, {
ShowDialog: function (str) {
var tip = UTF8ToString(str);
// '__UnityLib__' 是插件提供的unity對象,相當(dāng)于綁定了網(wǎng)頁渲染出來的Unity容器
__UnityLib__.showDialog(tip);
},
});
那么Unity怎么調(diào)用jslib中的方法呢?
C#為我們提供了這個命名空間System.Runtime.InteropServices下的DllImport方法,允許引入非托管代碼程序集,也就是說我們在Unity里可以通過DllImport方法調(diào)用外部程序集的方法。
這里為了測試方便,我就直接將Unity調(diào)用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項目的搭建,將項目發(fā)布成webgl包,部署到vue項目中測試。
創(chuàng)建Vue3測試項目
1、創(chuàng)建vue3項目,并安裝unity-webgl插件
創(chuàng)建vue3項目這里就不再贅述了,自行搜索相關(guān)教程,如有必要,后期再考慮出相關(guān)教程。
使用npm安裝unity-webgl插件,執(zhí)行以下命令:
npm install unity-webgl
安裝成功可在vue項目下node_modules看到unity-webgl。
2、創(chuàng)建vue3組件UnityGame.vue用于渲染unity畫布
vue組件一般我們就放在components文件夾下,vue默認的資源文件夾目錄是public,所以我們在public下新建Unity文件夾用于部署unity發(fā)布出來的webgl包內(nèi)容。
UnityGame.vue內(nèi)容如下:
<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 應(yīng)用程序所需的資源文件。
我們還需要再App.vue注冊并渲染UnityGame.vue組件:
<template>
<UnityGame />
</template>
<script setup>
import UnityGame from './components/UnityGame.vue'
</script>
這樣我們使用vue部署unity項目的基本結(jié)構(gòu)就完成了。
執(zhí)行命令:npm run dev
打開本地服務(wù)器地址:http://localhost:5173/,即可看到我們用vue部署的unity webgl項目。
3、vue中實現(xiàn)與unity通信的基礎(chǔ)
unity-webgl插件為我們提供了兩個關(guān)鍵方法:
-
vue調(diào)用unity方法
send(objectName: string, methodName: string, params?: any)
?? 向Unity實例對象發(fā)送消息,調(diào)用一個公共方法。
-
objectName
: Unity場景中對象的名稱 -
methodName
: Unity腳本中方法的名稱 -
params
: 傳遞的參數(shù)
-
-
unity調(diào)用vue方法
on(eventName: string, eventListener: Function)
?? 注冊一個事件或方法,用于監(jiān)聽觸發(fā)事件或供Unity腳本調(diào)用。
所以,我們需要在UnityGame組件里添加實現(xiàn)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';
//構(gòu)建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))//監(jiān)聽unity調(diào)用的方法
//向Unity發(fā)送信息
function postUnityMessage(methodName, arg) {
unityContext.send('MessageManager', methodName, arg)
}
//調(diào)用unity的方法
//設(shè)置cube顯隱
function onShowCube(){
visible.value = !visible.value;
postUnityMessage('Vue_SetVisible',visible.value ? "1" : "0")
}
//設(shè)置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的三個數(shù)值切割成數(shù)組 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項目構(gòu)建完成。
運行項目驗證unity和vue通信功能
1、unity打開vue的前端提示框。
2、vue前端UI按鈕點擊事件控制unity游戲物體的顯隱和設(shè)置顏色。
ok,我們已經(jīng)完成本次實踐目標。
總結(jié)與展望
unity發(fā)布的webgl,使用UGUI在界面顯示和處理用戶輸入方面存在體驗差的問題。這些都可以用vue來解決。其實就是使用vue開發(fā)前端頁面代替unity的UGUI界面,充分發(fā)揮了vue的優(yōu)勢,也保留了Unity渲染3d部分的優(yōu)勢。當(dāng)前這就需要unity開發(fā)人員同時具備vue開發(fā)前端方面的知識了。
當(dāng)我們開發(fā)前端的項目時,如果同時需要2d界面和3d場景交互時,如數(shù)字孿生、虛擬仿真等數(shù)據(jù)可視化項目,采用Unity+Vue3技術(shù)開發(fā)是個不錯的選擇!文章來源:http://www.zghlxwxcb.cn/news/detail-853868.html
本文對基于Unity+Vue3的WebGL項目發(fā)布實踐做了一個測試demo演示unity與vue通過第三方插件unity-webgl通信的流程。需要對你有所幫助哦!創(chuàng)作不易,如果合你胃口,來個三連支持吧!我們一起加油!文章來源地址http://www.zghlxwxcb.cn/news/detail-853868.html
到了這里,關(guān)于基于Unity+Vue3通信交互的WebGL項目發(fā)布實踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!