vue中使用unity3D如何實(shí)現(xiàn)webGL將要呈現(xiàn)的效果
1. 什么是webGL
WebGL(Web圖形庫)是一個(gè)JavaScript API,可在任何兼容的Web瀏覽器中渲染高性能的交互式3D和2D圖形,而無需使用插件。
WebGL通過引入一個(gè)與OpenGL ES 2.0非常一致的API來做到這一點(diǎn),該API可以在 HTML5 <canvas>元素中使用。
這種一致性使API可以利用用戶設(shè)備提供的硬件圖形加速。
1.1 兼容性
目前支持 WebGL 的瀏覽器有:
- Firefox 4+
- Google Chrome 9+
- Opera 12+
- Safari 5.1+
- Internet Explorer 11+
- Microsoft Edge build 10240+
然而, WebGL一些特性也需要用戶的硬件設(shè)備支持。
2. 什么是unity3D
Unity 3D 簡稱 U3D 或者 Unity,是當(dāng)今世界范圍內(nèi)主流的 3D 游戲開發(fā)引擎,用 Unity 3D 開發(fā)的游戲可以在電腦、手機(jī)、游戲機(jī)、瀏覽器等幾乎所有常見平臺(tái)上運(yùn)行。
Unity 3D 是由 Unity Technologies 公司開發(fā)的一個(gè)讓玩家輕松創(chuàng)建諸如三維視頻游戲、建筑可視化、實(shí)時(shí)三維動(dòng)畫等類型互動(dòng)內(nèi)容的多平臺(tái)的綜合型游戲開發(fā)工具。
Unity 3D 可以運(yùn)行在 Windows 和MacOS X下,可發(fā)布游戲至 Windows、Mac、Wii、iPhone、WebGL(需要 HTML5)、Windows Phone 8 和 Android 平臺(tái)。也可以利用 Unity Web Player插件發(fā)布網(wǎng)頁游戲,支持Mac和 Windows平臺(tái)的網(wǎng)頁瀏覽,是一個(gè)全面整合的專業(yè)游戲引擎。
2.1 unity3D 的發(fā)展史
- 2004 年,Unity 3D 誕生于丹麥的阿姆斯特丹。
- 2005 年,發(fā)布了 Unity 1.0 版本,此版本只能應(yīng)用于 Mac 平臺(tái),主要針對 Web 項(xiàng)目和VR(虛擬現(xiàn)實(shí))的開發(fā)。
- 2008 年,推出 Windows 版本,并開始支持iOS 和Wii,從眾多的游戲引擎中脫穎而出。
- 2009 年,榮登 2009 年游戲引擎的前五,此時(shí) Unity 的注冊人數(shù)已經(jīng)達(dá)到了 3.5 萬。
- 2010 年,Unity 3D 開始支持 Android,繼續(xù)擴(kuò)大影響力。
- 2011 年,開始支持 PS3 和 XBox360,此時(shí)全平臺(tái)的構(gòu)建完成。
- 2012 年,Unity Technologies公司正式推出 Unity 4.0版本,新加入對于DirectX 11 的支持和Mecanim動(dòng)畫工具,以及為用戶提供Linux及 Adobe Flash Player的部署預(yù)覽功能。
- 2013 年,Unity 3D引擎覆蓋了越來越多的國家,全球用戶已經(jīng)超過 150 萬,Unity 4.0引擎已經(jīng)能夠支持在包括MacOS X、Android、iOS、Windows 等在內(nèi)的 10 個(gè)平臺(tái)上發(fā)布游戲。同時(shí),Unity Technologies公司 CEO David Helgason 發(fā)布消息稱,游戲引擎Unity 3D 今后將不再支持Flash 平臺(tái),且不再銷售針對 Flash 開發(fā)者的軟件授權(quán)。
- 2014 年,發(fā)布 Unity 4.6 版本,更新了屏幕自動(dòng)旋轉(zhuǎn)等功能。
- 2016 年,發(fā)布 Unity 5.4 版本,專注于新的視覺功能,為開發(fā)人員提供了最新的理想實(shí)驗(yàn)和原型功能模式,極大地提高了其在 VR 畫面展現(xiàn)上的性能。
2.2 從 JavaScript 調(diào)用 Unity 腳本函數(shù)
有時(shí)需要從瀏覽器的 JavaScript 向 Unity 腳本發(fā)送一些數(shù)據(jù)或通知。建議的做法是調(diào)用內(nèi)容中的游戲?qū)ο笊系姆椒?。如果要從嵌入在?xiàng)目中的 JavaScript 插件執(zhí)行調(diào)用,可使用以下代碼:
unityInstance.SendMessage(objectName, methodName, value)
其中,objectName是場景中的對象名稱;methodName 是當(dāng)前附加到該對象的腳本中的方法名稱;value 可以是字符串、數(shù)字,也可為空。例如:
unityInstance.SendMessage('MyGameObject', 'MyFunction') unityInstance.SendMessage('MyGameObject', 'MyFunction', 5) unityInstance.SendMessage('MyGameObject', 'MyFunction', 'MyString')
如果您計(jì)劃從嵌入頁面的全局范圍中調(diào)用內(nèi)部 JavaScript 函數(shù),應(yīng)始終假設(shè)該頁面上嵌入了多個(gè)構(gòu)建,因此應(yīng)顯式指定要引用的構(gòu)建。例如,如果內(nèi)容已被實(shí)例化為:
var unityInstance = UnityLoader.instantiate("unityContainer", "Build/build.json", {onProgress: UnityProgress})
則可以使用 unityInstance.SendMessage() 向構(gòu)建發(fā)送消息,或使用 unityInstance.Module 訪問構(gòu)建 Module 對象。
2.3 WebGL 性能注意事項(xiàng)
2.3.1可在 WebGL 上期待什么樣的性能?
通常,您獲得的性能應(yīng)該接近于 GPU 上的原生應(yīng)用程序,這是因?yàn)?WebGL圖形 API 使用 GPU 進(jìn)行硬件加速渲染。將 WebGL API 調(diào)用和著色器轉(zhuǎn)換為操作系統(tǒng)圖形 API(通常是 Windows 上的DirectX,或者是 Mac或 Linux上的OpenGL)會(huì)有少量開銷。
在 CPU 上,Emscripten會(huì)將您的代碼轉(zhuǎn)換為 WebAssembly,因此性能取決于 Web 瀏覽器。有關(guān)更多信息,請參閱 Unity 博客文章 WebAssembly 加載時(shí)間和性能 (WebAssembly Load Times and Performance)。
JavaScript 語言不支持多線程和 SIMD。受益于這些功能的任何代碼可能比其他代碼都要慢。無法在腳本中為 WebGL 編寫線程代碼和 SIMD 代碼,但有些引擎部分通常為多線程或經(jīng)過 SIMD 優(yōu)化,因此在 WebGL 上的性能會(huì)降低。
2.3.2 影響性能的 WebGL 特有設(shè)置
為獲得最佳性能,請?jiān)?Build Player 對話框中將優(yōu)化級(jí)別設(shè)置為 Fastest,并在 WebGL 的 Player 設(shè)置中將 Exception support 設(shè)置為 None。
2.3.3 WebGL 性能分析
WebGL 支持 Unity 性能分析器。請參閱 性能分析器 文檔以了解如何設(shè)置性能分析器。
2.3.4 后臺(tái)標(biāo)簽中的 WebGL 內(nèi)容
如果在 WebGL 平臺(tái)的 Player 設(shè)置中啟用了 Run in background,或者如果啟用了 Application.runInBackground,您的內(nèi)容將在畫布或?yàn)g覽器窗口失去焦點(diǎn)時(shí)繼續(xù)運(yùn)行。
但是,某些瀏覽器可能會(huì)限制在后臺(tái)標(biāo)簽頁中運(yùn)行的內(nèi)容。如果包含該內(nèi)容的標(biāo)簽頁不可見,在大多數(shù)瀏覽器中,您的內(nèi)容每秒才會(huì)更新一次。請注意,這將導(dǎo)致 Time.time 比平常采用默認(rèn)設(shè)置時(shí)更慢,因?yàn)?Time.maximumDeltaTime 的默認(rèn)值小于一秒。
2.3.5 限制 WebGL 性能
在某些情況下,可能希望以較低的幀率運(yùn)行 WebGL 內(nèi)容,以降低 CPU 使用率。與其他平臺(tái)一樣,可使用 Application.targetFrameRate API 來實(shí)現(xiàn)此目的。
如果不想限制性能,請將此 API 設(shè)置為默認(rèn)值 –1,而不是較高的值。如此,瀏覽器便可調(diào)整幀率以便在瀏覽器的渲染循環(huán)中實(shí)現(xiàn)最平滑的動(dòng)畫,獲得的效果可能好于 Unity 嘗試執(zhí)行自身的主循環(huán)時(shí)序來匹配目標(biāo)幀率。
3. 如何在vue中使用unity3D和webGL
3.1 新建一個(gè)掛載unity3d加載器的vue組件
新建一個(gè)一個(gè)unity3d加載器的vue組件顧名思義就是為了引入unity3d的加載器來加載。
<template> ?? ?<div class="webgl-content"> ?? ??? ?<div ?? ??? ??? ?id="unity-container" ?? ??? ??? ?:style="{ ?? ??? ??? ??? ?width: width + 'px', ?? ??? ??? ??? ?height: height + 'px' ?? ??? ??? ?}" ?? ??? ?></div> ?? ?</div> </template>
<script> import Vue from 'vue' export default { ?? ?name: 'vue-unity-webgl', ?? ?props: ['width', 'height', 'config', 'unityLoader', 'onProgress'], ?? ?data() { ?? ??? ?return { ?? ??? ??? ?instance: null, ?? ??? ??? ?loaded: false ?? ??? ?} ?? ?}, ?? ?beforeMount() { ?? ??? ?if (!this.eventBus) { ?? ??? ??? ?this.eventBus = new Vue({ ?? ??? ??? ??? ?data: { ?? ??? ??? ??? ??? ?ready: false, ?? ??? ??? ??? ??? ?load: false ?? ??? ??? ??? ?} ?? ??? ??? ?}) ?? ??? ?} ?? ??? ?if (typeof UnityLoader === 'undefined' && !this.eventBus.load) { ?? ??? ??? ?const script = document.createElement('script') ?? ??? ??? ?script.setAttribute('id', 'vue-unity-webgl-loader') ?? ??? ??? ?script.setAttribute('src', this.unityLoader) ?? ??? ??? ?script.setAttribute('async', '') ?? ??? ??? ?script.setAttribute('defer', '') ?? ??? ??? ?document.body.appendChild(script) ?? ??? ??? ?script.addEventListener('load', () => { ?? ??? ??? ??? ?this.eventBus.ready = true ?? ??? ??? ??? ?this.eventBus.$emit('onload') ?? ??? ??? ?}) ?? ??? ?} else { ?? ??? ??? ?this.eventBus.ready = true ?? ??? ?} ?? ??? ?this.eventBus.load = true ?? ?}, ?? ?mounted() { ?? ??? ?const instantiate = () => { ?? ??? ??? ?if (typeof UnityLoader === 'undefined') { ?? ??? ??? ??? ?return Promise.reject('UnityLoader 未定義') ?? ??? ??? ?} ?? ??? ??? ?if (!this.config) { ?? ??? ??? ??? ?return Promise.reject('config 未定義配置') ?? ??? ??? ?} ?? ??? ??? ?let params = {} ?? ??? ??? ?params.onProgress = (instance, progress) => { ?? ??? ??? ??? ?this.onProgress && this.onProgress(instance, progress) ?? ??? ??? ??? ?this.loaded = progress === 1 ?? ??? ??? ?} ?? ??? ??? ?if (this.module) { ?? ??? ??? ??? ?params.Module = this.module ?? ??? ??? ?} ?? ??? ??? ?this.instance = UnityLoader.instantiate('unity-container', this.config, params) ?? ??? ?} ?? ??? ?if (this.eventBus.ready) { ?? ??? ??? ?instantiate() ?? ??? ?} else { ?? ??? ??? ?this.eventBus.$on('onload', () => { ?? ??? ??? ??? ?instantiate() ?? ??? ??? ??? ?this.$emit('onload') ?? ??? ??? ?}) ?? ??? ?} ?? ?}, ?? ?methods: { ?? ??? ?message(object, method, params) { ?? ??? ??? ?if (params === null) { ?? ??? ??? ??? ?params = '' ?? ??? ??? ?} ?? ??? ??? ?if (this.instance !== null) { ?? ??? ??? ??? ?this.instance.SendMessage(object, method, params) ?? ??? ??? ?} else { ?? ??? ??? ??? ?return Promise.reject('vue-unity-webgl: 你給 Unity 發(fā)送的信息, 沒有被接收到') ?? ??? ??? ?} ?? ??? ?} ?? ?} } </script>
<style lang="scss" scoped> .webgl-content { ?? ?border-radius: 5px; ?? ?text-align: center; } #unity-container { ?? ?display: inline-block; ?? ?border-radius: 5px; } </style>
3.2 使用新建的vue-unity-webgl組件
<template> ?? ?<div id="webgl-box-warpper" v-loading="is_loading"> ?? ??? ?<vue-unity-webgl ?? ??? ??? ?v-if="is_show_webgl" ?? ??? ??? ?ref="vueUnityWebgl" ?? ??? ??? ?:config="webglConfig" ?? ??? ??? ?:unity-loader="webglUnityLoader" ?? ??? ??? ?:width="webglWidth" ?? ??? ??? ?:height="webglHeight" ?? ??? ??? ?:on-progress="listenWebglProgress" ?? ??? ?></vue-unity-webgl> ?? ?</div> </template>
<script> import VueUnityWebgl from '@/components/vue-unity-webgl' export default { ?? ?components: { ?? ??? ?VueUnityWebgl ?? ?}, ?? ?data() { ?? ??? ?return { ?? ??? ??? ?is_loading: false, ?? ??? ??? ?is_show_webgl: true, ?? ??? ??? ?webglConfig: '/Scenes1/Build/Scenes1.json', ?? ??? ??? ?webglUnityLoader: '/Scenes1/Build/UnityLoader.js' ?? ??? ??? ?webglWith: 1000, ?? ??? ??? ?webglHeight: 600 ?? ??? ?} ?? ?}, ?? ?created() { ?? ??? ?window.toVueWebgl = (action) => { ?? ??? ??? ?action && this.sendWebglMessage('{}', '第二次發(fā)送JSON數(shù)據(jù)') ?? ??? ?} ?? ?}, ?? ?mounted() { ?? ??? ?window.ReportReady = () => { ?? ??? ??? ?this.sendWebglMessage('1', '第一次發(fā)送內(nèi)容標(biāo)識(shí)') ?? ??? ?} ?? ?}, ?? ?methods: { ?? ??? ?listenWebglProgress(instance, progress) { ?? ??? ??? ?this.is_loading = true ?? ??? ??? ?if (progress === 1) { ?? ??? ??? ??? ?this.is_loading = false ?? ??? ??? ?} ?? ??? ?}, ?? ??? ?sendWebglMessage(message, info) { ?? ??? ??? ?console.log(info) ?? ??? ??? ?this.$refs.vueUnityWebgl.message('JsTalker', 'toUnityWebgl', message) ?? ??? ?} ?? ?} } </script>
4. 演示效果
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue3+element-plus props中的變量使用 v-model 報(bào)錯(cuò)及解決方案
這篇文章主要介紹了vue3+element-plus props中的變量使用 v-model 報(bào)錯(cuò)及解決方案,prop 是單向數(shù)據(jù)流,這里只能用:model-value,不能用v-model,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10Vue關(guān)于組件化開發(fā)知識(shí)點(diǎn)詳解
在本篇文章里,小編給大家分享的是關(guān)于Vue關(guān)于組件化開發(fā)知識(shí)點(diǎn)詳解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。2020-05-05vue實(shí)現(xiàn)鼠標(biāo)經(jīng)過動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)鼠標(biāo)經(jīng)過動(dòng)畫的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10vue項(xiàng)目中如何調(diào)用多個(gè)不同的ip接口
這篇文章主要介紹了vue項(xiàng)目中如何調(diào)用多個(gè)不同的ip接口,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08vue3實(shí)現(xiàn)按鈕權(quán)限管理的項(xiàng)目實(shí)踐
在做后臺(tái)管理系統(tǒng)時(shí),經(jīng)常會(huì)有權(quán)限管理的功能,本文主要介紹了vue3實(shí)現(xiàn)按鈕權(quán)限管理的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08