跳转至

启用锁屏输入回调

当主机 PC 切换到 Windows 锁屏界面时,OS 安全策略会阻止 OS 级别的键盘和鼠标输入。在远程环境中,画面和音频流仍然可以传输,但无法进行实际的游戏操作。

过去,远程用户需要输入 Windows 账户密码来解除锁定。然而,这种方式存在暴露 PC 完整控制权限的风险,且连接流程也较为繁琐。

Remote Play Plugin 在 Hive Console 的 Remote Play 设置中提供了**不解除锁屏即可游玩**功能。启用此功能后,键盘、鼠标、触摸、摇杆、滚轮、缩放等所有输入事件将直接传递至游戏回调

主要行为

  • 基于回调的分发:所有输入事件将以 eventType: "Control" 的形式传递至通过 RegisterCallback 注册的回调函数。无论锁定状态如何均按相同方式运作,解锁后回调分发仍会持续。
  • 绕过 OS 输入路径:不使用 OS 的 SendInput 路径,无论 Windows 锁定状态如何,都能接收一致的输入事件。
  • 直接注入游戏:游戏将回调接收到的输入数据直接注入内部输入系统,在锁定状态和正常状态下均处理相同的操作。

前置准备

在应用此功能之前,请准备以下内容:

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 锁屏环境中 SendInputSendKey 等 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 功能时,建议如下启用后台运行:

Application.runInBackground = true;

如果存在失去焦点时停止音频的自定义逻辑,请考虑 Remote Play 的连接状态进行异常处理。

Unreal Engine

Unreal Engine 项目中也需要确认是否有限制失去焦点时的 Tick、渲染或音频处理的设置。特别建议确认以下项目:

  • Background Tick 的运行状况
  • Focus Lost 时的 Pause 处理情况
  • Audio Mixer 的运行状况
  • 后台 FPS 限制策略

Remote Play 连接期间,需要实现即使在后台状态下也能维持正常游戏循环的方式。

推荐操作场景

  1. 用户切换到 Windows 锁屏状态
  2. Remote Play 客户端连接
  3. 游戏检测到连接状态,维持后台渲染和音频输出
    • 继续游戏渲染
    • 继续游戏音频输出
  4. Remote Play Plugin 正常捕获并发送画面和音频
  5. 远程用户实时接收游戏画面和声音
  6. 输入事件通过 Remote Play 输入 Control 回调传递给游戏内部输入系统

必要确认事项概述

若要在锁屏环境中正常使用 Remote Play,需满足以下两个条件:

  • 需在 Hive Console 的 Remote Play 设置中启用**不解除锁屏即可游玩**功能,并将输入事件传递给游戏内部输入系统。
  • Remote Play 连接期间,即使在后台状态下也需要维持渲染和音频处理。

若任一条件不满足,可能因画面停止、声音输出错误、操作困难等问题导致无法正常运行。

相关文档