92 lines
3.1 KiB
C#
92 lines
3.1 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
|
|
namespace Ashwild.UI
|
|
{
|
|
/// <summary>
|
|
/// Screenshot/capture utility: one keypress hides (and restores) every Canvas in the scene at
|
|
/// once, so the world can be photographed with no HUD, crosshair, notifications or menus on top.
|
|
/// It toggles each root Canvas's <see cref="Canvas.enabled"/> rather than deactivating GameObjects,
|
|
/// so animations, timers and gameplay keep running untouched behind the hidden UI.
|
|
///
|
|
/// This is a deliberate, isolated exception to the "InputManager owns all input" rule: it is not a
|
|
/// gameplay action and never goes through the Send-Messages path, so it reads the key straight from
|
|
/// <see cref="Keyboard"/> instead of the action asset. Canvases are re-queried on every toggle, so
|
|
/// windows opened after hiding are still caught the next time the state flips.
|
|
/// </summary>
|
|
[DisallowMultipleComponent]
|
|
public class HudVisibilityToggle : MonoBehaviour
|
|
{
|
|
#region Serialized Fields
|
|
|
|
[Header("Input")]
|
|
[Tooltip("Key that toggles all UI on/off (default F8).")]
|
|
[SerializeField] private Key toggleKey = Key.F8;
|
|
|
|
[Header("Exclusions")]
|
|
[Tooltip("Root canvases that must stay visible even when the HUD is hidden (e.g. a debug overlay).")]
|
|
[SerializeField] private List<Canvas> alwaysVisible = new List<Canvas>();
|
|
|
|
#endregion
|
|
|
|
#region State
|
|
|
|
/// <summary>
|
|
/// True while the UI is currently hidden — the next press restores it.
|
|
/// </summary>
|
|
private bool hidden;
|
|
|
|
#endregion
|
|
|
|
#region Unity Lifecycle
|
|
|
|
/// <summary>
|
|
/// Polls the toggle key each frame and flips UI visibility on a fresh press.
|
|
/// </summary>
|
|
private void Update()
|
|
{
|
|
Keyboard keyboard = Keyboard.current;
|
|
if (keyboard == null) return;
|
|
|
|
if (keyboard[toggleKey].wasPressedThisFrame)
|
|
ToggleHud();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public API
|
|
|
|
/// <summary>
|
|
/// Flips the hidden state and re-applies it to every root canvas in the scene.
|
|
/// </summary>
|
|
public void ToggleHud()
|
|
{
|
|
hidden = !hidden;
|
|
ApplyVisibility();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Internal Helpers
|
|
|
|
/// <summary>
|
|
/// Enables or disables every root Canvas to match the current hidden state, skipping any
|
|
/// canvas listed in <see cref="alwaysVisible"/>. Only root canvases are touched — nested
|
|
/// canvases follow their parent's rendering, so toggling them too would be redundant.
|
|
/// </summary>
|
|
private void ApplyVisibility()
|
|
{
|
|
Canvas[] canvases = FindObjectsByType<Canvas>(FindObjectsInactive.Exclude, FindObjectsSortMode.None);
|
|
foreach (Canvas canvas in canvases)
|
|
{
|
|
if (canvas == null || !canvas.isRootCanvas) continue;
|
|
if (alwaysVisible.Contains(canvas)) continue;
|
|
canvas.enabled = !hidden;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|