Add taunt button, Tab as Escape alternative, free cam Q/E removal

- OverviewMenu: taunt button (manual ping + close, hider/seek-only), Tab triggers the Escape chain (TypingGuard-gated)
- GameModeManager: LocalPlayerIsHider helper, allow E-ping in free cam (Q/E no longer used for movement)
- FreeCamController: vertical movement only via Space/Ctrl
- Icons: Icon_taunt (wired), Icon_firstperson_paint (unwired, for later)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Fable 5 committed 2026-07-12 15:22:47 +02:00
1 parent 1054bcd3d6
commit c6a22c1643
7 files changed
+269 -12

No files matched your search

@@ -6,7 +6,7 @@ using UnityEngine.InputSystem;
/// <summary>
/// Free-flying spectator camera on its own dedicated <see cref="CinemachineCamera"/>: WASD flight relative
/// to the view, Q/E (or Space/Left&#160;Ctrl) for down/up, mouse look. A <see cref="CharacterController"/>
/// to the view, Space/Left&#160;Ctrl for up/down, mouse look. A <see cref="CharacterController"/>
/// capsule makes it slide along world geometry instead of clipping. Driven by <see cref="FreeCamMode"/>
/// via <see cref="SetActive"/>; while inactive this component does nothing.
/// </summary>
@@ -170,14 +170,15 @@ public class FreeCamController : MonoBehaviour
if (kb.sKey.isPressed) dir -= transform.forward;
if (kb.dKey.isPressed) dir += transform.right;
if (kb.aKey.isPressed) dir -= transform.right;
if (kb.eKey.isPressed || kb.spaceKey.isPressed) dir += Vector3.up;
if (kb.qKey.isPressed || kb.leftCtrlKey.isPressed) dir -= Vector3.up;
// Q/E intentionally unbound: E is the taunt key and must work in free cam.
if (kb.spaceKey.isPressed) dir += Vector3.up;
if (kb.leftCtrlKey.isPressed) dir -= Vector3.up;
}
#else
dir += transform.forward * Input.GetAxisRaw("Vertical");
dir += transform.right * Input.GetAxisRaw("Horizontal");
if (Input.GetKey(KeyCode.E) || Input.GetKey(KeyCode.Space)) dir += Vector3.up;
if (Input.GetKey(KeyCode.Q) || Input.GetKey(KeyCode.LeftControl)) dir -= Vector3.up;
if (Input.GetKey(KeyCode.Space)) dir += Vector3.up;
if (Input.GetKey(KeyCode.LeftControl)) dir -= Vector3.up;
#endif
return dir;
}
+23 -4
View File
@@ -6,7 +6,8 @@ using UnityEngine.InputSystem;
#endif
/// <summary>
/// The Esc overview menu (the "Overview UI" canvas in Main). Owns ALL Escape handling: Esc toggles
/// The Esc overview menu (the "Overview UI" canvas in Main). Owns ALL Escape handling (Tab acts as an
/// alternative to Esc): Esc toggles
/// this panel as a modal pause overlay (gameplay suspended via <see cref="GameModeManager.SetPaused"/>);
/// while the session browser or match results overlay is open instead, Esc closes that, and while paint
/// mode is active Esc exits to the camera mode (Player Control, or First Person for the hunter). Buttons
@@ -41,6 +42,9 @@ public class OverviewMenu : MonoBehaviour
[SerializeField] private Button paintButton;
[SerializeField] private Button firstPersonButton;
[SerializeField] private Button freeCamButton;
[Tooltip("Triggers the hider's manual radar ping (same as the E key) and closes the menu. Only shown " +
"for a hider during Seek.")]
[SerializeField] private Button tauntButton;
private bool _open;
@@ -60,6 +64,7 @@ public class OverviewMenu : MonoBehaviour
if (paintButton) paintButton.onClick.AddListener(OnPaint);
if (firstPersonButton) firstPersonButton.onClick.AddListener(OnFirstPerson);
if (freeCamButton) freeCamButton.onClick.AddListener(OnFreeCam);
if (tauntButton) tauntButton.onClick.AddListener(OnTaunt);
}
private void OnDisable()
@@ -70,6 +75,7 @@ public class OverviewMenu : MonoBehaviour
if (paintButton) paintButton.onClick.RemoveListener(OnPaint);
if (firstPersonButton) firstPersonButton.onClick.RemoveListener(OnFirstPerson);
if (freeCamButton) freeCamButton.onClick.RemoveListener(OnFreeCam);
if (tauntButton) tauntButton.onClick.RemoveListener(OnTaunt);
}
private void Update()
@@ -147,6 +153,12 @@ public class OverviewMenu : MonoBehaviour
gameMode.SetPaused(false);
}
private void OnTaunt()
{
Close(resume: true);
if (MatchManager.Instance) MatchManager.Instance.RequestManualPing();
}
private void OnPlayerControl() => SwitchMode<PlayerControlMode>();
private void OnPaint() => SwitchMode<PaintMode>();
private void OnFirstPerson() => SwitchMode<FirstPersonMode>();
@@ -174,6 +186,12 @@ public class OverviewMenu : MonoBehaviour
if (matchResultButton)
matchResultButton.gameObject.SetActive(matchResultScreen && matchResultScreen.HasResults);
// Taunt/ping only does something for a hider during Seek (the server re-gates found hiders) -
// hide it otherwise, same pattern as the role-scoped mode buttons.
if (tauntButton)
tauntButton.gameObject.SetActive(gameMode.LocalPlayerIsHider && MatchManager.Instance &&
MatchManager.Instance.LocalSubPhase == MatchManager.MatchSubPhase.Seek);
SetModeButton<PlayerControlMode>(playerControlButton, modes, active);
SetModeButton<PaintMode>(paintButton, modes, active);
SetModeButton<FirstPersonMode>(firstPersonButton, modes, active);
@@ -191,13 +209,14 @@ public class OverviewMenu : MonoBehaviour
button.interactable = !(active is T);
}
// NOT TypingGuard-gated (GameplayKeyPressed): Esc must work even while a text field has focus.
// Esc is NOT TypingGuard-gated: it must work even while a text field has focus.
// Tab (alternative binding) IS gated so it stays usable for typing/field navigation.
private static bool EscapePressed()
{
#if ENABLE_INPUT_SYSTEM
return InputUtil.KeyPressedThisFrame(Key.Escape);
return InputUtil.KeyPressedThisFrame(Key.Escape) || InputUtil.GameplayKeyPressed(Key.Tab);
#else
return InputUtil.KeyPressedThisFrame(KeyCode.Escape);
return InputUtil.KeyPressedThisFrame(KeyCode.Escape) || InputUtil.GameplayKeyPressed(KeyCode.Tab);
#endif
}
}