VR 带看3 快速接入指南
本文档是最简化的带看3接入指南,帮助你用最少的代码在项目中跑通「双端 VR 同步带看」。
如需了解完整的架构设计、UI 同步、画笔标注等高级功能,请阅读 带看3集成指南(完整版)。 SDK 全量 API 参考请阅读 带看3 SDK 对接指导文档。
前置条件
- VR 场景已初始化完成,
housePlay实例可用(参见 VR 初始化展示指南)。 - 已获取众趣开放平台的服务 Token(
serviceId)。 - 已引入带看3 SDK:
import { NestTakelook3 } from 'nest-takelook3-plugin'
最简流程(5 步跑通)
第一步:设置服务参数
await NestTakelook3.setSDKParams('your-service-token', 'https://opendev.3dnest.cn')
await NestTakelook3.getConfig()
第二步:注册核心事件
// 连接成功 → 开启 VR 同步 + 通知 housePlay 进入带看连接状态
NestTakelook3.onUserConnected(() => {
NestTakelook3.enableSyncLocalActionToRemote(true)
// 必须:通知 housePlay 已进入带看连接状态,SDK 才会开始收发同步消息
housePlay.setConnectionStatus(true)
})
// 收到远端 VR 操作 → 同步到本地
NestTakelook3.onRemoteControllingNotify((action) => {
if (!action?.payload) return
// 首次视角同步(接听方加入后,发起方会广播当前完整视角快照)
if (action.payload.isFirstSyncAction && housePlay.firstSyncRemoteActions) {
housePlay.firstSyncRemoteActions(action.payload.state)
return
}
// 常规增量同步(持续跟随对方视角)
housePlay.syncRemoteActions(action.payload)
})
// 成员加入 → 发起方广播当前视角给新成员
NestTakelook3.onMemberJoin((member) => {
console.log('成员加入:', member.userId)
// 发起方:将当前 VR 视角快照发给新加入的成员
if (isCaller && housePlay.getCurrentState) {
const state = housePlay.getCurrentState()
if (state) {
NestTakelook3.syncLocalActionToRemote({
state,
isFirstSyncAction: true,
})
}
}
})
// 带看结束 → 重置连接状态
NestTakelook3.onEndTour((isMe, reason) => {
console.log('带看结束', isMe ? '主动' : '被动', reason)
housePlay.setConnectionStatus(false)
})
setConnectionStatus(true)说明:必须在连接成功后调用,通知 housePlay 当前处于带看连接状态。housePlay 内部依赖此状态来决定是否启用操作同步(如uploadLocalActions事件的触发、syncRemoteActions的接收等)。带看结束时需调用setConnectionStatus(false)重置。首次视角同步说明:接听方加入带看后,需要立即同步到发起方当前的 VR 视角位置。发起方在
onMemberJoin中调用housePlay.getCurrentState()获取完整视角快照,通过syncLocalActionToRemote发送给接听方。接听方在onRemoteControllingNotify中检测到isFirstSyncAction标记后,调用housePlay.firstSyncRemoteActions(state)执行一次性完整同步,而非增量同步。
第三步:启动带看
带看会话由发起方创建,接听方通过 URL 参数获取会议信息后加入。
发起方(经纪人) — 创建会议室并启动:
// 1. 创建会议室createMeetingRoom或发起呼叫callout(仅发起方调用)
const result = await NestTakelook3.createMeetingRoom('your-package-id')
const meetingId = result.meetingId // 后端分配的会议 ID
const roomId = result.roomId // TIM 群组 ID
// 2. 打开消息同步
NestTakelook3.enableSyncLocalActionToRemote(true)
// 3. 启动带看
await NestTakelook3.startTour({
userId: 'agent_01',
callerUserId: 'agent_01', // 发起者 userId == callerUserId
meetingId,
roomId,
imPlatform: 'web',
packageId: 'your-package-id',
})
// 4. 将 meetingId 和 roomId 拼入 URL 传给接听方
const customerUrl = `https://your-domain.com/vr?m=模型ID`
+ `&useVrTakeSee=1&startTour=1`
+ `&meetingId=${meetingId}&roomId=${roomId}`
+ `&userId=customer_01&callerUserId=agent_01`
console.log('接听方链接:', customerUrl)
接听方(客户) — 从 URL 获取参数后加入:
// 从 URL 中解析参数(接听方不创建会议室,直接加入)
const params = new URLSearchParams(window.location.search)
await NestTakelook3.startTour({
userId: params.get('userId'), // 接听方自己的 ID
callerUserId: params.get('callerUserId'), // 发起者的 ID
meetingId: params.get('meetingId'), // 从 URL 获取
roomId: params.get('roomId'), // 从 URL 获取
imPlatform: 'web',
packageId: 'your-package-id',
})
注意:
createMeetingRoom只能由发起方调用。接听方的meetingId和roomId必须从 URL 参数(或业务接口推送)中获取,不能自行创建。
第四步:同步本地 VR 操作到远端
// 监听 housePlay 的视角变化事件,将操作发送给对方
housePlay.on('uploadLocalActions', (vrState) => {
NestTakelook3.syncLocalActionToRemote(vrState)
})
第五步:结束带看
await NestTakelook3.endTour('用户主动结束')
完整最小示例
以下是一个可直接运行的最小完整示例,展示从初始化到结束带看的全过程:
import { NestTakelook3 } from 'nest-takelook3-plugin'
/**
* 判断当前用户是否为发起者。
* 约定:userId === callerUserId 即为发起者。
*/
function getIsCaller(): boolean {
const params = new URLSearchParams(window.location.search)
const userId = params.get('userId') ?? ''
const callerUserId = params.get('callerUserId') ?? ''
return userId !== '' && userId === callerUserId
}
// ============================================================
// 初始化(VR 场景 init_UI 完成后调用)
// ============================================================
async function initTakeLook(housePlay) {
const isCaller = getIsCaller()
// 1. 设置服务参数 + 拉取配置
await NestTakelook3.setSDKParams('your-service-token', 'https://opendev.3dnest.cn')
await NestTakelook3.getConfig()
// 2. 注册事件
NestTakelook3.onUserConnected(() => {
console.log('连接成功')
NestTakelook3.enableSyncLocalActionToRemote(true)
housePlay.setConnectionStatus(true)
})
NestTakelook3.onRemoteControllingNotify((action) => {
if (!action?.payload) return
// 首次视角同步:接听方收到发起方的完整视角快照
if (action.payload.isFirstSyncAction && housePlay.firstSyncRemoteActions) {
housePlay.firstSyncRemoteActions(action.payload.state)
return
}
// 常规增量同步
housePlay.syncRemoteActions(action.payload)
})
// 成员加入:发起方广播当前视角给新成员
NestTakelook3.onMemberJoin((member) => {
console.log('成员加入:', member.userId)
if (isCaller && housePlay.getCurrentState) {
const state = housePlay.getCurrentState()
if (state) {
NestTakelook3.syncLocalActionToRemote({
state,
isFirstSyncAction: true,
})
}
}
})
NestTakelook3.onMemberExit((member) => {
console.log('成员退出:', member.userId)
})
NestTakelook3.onEndTour((isMe, reason) => {
console.log('带看结束', isMe ? '主动' : '被动', reason)
housePlay.setConnectionStatus(false)
})
// 3. 同步本地 VR 操作到远端
housePlay.on('uploadLocalActions', (vrState) => {
NestTakelook3.syncLocalActionToRemote(vrState)
})
}
// ============================================================
// 发起带看(经纪人端调用)
// ============================================================
async function startAsAgent(housePlay) {
await initTakeLook(housePlay)
// 创建会议室(仅发起方创建)
const result = await NestTakelook3.createMeetingRoom('pkg_001')
NestTakelook3.enableSyncLocalActionToRemote(false)
await NestTakelook3.startTour({
userId: 'agent_01',
callerUserId: 'agent_01',
meetingId: result.meetingId,
roomId: result.roomId,
imPlatform: 'web',
packageId: 'pkg_001',
})
// 将 meetingId / roomId 拼入 URL 传给客户端
const customerUrl = window.location.origin + window.location.pathname
+ '?m=' + new URLSearchParams(window.location.search).get('m')
+ '&useVrTakeSee=1&startTour=1'
+ '&meetingId=' + result.meetingId
+ '&roomId=' + result.roomId
+ '&userId=customer_01&callerUserId=agent_01'
+ '&packageId=pkg_001'
console.log('接听方链接:', customerUrl)
}
// ============================================================
// 加入带看(客户端调用,参数从 URL 获取)
// ============================================================
async function joinAsCustomer(housePlay) {
await initTakeLook(housePlay)
const params = new URLSearchParams(window.location.search)
await NestTakelook3.startTour({
userId: params.get('userId'),
callerUserId: params.get('callerUserId'),
meetingId: params.get('meetingId'), // 从 URL 获取,不自行创建
roomId: params.get('roomId'), // 从 URL 获取,不自行创建
imPlatform: 'web',
packageId: params.get('packageId') || 'pkg_001',
})
}
// ============================================================
// 结束带看(任意一方调用)
// ============================================================
async function stopTour() {
await NestTakelook3.endTour('用户主动结束')
}
发送 → 监听 速查
| 你想做什么 | 本端调用 | 对端收到 |
|---|---|---|
| 同步 VR 视角 | syncLocalActionToRemote(state) |
onRemoteControllingNotify(cb) |
| 发送业务动作 | syncLocalCustomActionToRemote(action) |
onSyncRemoteCustomActionToLocal(cb) |
| 静音某人 | voiceForbidden(userId, true) |
onVoiceForbidden(cb) |
| 踢出某人 | kickOutById(userId) |
onKickOut(cb) |
| 结束带看 | endTour(reason) |
onEndTour(cb) |
进阶功能
跑通基础流程后,可按需接入以下能力:
| 功能 | 说明 | 参考文档 |
|---|---|---|
| UI 状态同步 | 楼层切换、详情面板等双端联动 | 带看3集成指南 - 第十一章 |
| 画笔标注 | 双方在画面上实时绘制标注 | 带看3集成指南 - 第十二章 |
| 操作权限管理 | 「谁在操作」状态机,防冲突 | 带看3集成指南 - 第十章 |
| 呼叫模式 | callOut 推送通知到对方 |
SDK 文档 - 4.2 会议管理 |
| App WebView 适配 | Android/iOS JSBridge 音频桥接 | SDK 文档 - 第8章 多平台对接 |
| 自定义动作扩展 | 同步任意业务逻辑到远端 | 带看3集成指南 - 第九章 |