Danro/Assets/Scripts/Utilities/AutoCursorHider.cs

79 lines
3.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Linq;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
public class AutoCursorHider : MonoBehaviour
{
[Header("Поведение")]
[Tooltip("Сколько секунд после движения мыши держать курсор видимым")]
public float mouseVisibleHold = 1.0f;
[Tooltip("Блокировать ли курсор, когда он скрыт (Locked)") ]
public bool lockWhenHidden = false;
[Tooltip("Начинать со скрытого курсора")]
public bool startHidden = true;
private float _lastMouseMoveTime = -999f;
private bool _visible;
private void Awake()
{
SetCursorVisible(!startHidden);
}
private void Update()
{
bool mouseMoved = WasMouseMovedOrClickedThisFrame();
if (mouseMoved)
_lastMouseMoveTime = Time.unscaledTime;
bool nonPointerInput = WasKeyboardOrGamepadThisFrame();
// Показать курсор сразу при движении мыши
if (mouseMoved && !_visible)
SetCursorVisible(true);
// Скрыть курсор при управлении клавишами/геймпадом
if (nonPointerInput && _visible)
SetCursorVisible(false);
// Если мышь не трогали какое-то время — можно снова спрятать (опционально)
if (_visible && !mouseMoved && (Time.unscaledTime - _lastMouseMoveTime) > mouseVisibleHold && nonPointerInput)
SetCursorVisible(false);
}
private void SetCursorVisible(bool show)
{
if (_visible == show) return;
_visible = show;
Cursor.visible = show;
Cursor.lockState = show ? CursorLockMode.None
: (lockWhenHidden ? CursorLockMode.Locked : CursorLockMode.None);
// Совет: для UI-меню лучше Confined вместо Locked, если хочется скрыть не блокируя:
// Cursor.lockState = show ? CursorLockMode.None : CursorLockMode.Confined;
}
private static bool WasMouseMovedOrClickedThisFrame()
{
if (Mouse.current == null) return false;
if (Mouse.current.delta.ReadValue().sqrMagnitude > 0) return true;
if (Mouse.current.scroll.ReadValue().y != 0) return true;
return Mouse.current.leftButton.wasPressedThisFrame ||
Mouse.current.rightButton.wasPressedThisFrame ||
Mouse.current.middleButton.wasPressedThisFrame;
}
private static bool WasKeyboardOrGamepadThisFrame()
{
bool kb = Keyboard.current != null && Keyboard.current.anyKey.isPressed;
bool gp = Gamepad.current != null && Gamepad.current.allControls.Any(c => c is ButtonControl { wasPressedThisFrame: true });
return kb || gp;
}
// Публичные методы, если нужно управлять вручную
public void ForceShowCursor() => SetCursorVisible(true);
public void ForceHideCursor() => SetCursorVisible(false);
}