玩家控制开关
基本信息
| 属性 | 值 |
|---|---|
| 翻译键 | key.freecam.playerControl |
| 显示名 | Toggle Player Control (with Toggle)(en_US.lang) |
| 默认按键 | 未绑定(Keyboard.KEY_NONE) |
| 默认类别 | key.categories.freecam → Freecam |
| 构造位置 | ClientEventHandler 构造函数 |
| 注册方式 | ClientRegistry.registerKeyBinding(playerControlKey) |
| 事件 | InputEvent.KeyInputEvent(ClientEventHandler.onKeyInput) |
| 生效前提 | 必须按住 切换自由相机(F4),且在松开时触发 |
| 生效前提 2 | 自由相机必须已激活(FreecamController.togglePlayerControl() 首行判断) |
⚠️ 默认没有任何按键。显示名里的 (with Toggle) 提示了"需配合 F4 使用"。
触发条件与状态翻转
ClientEventHandler.onKeyInput 第三个分支:
} else if (!pressed && matchesKeyBinding(playerControlKey, key)) {
while (playerControlKey.isPressed()) {}
FreecamController.instance().togglePlayerControl();
tripodActivated = true;
}
FreecamController.togglePlayerControl()(FreecamController.java:217):
if (!active) return;
playerControlled = !playerControlled;
AboveHotbarHUD.renderTextAboveHotbar(
StatCollector.translateToLocal(
playerControlled ? "msg.freecam.control.player" : "msg.freecam.control.camera"),
20, true, true);
| 情形 | 结果 |
|---|---|
| 自由相机未激活 | 静默 return,无消息、无状态变化 |
| 已激活 | 翻转 playerControlled,输出 Controlling: Player 或 Controlling: Camera |
置位 tripodActivated 同样意味着本轮松手不会再切换自由相机。
开启后行为的三处变化
| 变化点 | 相机模式下 | 玩家操控模式下 |
|---|---|---|
FreecamController.tick() |
继续读 WASD 并移动相机 | 在第 6 步 if (playerControlled) return; 提前返回,相机完全不动 |
MixinMinecraft 的四个 @Inject |
freecam$shouldCancel() 为真 → 取消左键/中键/右键/取方块 |
为假 → 不取消,玩家可正常交互世界 |
MixinEntityRenderer.getMouseOver |
不注入,走原版逻辑(对相机做射线检测) | @Inject HEAD + cancellable 生效:改用 thePlayer.rayTrace(mc.playerController.getBlockReachDistance(), partialTicks) 并覆写 mc.objectMouseOver |
⚠️ 第三行意味着:玩家操控模式下准星判定回到玩家身上,方块高亮、破坏进度 会跟随玩家而不是相机——相机此时纯粹是一个旁观视角。
freecam$shouldCancel() 的定义是 isActive() && !isPlayerControlled(),
这四个点击补丁与 移动模式 的求值都依赖它。
移动键的处理
无论 playerControlled 与否,ClientEventHandler.onUnpressMovementKeys
(TickEvent.PlayerTickEvent,优先级 HIGHEST)在相机模式下每 tick 把 7 个原版移动键
的 KeyBinding 状态强制清除:
keyBindForward、keyBindBack、keyBindLeft、keyBindRight、keyBindJump、
keyBindSneak、keyBindSprint → 一律 KeyBinding.setKeyBindState(..., false)。
条件是 controller.isActive() && !controller.isPlayerControlled(),
所以玩家操控模式下这 7 个键不被清除——玩家仍能正常走动。
MixinMovementInputFromOptions 的 updatePlayerMoveState 注入是第二重保障。
相关条目
- 切换自由相机 - 必须按住的主按键
- 重置相机 - 结构完全对称的另一个组合键
- 自由相机状态机 -
playerControlled的全部读取点 - Mixin 加载阶段 - 四处受
isPlayerControlled影响的注入点 - 移动模式 - 玩家操控时该模式完全不参与求值