与react.js/vue.js集成

将Verge3D场景集成到项目中的方法有很多, 其中最简单的方法之一是通过iframe元素单独嵌入页面后加载。 但如果您想直接在应用内使用, 那么在这一过程中可能会比较麻烦。 但很多项目配置都有其特定的问题和特性。 本指南不能覆盖全部, 只针对流行的javascript框架 React.js 和 Vue.js 做出介绍。

Verge3D的资源商店(Asset Store)中提供了简单的 React 和 Vue.js 演示: React-V3D-AppVue-V3D-App。 如果您想了解如何从头开始创建 React/Vue.js + Verge3D 应用, 请遵循以下指南。

Verge3D提供了一个简单的例子, 说明如何制作一个简单的"Hello,World!" React 或 Vue 项目, 并将一个标准的Verge3D应用集成到其中。 示例文件位于Verge3D发行版中的 manager/templates/Embeddable 目录下。

Verge3D React.js应用示例

这里有一个简单的说明, 如何用Create React App工具创建一个基本的React.js + Verge3D应用。 您可以在Verge3D发行版中的 manager/templates/embeddable/readme.md 目录中找到此说明的副本。

1)通过Create React App 工具创建React.js应用: npx create-react-app react-app-example

2)将以下文件从 Verge3D 发行版复制到您的应用中:

或使用以下命令:

V3D_PATHMY_PATH 分别更改为Verge3D发行版和您的 React 应用所在的位置。 V3D_PATH=/path/to/v3d/distribution MY_PATH=/path/to/my/react/app cp -r $V3D_PATH/manager/templates/Embeddable/public/* $MY_PATH/public/ cp -r $V3D_PATH/manager/templates/Embeddable/src/* $MY_PATH/src/ cp $V3D_PATH/build/v3d.js $MY_PATH/public/
V3D_PATHMY_PATH 分别更改为Verge3D发行版和您的 React 应用所在的位置。 $V3D_PATH = "path\to\v3d\distribution" $MY_PATH = "path\to\my\react\app" Copy-Item -Path "$V3D_PATH\manager\templates\Embeddable\public\*" -Destination "$MY_PATH\public" -Recurse Copy-Item -Path "$V3D_PATH\manager\templates\Embeddable\src\*" -Destination "$MY_PATH\src" -Recurse Copy-Item "$V3D_PATH\build\v3d.js" -Destination "$MY_PATH\public"

3)将以下脚本标签添加到 react-app-example/public/index.html: <script src="%PUBLIC_URL%/v3d.js"></script>

4) 创建一个名为 react-app-example/src/V3DApp.js 的文件,其内容如下: import React from 'react'; import { createApp } from './v3dApp/app'; import './v3dApp/app.css'; class V3DApp extends React.Component { #app = null; #PL = null; #uuid = window.crypto.randomUUID(); #containerId = `v3d-container-${this.#uuid}`; #fsButtonId = `fullscreen-button-${this.#uuid}`; #sceneURL = 'v3dApp/app.gltf'; #logicURL = 'v3dApp/visual_logic.js'; async loadApp() { ({ app: this.#app, PL: this.#PL } = await createApp({ containerId: this.#containerId, fsButtonId: this.#fsButtonId, sceneURL: this.#sceneURL, logicURL: this.#logicURL, })); } disposeApp() { this.#app?.dispose(); this.#app = null; // dispose Puzzles' visual logic this.#PL?.dispose(); this.#PL = null; } reloadApp() { this.disposeApp(); this.loadApp(); } componentDidMount() { this.loadApp(); } componentWillUnmount() { this.disposeApp(); } render() { return <div id={this.#containerId}> <div id={this.#fsButtonId} className="fullscreen-button fullscreen-open" title="Toggle fullscreen mode" ></div> </div>; } } export default V3DApp;

react-app-example/src/index.js 的内容替换为以下代码: import React from 'react'; import ReactDOM from 'react-dom/client'; import V3DApp from './V3DApp'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<V3DApp/>);

6) 通过在 react-app-example 目录中执行以下命令来运行开发服务器: npm start 默认情况下,应用现在应该可以在 http://localhost:3000/ 地址中访问了。

Verge3D Vue.js应用示例

下面是关于如何使用Vue CLI工具创建基础的 Vue.js + Verge3D 应用的简单说明。 您可以在Verge3D发行版中的 manager/templates/Embeddable/README.md 目录中找到此说明的副本。

1)通过Vue CLI工具创建 Vue.js 应用: npx @vue/cli create vue-app-example

2)将以下文件从 Verge3D 发行版复制到您的应用中:

或使用以下命令:

V3D_PATHMY_PATH 分别更改为Verge3D发行版和 您的 Vue 应用所在的位置。 V3D_PATH=/path/to/v3d/distribution MY_PATH=/path/to/my/vue/app cp -r $V3D_PATH/manager/templates/Embeddable/public/* $MY_PATH/public/ cp -r $V3D_PATH/manager/templates/Embeddable/src/* $MY_PATH/src/ cp $V3D_PATH/build/v3d.js $MY_PATH/public/
V3D_PATHMY_PATH 分别更改为Verge3D发行版和 您的 Vue 应用所在的位置。 $V3D_PATH = "path\to\v3d\distribution" $MY_PATH = "path\to\my\vue\app" Copy-Item -Path "$V3D_PATH\manager\templates\Embeddable\public\*" -Destination "$MY_PATH\public" -Recurse Copy-Item -Path "$V3D_PATH\manager\templates\Embeddable\src\*" -Destination "$MY_PATH\src" -Recurse Copy-Item "$V3D_PATH\build\v3d.js" -Destination "$MY_PATH\public"

3) 添加如下脚本标签至 vue-app-example/public/index.html: <script src="<%= BASE_URL %>v3d.js"></script>

4) 创建一个文件 vue-app-example/src/components/V3DApp.vue , 包含以下代码:

<template> <div :id="containerId"> <div :id="fsButtonId" class="fullscreen-button fullscreen-open" title="Toggle fullscreen mode" ></div> </div> </template> <script> import { createApp } from '../v3dApp/app'; export default { name: 'V3DApp', created() { this.app = null; this.PL = null, this.uuid = window.crypto.randomUUID(); this.containerId = `v3d-container-${this.uuid}`; this.fsButtonId = `fullscreen-button-${this.uuid}`; this.sceneURL = 'v3dApp/app.gltf'; this.logicURL = 'v3dApp/visual_logic.js'; this.loadApp = async function() { ({ app: this.app, PL: this.PL } = await createApp({ containerId: this.containerId, fsButtonId: this.fsButtonId, sceneURL: this.sceneURL, logicURL: this.logicURL, })); } this.disposeApp = function() { this.app?.dispose(); this.app = null; // dispose Puzzles' visual logic this.PL?.dispose(); this.PL = null; } this.reloadApp = function() { this.disposeApp(); this.loadApp(); } }, mounted() { this.loadApp(); }, beforeDestroy() { this.disposeApp(); }, } </script> <style> @import '../v3dApp/app.css'; </style> <template> <div :id="containerId"> <div :id="fsButtonId" class="fullscreen-button fullscreen-open" title="Toggle fullscreen mode" ></div> </div> </template> <script> import { createApp } from '../v3dApp/app'; export default { name: 'V3DApp', created() { this.app = null; this.PL = null, this.uuid = window.crypto.randomUUID(); this.containerId = `v3d-container-${this.uuid}`; this.fsButtonId = `fullscreen-button-${this.uuid}`; this.sceneURL = 'v3dApp/app.gltf'; this.logicURL = 'v3dApp/visual_logic.js'; this.loadApp = async function() { ({ app: this.app, PL: this.PL } = await createApp({ containerId: this.containerId, fsButtonId: this.fsButtonId, sceneURL: this.sceneURL, logicURL: this.logicURL, })); } this.disposeApp = function() { this.app?.dispose(); this.app = null; // dispose Puzzles' visual logic this.PL?.dispose(); this.PL = null; } this.reloadApp = function() { this.disposeApp(); this.loadApp(); } }, mounted() { this.loadApp(); }, beforeUnmount() { this.disposeApp(); }, } </script> <style> @import '../v3dApp/app.css'; </style>

5)将 vue-app-example/src/App.vue 中的内容替换为如下代码: <template> <V3DApp></V3DApp> </template> <script> import V3DApp from './components/V3DApp.vue'; export default { name: 'App', components: { V3DApp, }, } </script>

6)通过在 vue-app-example 目录中执行以下命令来运行开发服务器: npm run serve 默认情况下,应用现在应该可以在 http://localhost:8080/ 地址中访问了。

使用拼图编辑器

React/Vue和 拼图编辑器 / 应用管理器 之间没有直接的整合方式。尽管如此, 您仍然可以使用拼图来为您的React/Vue应用添加场景交互。 本节解释了如何使用这种方法及其局限性。

应用管理器并不能直接处理一个典型的React/Vue项目的目录结构。 但经过一些调整后,应用管理器至少可以识别项目的 *.blend* 文件、导出的 *.gltf/.glb/.bin* 场景文件,以及拼图的可视化逻辑脚本。 这意味着您可以在应用管理器网页 中查看相应的场景资源并启动拼图编辑器。

这里的缺点是,查看.gltf文件和处理拼图只能通过Verge3D播放器来完成, 也就是说,与 在应用管理器内创建 的所有标准Verge3D应用的方式相同。因此,无法访问React/Vue的功能、组件、逻辑等...... 而且只能以一种单独的方式添加拼图。 不过,一个完整的React/Vue应用可以加载、 运行并与拼图编辑器中创建的逻辑脚本进行通信。

应用管理器设置

假设我们有一个根据本手册指南创建的React或Vue应用。 为了 “连接” 应用管理器和 React/Vue 项目, 我们需要创建一个专用的 “适配器” 应用。 这是一个自定义应用 模板 , 默认情况下并不存在于应用管理器中, 但可以在应用管理器的设置中添加。 请按照创建模板教程进行操作, 并在命名新模板时将 Embeddable/adapter 放入名称字段。 接下来,请点击 Apply Changes 按钮, 模板将会成功添加到应用管理器中:

然后,我们需要使用新添加的模板创建一个新的应用。 我们命名它为 my_awesome_app

最后,我们需要创建指向 React/Vue 项目中资源的符号链接, 应用管理器需要这些资源才能启动拼图编辑器。 假设 React/Vue 项目位于路径 MY_PATH 而您的 Verge3D applications 文件夹位于路径 V3D_APPS_PATH

您可以通过检查Verge3D的 应用管理器设置 来查看应用存放的目录 -> General -> Applications Folder

我们将创建一个符号链接,从 V3D_APPS_PATH/my_awesome_app/v3dApp 指向 MY_PATH/public/v3dApp - 后者是 React/Vue 项目中存储 verge3d 相关场景资源的地方。 此外,我们需要为拼图逻辑的 JS 和 XML 文件创建更多的符号链接。 请参照如下方法:

V3D_APPS_PATHMY_PATH 分别更改为 Verge3D applications 文件夹和您的 React/Vue 应用所在的位置。此外,将 my_awesome_app 替换为您在应用管理器中创建应用时指定的名称。 V3D_APPS_PATH=/path/to/v3d/applications MY_PATH=/path/to/my/app ln -s $MY_PATH/public/v3dApp $V3D_APPS_PATH/my_awesome_app/v3dApp ln -s v3dApp/visual_logic.js $V3D_APPS_PATH/my_awesome_app/visual_logic.js ln -s v3dApp/visual_logic.xml $V3D_APPS_PATH/my_awesome_app/visual_logic.xml

如下命令需要以管理员身份运行 PowerShell 。

V3D_APPS_PATHMY_PATH 分别更改为 Verge3D applications 文件夹和您的 React/Vue 应用所在的位置。此外,将 my_awesome_app 替换为您在应用管理器中创建应用时指定的名称。 $V3D_APPS_PATH = "path\to\v3d\applications" $MY_PATH = "path\to\my\app" cmd /c mklink /D $V3D_APPS_PATH\my_awesome_app\v3dApp (Resolve-Path $MY_PATH\public\v3dApp) cmd /c mklink $V3D_APPS_PATH\my_awesome_app\visual_logic.js (Resolve-Path $V3D_APPS_PATH\my_awesome_app\v3dApp\visual_logic.js) cmd /c mklink $V3D_APPS_PATH\my_awesome_app\visual_logic.xml (Resolve-Path $V3D_APPS_PATH\my_awesome_app\v3dApp\visual_logic.xml)

之后,只需打开文件 MY_PATH/src/v3dApp/app.js , 然后找到以下行:

var LOAD_LOGIC_FILES = false;

并对其进行如下修改,以实现加载拼图的逻辑脚本。

var LOAD_LOGIC_FILES = true;

现在您可以在应用管理器中看到该项目了。 在这里,您可以直接打开.gltf和.blend文件,以及使用拼图编辑器了。

加载拼图中的资源

替换纹理、加载场景、加载声音、加载视频、加载数据等难题允许指定 URL 以加载纹理、媒体和其他类型的文件。 诸如 replace texture(替换纹理)load scene(加载场景)load sound(加载声音)load video(加载视频)load data(加载数据) 等拼图允许指定 URL 以加载纹理、媒体文件和其他类型的文件。

将拼图编辑器与 React/Vue 应用一起使用时, 此类拼图中指定的所有文件路径都是相对于应用根路径计算的, 该路径通常指向应用的 public 目录。 如果 React/Vue 应用是根据本手册中描述的指南创建的, 那么该目录应该包含 v3d.js 文件和 v3dApp 目录。 此外,如果拼图编辑器按照本手册中描述的方式与 React/Vue 应用集成, 则编辑器只能访问应用程序的 public/v3dApp 目录。

因此,举例说明:如果我们想通过拼图加载一个声音文件,比如 sound.mp3, 应该放在 public/v3dApp 目录(或其子目录)中。 之后就可以在 load sound(加载声音) 拼图的 URL 字段中使用 v3dApp/mySound.mp3 来加载文件了: