自己做網(wǎng)站哪種好做搜索引擎優(yōu)化的策略主要有
1.概述
Networked-Aframe 的工作原理是將實(shí)體及其組件同步到連接的用戶。要連接到房間,您需要將networked-scene
組件添加到a-scene
元素。對(duì)于要同步的實(shí)體,請(qǐng)向其添加networked
組件。默認(rèn)情況下,position
和rotation
組件是同步的,但如果您想同步其他組件或子組件,則需要定義架構(gòu)。有關(guān)網(wǎng)絡(luò)消息的更高級(jí)控制,請(qǐng)參閱廣播自定義消息和選項(xiàng)部分。
2.場(chǎng)景組件
A-Frame<a-scene>
上的組件。
<a-scene networked-scene="serverURL: /;app: <appId>;room: <roomName>;connectOnLoad: true;onConnect: onConnect;adapter: wseasyrtc;audio: false;video: false;debug: false;
">...
</a-scene>
屬性 | 描述 | 默認(rèn)值 |
serverURL | 選擇 WebSocket/信令服務(wù)器所在的位置。 | / |
app | 唯一的應(yīng)用程序名稱。不允許有空格。 | default |
room | 獨(dú)特的房間名稱。每個(gè)應(yīng)用程序可以有多個(gè)。不允許有空格。每個(gè)應(yīng)用程序可以有多個(gè)房間,客戶端只能連接到同一應(yīng)用程序和房間中的客戶端。 | default |
connectOnLoad | 網(wǎng)頁(yè)加載后立即連接到服務(wù)器。 | true |
onConnect | 當(dāng)客戶端成功連接到服務(wù)器時(shí)調(diào)用的函數(shù)。 | onConnect |
adapter | 您要使用的網(wǎng)絡(luò)服務(wù),請(qǐng)參閱適配器。 | wseasyrtc |
audio | 打開(kāi)/關(guān)閉您的應(yīng)用程序的麥克風(fēng)音頻流。僅當(dāng)所選適配器支持時(shí)才有效。 | false |
video | 打開(kāi)/關(guān)閉您的應(yīng)用程序的視頻流。僅當(dāng)所選適配器支持時(shí)才有效。 | false |
debug | 打開(kāi)/關(guān)閉 Networked-Aframe 調(diào)試日志。 | false |
3.連接
默認(rèn)情況下,networked-scene
將自動(dòng)連接到您的服務(wù)器。為了防止這種情況發(fā)生并控制何時(shí)連接,請(qǐng)?jiān)?code>networked-scene中將connectOnLoad
設(shè)置為 false。當(dāng)您準(zhǔn)備好連接時(shí),會(huì)在a-scene
元素上發(fā)出connect
事件。
AFRAME.scenes[0].emit('connect');
4.斷開(kāi)連接
要斷開(kāi)連接,只需從a-scene
元素中刪除networked-scene
組件即可。
AFRAME.scenes[0].removeAttribute('networked-scene');
從頁(yè)面中完全刪除a-scene
也可以徹底斷開(kāi)連接。
5.創(chuàng)建網(wǎng)絡(luò)實(shí)體
<a-assets><template id="my-template"><a-entity><a-sphere color="#f00"></a-sphere></a-entity></template>
</a-assets><!-- Attach local template by default -->
<a-entity networked="template: #my-template">
</a-entity><!-- Do not attach local template -->
<a-entity networked="template:#my-template;attachTemplateToLocal:false">
</a-entity>
創(chuàng)建要在客戶端之間同步的模板實(shí)例。默認(rèn)情況下,位置和旋轉(zhuǎn)將同步。buffered-interpolation
庫(kù)用于允許更少的網(wǎng)絡(luò)更新,同時(shí)保持平滑的運(yùn)動(dòng)。
模板只能有一個(gè)根元素。當(dāng)attachTemplateToLocal
設(shè)置為true時(shí),該元素上的屬性將被復(fù)制到本地實(shí)體,并且子元素將被附加到本地實(shí)體。遠(yuǎn)程實(shí)例化的實(shí)體將是模板根元素的副本,并添加了networked
組件。
(1)attachTemplateToLocal=true示例
<a-entity wasd-controls networked="template:#my-template">
</a-entity><!-- Locally instantiated as: -->
<a-entity wasd-controls networked="template:#my-template"><a-sphere color="#f00"></a-sphere>
</a-entity><!-- Remotely instantiated as: -->
<a-entity networked="template:#my-template;networkId:123;"><a-sphere color="#f00"></a-sphere>
</a-entity>
(2)attachTemplateToLocal=false示例
<a-entity wasd-controls networked="template:#my-template;attachTemplateToLocal:false;">
</a-entity><!-- No changes to local entity on instantiation --><!-- Remotely instantiated as: -->
<a-entity networked="template:#my-template;networkId:123;"><a-sphere color="#f00"></a-sphere>
</a-entity>
屬性 | 描述 | 默認(rèn)值 |
template | 存儲(chǔ)在 | ''” |
attachTemplateToLocal | 設(shè)置為 false 時(shí),不附加本地用戶的模板。當(dāng)本地和遠(yuǎn)程存在不同行為時(shí),這非常有用。 | true |
persistent | 在遠(yuǎn)程創(chuàng)建者(而非所有者)斷開(kāi)連接時(shí),嘗試獲取持久實(shí)體的所有權(quán)而不是刪除它們 | false |
6.刪除網(wǎng)絡(luò)實(shí)體
目前只有網(wǎng)絡(luò)實(shí)體的創(chuàng)建者可以刪除它。要?jiǎng)h除,只需使用常規(guī) DOM API 從 HTML 中刪除元素,Networked-Aframe 將自動(dòng)處理同步。
7.同步自定義組件
默認(rèn)情況下,根實(shí)體上的position
和rotation
組件是同步的。
要同步其他組件和子實(shí)體的組件,您需要為每個(gè)模板定義一個(gè)架構(gòu)。以下是定義和添加架構(gòu)的方法:
NAF.schemas.add({template: '#avatar-template',components: ['position','rotation','scale',{selector: '.hairs',component: 'show-child'},{selector: '.head',component: 'material',property: 'color'},]
});
根實(shí)體的組件可以用組件的名稱來(lái)定義。子實(shí)體的組件可以使用具有selector
字段和component
字段的對(duì)象來(lái)定義,該字段使用document.querySelector
使用的標(biāo)準(zhǔn) CSS 選擇器它指定組件的名稱。要僅同步多屬性組件的一個(gè)屬性,請(qǐng)?zhí)砑訋в袑傩悦Q的property
字段。
定義架構(gòu)后,通過(guò)調(diào)用NAF.schemas.add(YOUR_SCHEMA)
將其添加到架構(gòu)列表中。
組件數(shù)據(jù)由 A-Frame 組件data
屬性檢索。在網(wǎng)絡(luò)更新期間,每個(gè)組件的數(shù)據(jù)都會(huì)根據(jù)其之前的同步值進(jìn)行檢查;如果數(shù)據(jù)對(duì)象發(fā)生了任何變化,它將通過(guò)網(wǎng)絡(luò)同步。
8.同步組件優(yōu)化
對(duì)于每個(gè)組件,您可以定義一個(gè)requiresNetworkUpdate
函數(shù),該函數(shù)采用當(dāng)前值,如果當(dāng)前值較之前值發(fā)生更改,則返回 true。如果當(dāng)前值和先前值足夠接近,您可以返回 false,以免將此更改發(fā)送給其他參與者。
默認(rèn)情況下,當(dāng)您未定義它時(shí),它始終使用defaultRequiresUpdate
函數(shù)(在networked.js
頂部定義),該函數(shù)使用通用deepEqual
函數(shù)來(lái)將當(dāng)前值與前一個(gè)值進(jìn)行比較,當(dāng)兩個(gè)值不同時(shí)使用cachedData = AFRAME.utils.clone(newData);
以保留前一個(gè)值以供下次比較。AFRAME.utils.clone
實(shí)現(xiàn)正做JSON.parse(JSON.stringify(obj))
,可以與任何類型一起使用,但這可能不是 Vector3 類型(如位置、旋轉(zhuǎn)、縮放)的最佳性能實(shí)現(xiàn)。
只是為了讓你知道這是在做什么:
> const v = new THREE.Vector3(1,2,3);
Vector3 {x: 1, y: 2, z: 3}
> JSON.parse(JSON.stringify(v))
{x: 1, y: 2, z: 3}
因此,如果值發(fā)生變化,每次同步過(guò)程完成時(shí)都會(huì)在內(nèi)存中創(chuàng)建一個(gè)新對(duì)象,這些對(duì)象會(huì)在某一時(shí)刻被垃圾收集。如果場(chǎng)景很重,垃圾收集通常可能需要 1 毫秒或更長(zhǎng)的時(shí)間,結(jié)果可能是瀏覽器丟掉一些幀,因此沒(méi)有一致的 fps。您可以使用 Chrome 分析器來(lái)確認(rèn)這一點(diǎn)。對(duì)于移動(dòng)的頭像來(lái)說(shuō),這一點(diǎn)幾乎不會(huì)被注意到,但如果用戶擁有大量連續(xù)移動(dòng)的對(duì)象,這對(duì)于您的用例可能很重要。
此外,使用當(dāng)前的 aframewasd-controls
實(shí)現(xiàn)以及位置平滑方式,在用戶停止按鍵后 2 秒,玩家位置的變化仍然低于毫米精度,因此通過(guò)網(wǎng)絡(luò)發(fā)送大量 NAF 消息視覺(jué)上不易察覺(jué)的位置變化。 NAF 已經(jīng)包含位置插值來(lái)平滑接收到的位置變化,因此通過(guò)網(wǎng)絡(luò)發(fā)送所有這些位置變化甚至是多余的。
您可以使用專用函數(shù)來(lái)比較給定精度的兩個(gè) Vector3,通過(guò)避免創(chuàng)建新對(duì)象,通過(guò)網(wǎng)絡(luò)和內(nèi)存發(fā)送更少的消息來(lái)實(shí)現(xiàn)更好的性能:
const vectorRequiresUpdate = epsilon => {return () => {let prev = null;return curr => {if (prev === null) {prev = new THREE.Vector3(curr.x, curr.y, curr.z);return true;} else if (!NAF.utils.almostEqualVec3(prev, curr, epsilon)) {prev.copy(curr);return true;}return false;};};
};
這個(gè)函數(shù)實(shí)際上是在NAF.utils.vectorRequiresUpdate
中定義的,供你使用。
要在網(wǎng)絡(luò)模式中使用它以獲得 1 毫米的位置精度和 0.5 度的旋轉(zhuǎn)精度,請(qǐng)按如下方式使用:
{template: '#avatar-template',components: [{component: 'position',requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.001)},{component: 'rotation',requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.5)}]
}
從0.11.0版本開(kāi)始,同步位置和旋轉(zhuǎn)的默認(rèn)模式使用上述優(yōu)化。
9.同步嵌套模板 - 例如:手
要同步嵌套模板,請(qǐng)像這樣設(shè)置 HTML 節(jié)點(diǎn):
<a-entity id="player" networked="template:#player-template;attachTemplateToLocal:false;" wasd-controls><a-entity camera look-controls networked="template:#head-template;attachTemplateToLocal:false;"></a-entity><a-entity hand-controls="hand:left" networked="template:#left-hand-template"></a-entity><a-entity hand-controls="hand:right" networked="template:#right-hand-template"></a-entity>
</a-entity>
在此示例中,頭部/攝像頭、控制器的左手和右手將生成自己的模板,這些模板將獨(dú)立于根玩家進(jìn)行聯(lián)網(wǎng)。注意:這與當(dāng)前不支持的手部追蹤無(wú)關(guān)。這種父子關(guān)系僅在一個(gè)級(jí)別之間有效,即。子實(shí)體的直接父實(shí)體必須具有networked
組件。
您需要自己定義左手和右手模板,以便向其他用戶顯示手部模型。只有位置和旋轉(zhuǎn)會(huì)同步給其他用戶。要同步手勢(shì),請(qǐng)參閱下面的networked-hand-controls
組件。
10.帶同步手勢(shì)的跟蹤控制器
這是比上述更簡(jiǎn)單的替代方案。 NAF 允許輕松添加其他人可見(jiàn)的手部模型,這些模型顯示與觸摸的按鈕相匹配的模擬手勢(shì)(不是手部跟蹤),這樣您就可以向房間里的其他人指向并豎起大拇指或握拳。
您所要做的就是使用內(nèi)置的networked-hand-controls
組件,將這兩個(gè)實(shí)體添加為相機(jī)裝備的子級(jí):
<a-entityid="my-tracked-left-hand"networked-hand-controls="hand:left"networked="template:#left-hand-default-template"
></a-entity>
<a-entityid="my-tracked-right-hand"networked-hand-controls="hand:right"networked="template:#right-hand-default-template"
></a-entity
您可以設(shè)置的公共架構(gòu)屬性有:
屬性 | 描述 | 默認(rèn)值 | 取值范圍 |
color | 將被設(shè)置為材質(zhì)顏色 | white | |
hand | 指定實(shí)體是用于左手還是右手 | left | left, right |
handModelStyle | A-Frame中可用的內(nèi)置模型 | highPoly | highPoly, lowPoly, toon, controller |
customHandModelURL | 可選的自定義手模型網(wǎng)址 |
請(qǐng)注意“控制器”選項(xiàng)——它將使用控制器本身的模型,根據(jù)您的平臺(tái)自動(dòng)正確設(shè)置——它還將廣播模型支持的按鈕網(wǎng)格更新。 (不幸的是,Quest 2 模型按鈕網(wǎng)格目前存在一個(gè)錯(cuò)誤,因此不會(huì)顯示任何更新。)
networked-hand-controls
正在完全替換hand-controls
,不要同時(shí)使用兩者。如果您使用如上所述的網(wǎng)絡(luò)組件,則無(wú)需為每只手定義模板和網(wǎng)絡(luò)架構(gòu)。默認(rèn)模板和網(wǎng)絡(luò)模式已定義如下:
<template id="left-hand-default-template"><a-entity networked-hand-controls="hand:left"></a-entity>
</template>
<template id="right-hand-default-template"><a-entity networked-hand-controls="hand:right"></a-entity>
</template>
NAF.schemas.add({template: '#left-hand-default-template',components: [{component: 'position',requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.001)},{component: 'rotation',requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.5)},'networked-hand-controls']
});
NAF.schemas.add({template: '#right-hand-default-template',components: [{component: 'position',requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.001)},{component: 'rotation',requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.5)},'networked-hand-controls']
});
11.發(fā)送自定義消息
NAF.connection.subscribeToDataChannel(dataType, callback)
NAF.connection.unsubscribeToDataChannel(dataType)NAF.connection.broadcastData(dataType, data)
NAF.connection.broadcastDataGuaranteed(dataType, data)NAF.connection.sendData(clientId, dataType, data)
NAF.connection.sendDataGuaranteed(clientId, dataType, data)
訂閱和取消訂閱dataType
指定的網(wǎng)絡(luò)消息的回調(diào)。使用broadcastData
功能向房間內(nèi)的所有客戶端廣播數(shù)據(jù)。要僅發(fā)送到特定客戶端,請(qǐng)改用sendData
函數(shù)。
參數(shù) | 描述 |
clientId | 將此數(shù)據(jù)發(fā)送到的 ClientId |
dataType | 用于標(biāo)識(shí)網(wǎng)絡(luò)消息的字符串。 |
callback | 收到類型 |
data | 要發(fā)送給所有其他客戶端的對(duì)象 |
12.轉(zhuǎn)讓實(shí)體所有權(quán)
實(shí)體的所有者負(fù)責(zé)同步其組件數(shù)據(jù)。當(dāng)用戶想要修改另一個(gè)用戶的實(shí)體時(shí),他們必須首先獲得該實(shí)體的所有權(quán)。所有權(quán)轉(zhuǎn)移示例和切換所有權(quán)組件展示了如何獲取實(shí)體的所有權(quán)并更新它。
NAF.utils.takeOwnership(entityEl)
取得實(shí)體的所有權(quán)。
NAF.utils.isMine(entityEl)
檢查您是否擁有指定實(shí)體。
13.事件
當(dāng) NAF 中發(fā)生某些事情時(shí),事件就會(huì)被觸發(fā)。要訂閱這些事件,請(qǐng)遵循以下模式:
document.body.addEventListener('clientConnected', function (evt) {console.error('clientConnected event. clientId =', evt.detail.clientId);
});
創(chuàng)建document.body
元素后需要訂閱事件。這可以通過(guò)等待document.body
onLoad
方法或使用 NAF 的onConnect
函數(shù)來(lái)實(shí)現(xiàn)。使用 NAF 活動(dòng)演示作為示例。
事件列表:
事件 | 描述 | 取值范圍 |
clientConnected | 當(dāng)另一個(gè)客戶端連接到您時(shí)觸發(fā) |
|
clientDisconnected | 當(dāng)另一個(gè)客戶端與您斷開(kāi)連接時(shí)觸發(fā) |
|
entityCreated | 創(chuàng)建網(wǎng)絡(luò)實(shí)體時(shí)觸發(fā) |
|
entityRemoved | 刪除網(wǎng)絡(luò)實(shí)體時(shí)觸發(fā) |
|
以下事件在networked
組件上觸發(fā)。有關(guān)示例,請(qǐng)參閱切換所有權(quán)組件。
所有權(quán)轉(zhuǎn)讓事件列表:
事件 | 描述 | 參數(shù)范圍 |
ownership-gained | 當(dāng)網(wǎng)絡(luò)實(shí)體的所有權(quán)被奪取時(shí)觸發(fā) |
|
| ||
ownership-lost | 當(dāng)網(wǎng)絡(luò)實(shí)體的所有權(quán)丟失時(shí)觸發(fā) |
|
| ||
ownership-changed | 當(dāng)網(wǎng)絡(luò)實(shí)體的所有權(quán)更改時(shí)觸發(fā) |
|
| ||
|
14.適配器
NAF 可與多個(gè)網(wǎng)絡(luò)庫(kù)和服務(wù)一起使用。適配器是一個(gè)向 NAF 添加對(duì)庫(kù)的支持的類。如果您只是在開(kāi)發(fā)一個(gè)小項(xiàng)目或概念驗(yàn)證,那么您可能會(huì)使用默認(rèn)配置,并且可以跳過(guò)本節(jié)。評(píng)估不同適配器時(shí)應(yīng)考慮的因素包括:
-
一間房間需要支持多少個(gè)并發(fā)用戶?
-
您想托管自己的服務(wù)器嗎?或者像 Firebase 這樣的“無(wú)服務(wù)器”解決方案可以完成這項(xiàng)工作嗎?
-
您需要音頻(麥克風(fēng))流嗎?
-
您需要自定義服務(wù)器端邏輯嗎?
-
您想要 WebSocket(客戶端-服務(wù)器)網(wǎng)絡(luò)架構(gòu)還是 WebRTC(點(diǎn)對(duì)點(diǎn))網(wǎng)絡(luò)架構(gòu)?
默認(rèn)情況下使用wseasyrtc
適配器,它不支持音頻并使用 TCP 連接。這對(duì)于生產(chǎn)部署來(lái)說(shuō)并不理想,但是由于 WebRTC 固有的連接問(wèn)題,我們將其設(shè)置為默認(rèn)值。要通過(guò) WebRTC 支持音頻,請(qǐng)確保服務(wù)器使用 https 并將適配器更改為easyrtc
(這使用 UDP)。
支持的適配器列表:
適配器 | 描述 | 音頻/視頻支持情況 | 基于WebSocket 或 WebRTC | 如何啟動(dòng) |
wseasyrtc | 默認(rèn) - 使用 open-easyrtc 庫(kù) | No | WebSocket |
|
easyrtc | 使用 open-easyrtc 庫(kù) | 音頻和視頻(相機(jī)和屏幕共享) | WebRTC |
|
janus | 使用 Janus WebRTC 服務(wù)器和 janus-plugin-sfu | 音頻和視頻(相機(jī)或屏幕共享) | WebRTC | 參閱 naf-janus-adapter |
socketio | 無(wú)需外部庫(kù)的 SocketIO 實(shí)現(xiàn)(服務(wù)器支持房間實(shí)例化) | No | WebSocket |
|
webrtc | 無(wú)需外部庫(kù)的原生 WebRTC 實(shí)現(xiàn)(正在進(jìn)行中,目前沒(méi)有維護(hù)者) | 音頻 | WebRTC |
|
Firebase | 用于 WebRTC 信號(hào)傳輸?shù)?Firebase(目前沒(méi)有維護(hù)者) | No | WebRTC | 參閱 naf-firebase-adapter |
uWS | uWebSockets 的實(shí)現(xiàn)(目前沒(méi)有維護(hù)者) | No | WebSocket | 參閱 naf-uws-adapter |
表中的 WebRTC 表示組件更新使用 WebRTC 數(shù)據(jù)通道 (UDP),而不是 WebSocket (TCP)。您仍然有一個(gè)用于信令部分的 WebSocket。
更為詳細(xì)比較,請(qǐng)參閱文檔 NAF 適配器比較。
15.音頻
將audio: true
添加到networked-scene
組件(并使用支持它的適配器)后,默認(rèn)情況下您將聽(tīng)不到任何音頻。盡管音頻將進(jìn)行流式傳輸,但在創(chuàng)建具有networked-audio-source
的實(shí)體之前,它是聽(tīng)不到的。來(lái)自該實(shí)體所有者的音頻將從該實(shí)體的位置在 3D 空間中發(fā)出。networked-audio-source
組件必須與networked
組件一起添加到實(shí)體(或?qū)嶓w的子實(shí)體)。
要使麥克風(fēng)靜音/取消靜音,您可以使用以下 API(easyrtc 和 janus 適配器):
NAF.connection.adapter.enableMicrophone(enabled)
其中enabled
是true
或false
。
16.視頻
將video: true
(janus 適配器不需要)添加到networked-scene
組件(并使用支持它的適配器)后,默認(rèn)情況下您將看不到任何視頻。盡管視頻將進(jìn)行流式傳輸,但在創(chuàng)建使用帶有networked-video-source
的網(wǎng)格(例如<a-plane>
)的實(shí)體之前,它是不可見(jiàn)的。來(lái)自該實(shí)體所有者的視頻將在 3D 空間中從該實(shí)體的位置可見(jiàn)。networked-video-source
組件必須添加到具有networked
組件的實(shí)體的<a-plane>
子實(shí)體中。
目前,這僅適用于支持getMediaStream(clientId, type="video")
API 的 easyrtc 和 janus 適配器。
請(qǐng)參閱,該示例顯示了沒(méi)有音頻的用戶攝像頭。
要禁用/重新啟用相機(jī),您可以使用以下 API(僅限 easyrtc 適配器):
NAF.connection.adapter.enableCamera(enabled)
其中enabled
是true
或false
。
使用 easyrtc 適配器,您可以使用addLocalMediaStream
和removeLocalMediaStream
API 添加額外的視頻軌道,例如屏幕共享:
navigator.mediaDevices.getDisplayMedia().then((stream) => {NAF.connection.adapter.addLocalMediaStream(stream, "screen");
});NAF.connection.adapter.removeLocalMediaStream("screen");
請(qǐng)參閱多流示例,該示例使用帶有networked-video-source="streamName: screen"
的第二個(gè)平面向其他參與者顯示屏幕共享。請(qǐng)務(wù)必查看此示例 html 文件末尾的注釋以了解已知問(wèn)題。
17.雜項(xiàng)
NAF.connection.isConnected()
如果已與信令服務(wù)器建立連接,則返回 true。
NAF.connection.getConnectedClients()
返回當(dāng)前連接的客戶端列表。
18.選項(xiàng)
NAF.options.updateRate
每秒調(diào)用網(wǎng)絡(luò)組件sync
函數(shù)的頻率。對(duì)于大多數(shù)社交 VR 應(yīng)用程序來(lái)說(shuō),10-20 是正常的。默認(rèn)為15
。
NAF.options.useLerp
默認(rèn)情況下,當(dāng)創(chuàng)建實(shí)體時(shí),buffered-interpolation
庫(kù)用于平滑位置、旋轉(zhuǎn)和縮放網(wǎng)絡(luò)更新。如果您不希望在創(chuàng)建時(shí)使用此功能,請(qǐng)將其設(shè)置為 false。
19.離線使用
NAF 已經(jīng)包含 easyrtc,因此運(yùn)行npm run dev
將提供完全有效的解決方案,而無(wú)需訪問(wèn)外部服務(wù)器。不過(guò),這些示例確實(shí)依賴于 AFrame 和其他未與 NAF 打包的依賴項(xiàng)。因此,必須首先使 AFrame 適應(yīng)離線工作,然后對(duì)所有其他組件執(zhí)行相同的操作。這基本上可以歸結(jié)為下載所使用的腳本及其內(nèi)容,例如 3D 模型、字體等資產(chǎn)。建議在網(wǎng)絡(luò)控制臺(tái)打開(kāi)時(shí)加載頁(yè)面并識(shí)別哪些請(qǐng)求來(lái)自主機(jī)外部。
對(duì)于 VR,您還需要 https,因?yàn)闉g覽器需要它才能實(shí)現(xiàn)沉浸式模式。server/easyrtc-server.js
文件中提供了說(shuō)明。也就是說(shuō),您必須生成密鑰和證書(shū),將它們添加到本地 CA,然后通過(guò) NAF 提供的 Express 服務(wù)器加載它們。確保在server/easyrtc-server.js
頂部正確配置,并按照說(shuō)明通過(guò)https.createServer
進(jìn)一步向下啟用 https 本身。一旦您連接到 VR 中的 NAF 服務(wù)器,瀏覽器仍然會(huì)抱怨證書(shū)未知。您可以單擊高級(jí)并繼續(xù)。