Skip to content

Instantly share code, notes, and snippets.

@SixWays
Last active January 20, 2022 08:39
Show Gist options
  • Save SixWays/8b98dff4ab5ee9a25fc0e8acc2fa8dfa to your computer and use it in GitHub Desktop.
Save SixWays/8b98dff4ab5ee9a25fc0e8acc2fa8dfa to your computer and use it in GitHub Desktop.
Nicer cursor hiding/locking for Unity, including automatic alt-tab handling. Tested on 5.4+, probably fine 5.0+.
using UnityEngine;
using System.Collections;
public class CursorManager : MonoBehaviour {
#region Static
#region Singleton
/* Class is a MonoBehaviour to recieve OnApplicationFocus(bool) message
* If no instance already present, one will be created BEFORE scene load
* CursorManager placed in scene will override auto-created instance
* Any created instance will call DontDestroyOnLoad on itself, but still gets overridden by scene
*
* NOTE: UI Input modules will still respond to mouse clicks. Cannot disable this without a custom input module.
*/
private static CursorManager __instance;
private static CursorManager _instance {
get {
if (__instance == null){
Initialise();
}
return __instance;
}
}
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void Initialise(){
if (__instance == null){
new GameObject("CursorManager").AddComponent<CursorManager>();
}
}
#endregion
#region API
/// <summary>
/// If false, cursor will always remain locked and invisible in VR
/// </summary>
public static bool showInVR {
get {return _instance._showInVR;}
set {_instance._showInVR = value;}
}
private static bool _vr {
get {return UnityEngine.VR.VRSettings.enabled && !showInVR;}
}
/// <summary>
/// Should be either CONFINED or LOCKED
/// </summary>
/// <value>The cursor mode when active.</value>
public static CursorLockMode modeWhenActive {
get {return _instance._modeWhenActive;}
set {_instance._modeWhenActive = value;}
}
/// <summary>
/// Stored for alt-tab
/// </summary>
private static bool _targetActive;
public static bool isActive {
get {return _targetActive;}
private set {_targetActive = value;}
}
public static void SetActive(bool active){
isActive = active;
if (_vr) {
// Lock and hide in VR
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
} else {
Cursor.visible = isActive;
Cursor.lockState = isActive ? modeWhenActive : CursorLockMode.Locked;
}
}
#endregion
#endregion
#region Instance
#region Fields
[SerializeField][Tooltip("If false, cursor always hidden and locked in VR")]
private bool _showInVR = false;
[SerializeField][Tooltip("Should be either CONFINED or NONE")]
private CursorLockMode _modeWhenActive = CursorLockMode.Confined;
#endregion
#region Messages
void Awake () {
if (__instance != null) {
Destroy(__instance);
}
__instance = this;
DontDestroyOnLoad(gameObject);
if (_vr){
SetActive(false);
}
}
void OnDestroy(){
if (__instance == this){
__instance = null;
}
}
private void OnApplicationFocus(bool focus){
if (focus){
SetActive(isActive);
}
}
#endregion
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment