Skip to content

web 工程集成

web 工程示例以 Vite+vue3+ts 的框架作为前端工程开发环境。工程可以使用 create-vue,即 vue 官方的项目脚手架工具,提供了搭建基于 Vite 且 TypeScript 就绪的 Vue 项目的选项。

web 工程集成采用运行像素流的技术作为示例,当然你也可以采用 iframe 的技术手段。

第一步:页面实例化 ThingJS UE 像素流,首先在 web 工程中新建一篇 ts 文件pixelstreaming.ts,像素流送前端需要依赖库文件 @thingue/lib-pixelstreamingfrontend ,可以在 npm 官方镜像库中查看下载,需要在你的前端工程配置(package.json)中加入到 dependence 依赖。

ts
import {Config, PixelStreaming} from "@thingue/lib-pixelstreamingfrontend";

let stream: PixelStreaming;

function instanceStream() {
    const config = new Config({
        initialSettings: {
            AutoPlayVideo: true,
            AutoConnect: true,
            OfferToReceive: true,
            HoveringMouse: true,
            StartVideoMuted: true,
            MatchViewportRes: true,
        },
        useUrlParams: true
    });

    stream = new PixelStreaming(config, {
        playerUrlBuilder: () => new Promise<string>((resolve, reject) => {
            // ThingJS UE服务对外的地址,当前以web工程与ThingJS UE服务在同一机器中
            resolve('ws://localhost')
        })
    })
}
export { stream, instanceStream }

第二步,加载 ThingJS UE 像素流到页面,页面加载像素流依赖一个ui文件 @thingue/lib-pixelstreamingfrontend-ui ,需要在你的前端工程配置(package.json)中加入到 dependence 依赖。实例像素流须在 vue 中的 onBeforeMount 生命周前完成。

vue
<script setup lang="ts">
import { Application, PixelStreamingApplicationStyle } from '@thingue/lib-pixelstreamingfrontend-ui';
import { instanceStream, stream } from "@/pixelstreaming";
import { onMounted, onBeforeMount, ref } from "vue";

const player = ref();
onBeforeMount(() => {
  instanceStream();
});
onMounted(() => {
  const PixelStreamingApplicationStyles = new PixelStreamingApplicationStyle();
  PixelStreamingApplicationStyles.applyStyleSheet();

  const application = new Application({
    stream,
    onColorModeChanged: (isLightMode) => PixelStreamingApplicationStyles.setColorMode(isLightMode),
  });
  player.value.appendChild(application.rootElement)
})
</script>

<template>
  <div ref="player" style="width: 100vw; height: 100vh;"></div>
</template>

<style scoped></style>

第三步,页面与3D通讯。在页面增加一个功能按钮,实现3D中变换天气的功能,在 pixelstreaming.ts 文件中增加 sendCommand 方法并发布.

ts
function sendCommand(param: any) {
    stream.emitUIInteraction({
        type: "UserCommand",
        command: "ToUEMessage",
        param
    })
}
// 修改对外发布
export { stream, instanceStream, sendCommand }
vue
<script setup lang="ts">
import { sendCommand } from "@/pixelstreaming"
interface Weather {
  messageType: string;
  status: number;
}
let status:number = 0
function changeWeather() {
  status = (status += 1) == 4 ? 0 : status += 1
  let param:Weather = {
    messageType: 'changeWeather',
    status
  }
  sendCommand({
      type: "UserCommand",
      command: "ToUEMessage",
      param
  })
}
</script>

<template>
  <div class="overlay">
    <button @click="changeWeather()">天气变化</button>
  </div>
</template>

<style scoped>
.overlay {
  position: absolute;
  z-index: 100;
}
</style>

第四步,ThingJS UE 工程中实现接收web页面调用的方法,在 UE 工程中新建一篇js文件event.js并且在入口文件中引用,需要值得注意的是,该文件要引入 Thing.UE/PixelStreaming 一篇核心代码,具体文件路径详见 Context/Script 文件夹下。示例中把事件接收和定义接口写在了同一个文件中,实际项目中完全可以分开进行封装。

javascript
// event.js
const PixelStreaming = require('../Thing.UE/PixelStreaming');

const customInterface = {
    weather: new THING.UE.Weather(),
    callbackEvent: function(data) {
        const promise = new Promise((resolve, reject) => {
            customInterface[data.messageType] & customInterface[data.messageType](data)
            resolve(({data: data, meg: data.messageType}))
        })
        PixelStreaming.BroadcastMessageToFront("ToWebMessage", JSON.stringify({messageType: 'toFront', data: 'this is test'}));
        return promise
    },
    changeWeather: function (data) {
        data.status == 1 & this.weather.toRain()
        data.status == 2 & this.weather.toLargeSnow()
        data.status == 3 & this.weather.toRain()
        data.status == 0 & this.weather.toSun()
    },
}

function addMessageEvent() {
    PixelStreaming.addMessageMap("ToUEMessage", async function (param) {
        // 根据 web 传递的参数 messageType 来执行具体的方法
        if (param.hasOwnProperty('messageType')) {
            return await (customInterface.callbackEvent(param))
        }
    })
}

addMessageEvent()
module.exports = addMessageEvent

京ICP备13053130号 京公网安备11010502050947号