Skip to main content

Room

Room 是组成 World 的基本单位,是一个独立的 3D 场景,玩家可以在不同的 Room 中跳转切换。

初始化

const room = world.getRoomInstance('RoomId', Room)
await room.enter()

Room 的实例化和 World 不同,需要通过 World 提供的工厂方法 getRoomInstance 去完成实例化。

第一个参数传入的是 Room 类,可以是从 SDK 导出的 Room 类也可以是导出的 Room 类的子类。第二个参数是 roomId ,这个 roomId 可以在 XConsole 上创建得到。

Room 实例化之后需要调用 Room 的 enter 方法才能进入,等待异步调用成功后就成功进入了该 Room。 进房有几种特殊模式,以应对网络异常等情况,可以进房模式章节

默认情况下 SDK 内部会使用皮肤列表的第一个皮肤和该皮肤下的Path列表中的第一个Path作为默认选项进入房间。如果想要改变这一默认行为,可以提前通过 setSkinInfo 指定进入房间的选项。参考如下代码

// room.enter前调用setSkinInfo指定目标
const room = world.getRoomInstance('RoomId', Room)
room.setSkinInfo({
skinId: '10086',
pathId: 'pathId',
})

await room.enter()

离开房间

在多次调用 enter 方法切换了多个房间之后,如果想要从当前房间退出,可以调用 Room 的 leave 方法,则会从当前房间离开,回到上次访问的房间。

await roomA.enter()
await roomB.enter()
await world.getCurrentRoom().leave()

参考上述代码,先进入了 roomA 房间,再进入了 roomB 房间,那么再调用 world.getCurrentRoom().leave() (也就是roomB)的 leave 方法则会回到 roomA 房间。

如果当前房间就是你最初进入的那个房间,再次调用 leave 则什么也不会发生。

切换皮肤 Skin

一个房间可能有不同的皮肤风格,那么可以通过调用 setSkinInfo 来切换不同的皮肤

// SDK自动会取Skin下的第一个Path
room.setSkinInfo({
skinId: '10086',
})

// 也可以指定Path
room.setSkinInfo({
skinId: '10086',
pathId: 'aaaa1',
})

也支持指定出生点

room.setSkinInfo({
skinId: '10086',
pathId: 'aaaa1',
birthPoint: {
player: point.point,
camera: camPoint.point,
},
})

如果不传入birthPoint,SDK会找一个合适的位置作为角色的出生位置。

更多细节可参考 皮肤章节

切换 Path

同上,一个房间一个皮肤下可能有不同的 Path 可以切换,那么可以通过调用 setSkinInfo 来切换不同的 Path

// 切当前Skin下的指定Path,就可以不传SkinId
room.setSkinInfo({
pathId: 'aaaa2',
})

更多细节可参考 Path 章节

传送

传送可以将角色镜头从空间中的某一个位置迁移到另一个位置,这个需求也通过setSkinInfo来实现

跨Skin/Path传送

setSkinInfo支持切换Skin、Path,同时可以通过传入birthPoint设置切过去后的角色出生位置。即setSkinInfo先切换皮肤/Path,随后将角色传送到新Path的指定位置

// 切其它Skin下的指定Path
currRoom.setSkinInfo({
skinId: '10086',
pathId: 'aaaaa1',
birthPoint: {
player: point.point,
camera: camPoint.point,
},
})

// 切当前Skin下的指定Path,就可以不传SkinId
currRoom.setSkinInfo({
pathId: 'pathId',
birthPoint: {
player: point.point,
camera: camPoint.point,
},
})

Path内传送

在一个Path内传送时,也是通过 setSkinInfo 传入 birthPoint 来实现传送效果

// 在当前Path内传送,无需传入PathId
currRoom.setSkinInfo({
birthPoint: {
player: point.point,
camera: camPoint.point,
},
})
caution

同Path下的传送必须要调用setSkinInfo,直接设置角色和镜头的位置,会导致不可预期的bug

// 错误写法,画面可能出现撕裂/前景背景对不上等不可预期现象
world.getPlayer().position = point.point
world.getCamera().pose.position = camPoint.point

// 正确写法
currRoom.setSkinInfo({
birthPoint: {
player: point.point,
camera: camPoint.point,
},
})

跨房间传送

从一个房间传送到另一个房间的某个点,可以先获取目标房间的引用,然后通过 setSkinInfo 来设置房间的一些属性信息,再调用目标房间的 enter 方法即可实现跨房间传送。

切换 显隐组合 Combination

一个 Path 下可能有多种物品组合可以切换,那么可以通过调用 setSkinInfo 来切换不同的 Combination

room.setSkinInfo({
combinationId: '1',
})

触发事件

在运行时,Room 内部会触发一些事件提供给开发者,这些事件主要是

事件名说明
createRoom 实例化后触发
enterRoom enter 成功后触发
leaveRoom leave 成功后触发
skinChanged皮肤切换成功后触发
pathChangedPath 切换成功后触发

值得注意的是 enter 事件和 leave 事件的触发顺序。参考如下代码

await roomA.enter()
await roomB.enter()

这段代码会从 roomA 跳转到 roomB,事件触发的先后顺序是 roomA enter、 roomA leave、roomB enter

这些事件以 可复写方法 和 发布订阅 两种方式提供给开发者。

更多事件相关的通用操作可以参考事件处理

发布订阅

TODO:

内存占用

只实例化 Room 不调用 enter 进入的内存占用量是很小的,进入后才会加载该房间需要的资源导致内存占用量增加。同一时间也只有一个 Room 会被激活(可以通过读取 Room 的 actived 属性判断),也只有激活的 Room 才会占用内存。

在默认情况下,切换 Room 时会将开发者在上个 Room 时创建的 Actor 等资源都释放,如果要修改这个默认行为可参考 Spawn Actor