启用锁屏输入回调¶
当主机 PC 切换到 Windows 锁屏界面时,OS 安全策略会阻止 OS 级别的键盘和鼠标输入。在远程环境中,画面和音频流仍然可以传输,但无法进行实际的游戏操作。
过去,远程用户需要输入 Windows 账户密码来解除锁定。然而,这种方式存在暴露 PC 完整控制权限的风险,且连接流程也较为繁琐。
Remote Play Plugin 在 Hive Console 的 Remote Play 设置中提供了**不解除锁屏即可游玩**功能。启用此功能后,键盘、鼠标、触摸、摇杆、滚轮、缩放等所有输入事件将直接传递至游戏回调。
主要行为¶
- 基于回调的分发:所有输入事件将以
eventType: "Control"的形式传递至通过RegisterCallback注册的回调函数。无论锁定状态如何均按相同方式运作,解锁后回调分发仍会持续。 - 绕过 OS 输入路径:不使用 OS 的
SendInput路径,无论 Windows 锁定状态如何,都能接收一致的输入事件。 - 直接注入游戏:游戏将回调接收到的输入数据直接注入内部输入系统,在锁定状态和正常状态下均处理相同的操作。
前置准备¶
在应用此功能之前,请准备以下内容:
- 导入 Remote Play Plugin
- 注册用于接收事件的回调函数
- 支持的 SDK / 插件版本:
- Remote Play Plugin 1.2.0 及以上
- Hive SDK v4 26.4.0 及以上
Warning
若在未通过 RegisterCallback 注册回调的情况下启用 Hive Console 的**不解除锁屏即可游玩**功能,所有输入事件将丢失,远程操作将无法正常进行。请务必先注册回调。
Control 事件协议¶
启用**不解除锁屏即可游玩**功能后,回调传递的输入事件与聊天事件采用相同的 JSON 格式,eventType 的值固定为 "Control"。实际输入类型通过内部的 controlType 加以区分。
Envelope 公共结构¶
{
"version" : "1.02.00",
"eventType" : "Control",
"eventValue": {
"value": {
"controlType" : "<Key | Click | Wheel | Zoom>",
"controlValue": {
"value" : "<controlType-specific-value>",
"action" : "<controlType-specific-action>"
}
}
},
"etc" : { }
}
| 字段 | 说明 |
|---|---|
version | 固定为 "1.02.00" |
eventType | 始终为 "Control" |
eventValue.value.controlType | 输入类型,共 4 种:"Key" / "Click" / "Wheel" / "Zoom" |
eventValue.value.controlValue.value | 各 controlType 的数据(坐标、键码等) |
eventValue.value.controlValue.action | 各 controlType 的状态或动作 |
etc | 空对象 |
controlType = "Key" - 键盘输入¶
传递键盘单个按键的按下或释放状态。Web 客户端产生的键盘输入和摇杆输入均会转换为 controlType。
| 字段 | 值 |
|---|---|
controlValue.value | Windows 虚拟键码的 16 进制字符串(例:"0x41" = 'A',"0x57" = 'W',"0x20" = Space) |
controlValue.action | "Down" 或 "Up" |
摇杆方向码根据映射设置(WASD / DIRECTION)拆分为单个键事件后以 controlType 传递。游戏端的键盘输入和摇杆输入看起来格式相同。斜向移动也由主机拆分为两个单键事件后发送。
示例 - 按下 'A' 键
{
"version" : "1.02.00",
"eventType" : "Control",
"eventValue": {
"value": {
"controlType" : "Key",
"controlValue": { "value": "0x41", "action": "Down" }
}
},
"etc" : { }
}
示例 - 摇杆向上(WASD 映射时的 'W' 键)
{
"version" : "1.02.00",
"eventType" : "Control",
"eventValue": {
"value": {
"controlType" : "Key",
"controlValue": { "value": "0x57", "action": "Down" }
}
},
"etc" : { }
}
controlType = "Click" - 鼠标及触摸坐标输入¶
传递鼠标点击、鼠标移动及触摸坐标。Web 客户端产生的鼠标输入和触摸输入均会自动转换为以 GetClientRect() 为基准的游戏窗口客户端区域像素坐标后传递。
| 字段 | 值 |
|---|---|
controlValue.value | "x#y" 格式,单位为**游戏窗口客户端区域像素坐标**(保留小数点后 1 位)。Web 客户端的 0-1000 归一化坐标在主机端转换为像素后传递。 |
controlValue.action | "Down"、"Up" 或 "Move" |
Note
触摸输入转换为 Click 类型时,touchID 信息不会被保留。
坐标转换参考¶
curWidth / curHeight 是以游戏窗口 GetClientRect() 为基准的客户端区域尺寸,因此在游戏中可直接作为窗口坐标使用。
| Web 客户端位置 | 归一化坐标(inbound) | 像素坐标(curWidth=1053, curHeight=1585 示例) |
|---|---|---|
| 左上 | "0.0#0.0" | "0.0#0.0" |
| 右上 | "1000.0#0.0" | "1053.0#0.0" |
| 左下 | "0.0#1000.0" | "0.0#1585.0" |
| 右下 | "1000.0#1000.0" | "1053.0#1585.0" |
| 中央 | "500.0#500.0" | "526.5#792.5" |
示例 - 鼠标点击(Down -> Up)
{
"version" : "1.02.00",
"eventType" : "Control",
"eventValue": {
"value": {
"controlType" : "Click",
"controlValue": { "value": "526.5#792.5", "action": "Down" }
}
},
"etc" : { }
}
{
"version" : "1.02.00",
"eventType" : "Control",
"eventValue": {
"value": {
"controlType" : "Click",
"controlValue": { "value": "526.5#792.5", "action": "Up" }
}
},
"etc" : { }
}
示例 - 拖拽(Move)
{
"version" : "1.02.00",
"eventType" : "Control",
"eventValue": {
"value": {
"controlType" : "Click",
"controlValue": { "value": "645.1#681.7", "action": "Move" }
}
},
"etc" : { }
}
controlType = "Wheel" - 鼠标滚轮¶
传递鼠标滚轮的滚动操作。
| 字段 | 值 |
|---|---|
controlValue.value | "x.0#y.0" 格式,为**鼠标光标当前像素坐标**(以游戏窗口客户端区域为基准)。Web 客户端发送的滚动步数信息将丢失。 |
controlValue.action | "Up"(向上滚动)或 "Down"(向下滚动) |
示例 - 滚轮向下(鼠标位置 1234.0 px, 567.0 px)
{
"version" : "1.02.00",
"eventType" : "Control",
"eventValue": {
"value": {
"controlType" : "Wheel",
"controlValue": { "value": "1234.0#567.0", "action": "Down" }
}
},
"etc" : { }
}
controlType = "Zoom" - 放大/缩小¶
传递摄像头或地图画面的放大/缩小操作。
| 字段 | 值 |
|---|---|
controlValue.value | 固定为 "1"。Web 客户端发送的缩放步数信息将丢失。 |
controlValue.action | "In"(放大)或 "Out"(缩小) |
示例 - 放大
{
"version" : "1.02.00",
"eventType" : "Control",
"eventValue": {
"value": {
"controlType" : "Zoom",
"controlValue": { "value": "1", "action": "In" }
}
},
"etc" : { }
}
示例 - 缩小
{
"version" : "1.02.00",
"eventType" : "Control",
"eventValue": {
"value": {
"controlType" : "Zoom",
"controlValue": { "value": "1", "action": "Out" }
}
},
"etc" : { }
}
输入类型转换映射概述¶
以下是 Web 客户端发送的原始输入类型转换为主机回调事件的映射结构。
| Web 客户端输入 | 回调 controlType | 主要转换 / 信息丢失 |
|---|---|---|
| Key | "Key" | 直接使用 VK 16 进制值 |
| Joystick | "Key" | 方向码 -> WASD / DIRECTION 映射 -> 拆分为单键 |
| Click | "Click" | 坐标归一化 -> 像素转换 |
| Touch | "Click" | 坐标归一化 -> 像素转换,touchID 不传递(通过重复的 Down 判断多点触控) |
| Wheel | "Wheel" | 步数信息 -> 替换为鼠标像素坐标 |
| Zoom | "Zoom" | 步数信息 -> 固定为 "1" |
状态(Event)/ 聊天(Message)事件不通过此 Control 事件传递,而是按照现有协议规范单独传递。
游戏端输入处理指南¶
在 Hive Console 的 Remote Play 设置中启用**不解除锁屏即可游玩**功能后,Remote Play 不会将输入事件发送至 OS 输入队列,而是通过注册的回调直接传递给游戏。
因此,回调接收到的输入事件需要直接传递给 Unity Input System 或 Unreal Input Subsystem 等游戏内部输入系统进行处理。
这种方式是为了绕过 Windows 锁屏环境中 SendInput 和 SendKey 等 OS 级别输入注入受到限制的问题而设计的。由于输入事件直接在游戏进程内部分发,建议不区分锁屏状态和正常状态,使用相同的处理路径。
也就是说,启用**不解除锁屏即可游玩**功能后,建议接收此回调传递的所有输入事件,并将其传递给游戏内部输入系统的方式进行实现。这样可以确保无论锁屏状态如何,都能保证一致的输入处理和远程游玩行为。
- Unity:通过
InputSystem.QueueEvent或自定义输入管理器进行分发 - Unreal Engine:通过
FSlateApplication::OnKeyDown / OnMouseButtonDown等 Slate 事件进行分发,或使用游戏自定义输入管理器
锁屏环境下的后台渲染与音频处理指南¶
在 Windows 锁屏环境中使用 Remote Play,需要游戏在后台状态下也能正常运行。许多游戏引擎在失去焦点或切换到后台状态时,会停止渲染或限制帧率以降低 CPU 使用率,并暂停音频播放。为保证远程流媒体正常运行,需要修改设置使游戏进程在后台也能继续运行。
1. 根据 Remote Play 连接状态的推荐策略¶
游戏需要检查 Remote Play 的连接状态,判断是否有远程用户正在连接。推荐的行为如下:
| 连接状态 | 推荐行为 |
|---|---|
| 未连接 | 维持现有游戏策略,切换到后台时可停止渲染和音频 |
| 连接中 | 在后台状态下也维持渲染,在后台状态下也维持音频输出 |
连接状态可通过状态事件回调(eventType: "Event",值 REMOTE_PLAY_CONNECTED / REMOTE_PLAY_DISCONNECTED)进行判断。
2. 维持后台渲染¶
即使在锁屏状态下,Remote Play 也需要能够捕获画面,因此需要持续运行渲染循环。检查项目示例如下:
- 不停止帧更新
- 维持渲染循环
- 维持摄像机渲染
- 维持 UI 更新
- 检查后台帧限制策略
Warning
若在后台状态下停止渲染,Remote Play 将持续发送最后一帧画面,或显示黑屏。
3. 维持后台音频输出¶
Remote Play 会捕获游戏进程输出的音频并分发给远程玩家。因此,需要禁用以下类型的后台音频阻断策略:
- 失去焦点时暂停音频
- 窗口停用时停止 Audio Engine
- 启用后台静音功能
Warning
若在后台状态下停止音频输出,远程玩家将无法听到游戏声音。
各引擎注意事项与参考¶
Unity¶
Unity 在默认情况下,切换到后台时可能会限制更新。使用锁屏 Remote Play 功能时,建议如下启用后台运行:
如果存在失去焦点时停止音频的自定义逻辑,请考虑 Remote Play 的连接状态进行异常处理。
Unreal Engine¶
Unreal Engine 项目中也需要确认是否有限制失去焦点时的 Tick、渲染或音频处理的设置。特别建议确认以下项目:
- Background Tick 的运行状况
- Focus Lost 时的 Pause 处理情况
- Audio Mixer 的运行状况
- 后台 FPS 限制策略
Remote Play 连接期间,需要实现即使在后台状态下也能维持正常游戏循环的方式。
推荐操作场景¶
- 用户切换到 Windows 锁屏状态
- Remote Play 客户端连接
- 游戏检测到连接状态,维持后台渲染和音频输出
- 继续游戏渲染
- 继续游戏音频输出
- Remote Play Plugin 正常捕获并发送画面和音频
- 远程用户实时接收游戏画面和声音
- 输入事件通过 Remote Play 输入
Control回调传递给游戏内部输入系统
必要确认事项概述
若要在锁屏环境中正常使用 Remote Play,需满足以下两个条件:
- 需在 Hive Console 的 Remote Play 设置中启用**不解除锁屏即可游玩**功能,并将输入事件传递给游戏内部输入系统。
- Remote Play 连接期间,即使在后台状态下也需要维持渲染和音频处理。
若任一条件不满足,可能因画面停止、声音输出错误、操作困难等问题导致无法正常运行。