Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Feedback Why is there no way to hide the mouse cursor when entering Play Mode?

Discussion in 'Editor & General Support' started by dgoyette, May 18, 2023.

  1. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,192
    This has frustrated me since moving from 2019 LTS to 2021 LTS. I figured I'd eventually just get used to the new way things work, but it's been about a year, and I still deal with this annoyance every day.

    Previously, under 2019.X versions of Unity, hiding the mouse cursor worked fine when entering play mode. You'd do something like this:

    Code (CSharp):
    1.     void Start()
    2.     {
    3.         Cursor.lockState = CursorLockMode.Locked;
    4.         Cursor.visible = false;
    5.     }
    Enter play mode, the cursor goes away, and you start playing.

    But started in Unity 2020, and in all versions since then, this code no longer works as-is. Instead, you first need to click somewhere into the Game view to get the mouse cursor to go away. Every single time I enter play mode, I need to click the Game view.

    Making this even more annoying is that until you click the game view, the mouse cursor's hovering all over the Editor, and if you're not careful, your first click might land on the "X" to close Unity, the Play button (so you cancel Play mode immediately) or some other part of the Unity UI that you had no intention of clicking.

    I'd be happy with some kludge to hiding the cursor, if anyone knows of a way, but so far I'm unaware of one. I'm really tired of needing to perform this extra click every time I enter play mode.

    FWIW, I initially reported this as a regression bug, but Unity responded it's intentional, and will not be fixed.

    Can we please have some way to hide the cursor when entering Play mode?
     
    Unifikation, IC_ and Kurt-Dekker like this.
  2. IC_

    IC_

    Joined:
    Jan 27, 2016
    Posts:
    61
    I have encountered this stupid issue as well
     
  3. IC_

    IC_

    Joined:
    Jan 27, 2016
    Posts:
    61
    Got the same response from the Unity team. I wrote a script that fixes this issue (It uses DllImport stuff) but I will not publish it publicly so that Unity team doesn't "fix" it and ruin our experience again. Anyone who struggles with the same issue, PM me and I will send you the script as soon as I can
     
    Last edited: Aug 5, 2023
    Unifikation likes this.
  4. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    648
    I'm finding that the cursor doesn't stay locked in multi-monitor setups even in player builds. Does anyone know of a better hack that doesn't use external DLL function calls?

    // Don't ever use this code. This is for demonstration purposes only.

    Code (CSharp):
    1. using System.Drawing;
    2. using System.Runtime.InteropServices;
    3. using UnityEngine;
    4.  
    5. public class CursorHack : MonoBehaviour
    6. {
    7.     [DllImport("user32.dll")]
    8.     static extern bool SetCursorPos(int X, int Y);
    9.  
    10.     [StructLayout(LayoutKind.Sequential)]
    11.     public struct POINT
    12.     {
    13.         public int X;
    14.         public int Y;
    15.  
    16.         public static implicit operator Point(POINT point)
    17.         {
    18.             return new Point(point.X, point.Y);
    19.         }
    20.     }
    21.  
    22.     void LateUpdate()
    23.     {
    24.         if (Cursor.lockState == CursorLockMode.Locked)
    25.             SetCursorPos(Screen.width / 2, Screen.height / 2);
    26.     }
    27. }
    28.  
     
    Last edited: Aug 8, 2023
  5. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,628
    That sounds like a bug. Can you report it?
     
    stonstad likes this.
  6. Until Unity does something about this, here is a solution. Obviously you can move out the
    UnityEditor
    portions into an editor script and hang onto the
    playModeStateChanged
    event if you want.
    Code (CSharp):
    1. using UnityEngine;
    2. #if UNITY_EDITOR
    3. using UnityEditor;
    4. #endif
    5.  
    6. public class TestComponent : MonoBehaviour
    7. {
    8.     private void Awake()
    9.     {
    10. #if UNITY_EDITOR
    11.         var gameWindow = EditorWindow
    12.             .GetWindow(typeof(EditorWindow).Assembly.GetType("UnityEditor.GameView"));
    13.         gameWindow.Focus();
    14.         gameWindow.SendEvent(new Event
    15.         {
    16.             button = 0,
    17.             clickCount = 1,
    18.             type = EventType.MouseDown,
    19.             mousePosition = gameWindow.rootVisualElement.contentRect.center
    20.         });
    21. #endif
    22.      
    23.         Cursor.lockState = CursorLockMode.Locked;
    24.         Cursor.visible = false;
    25.     }
    26. }

    ---

    Here is the same with some extras:
    https://github.com/LurkingNinja/com.lurking-ninja.game-utils/blob/main/Editor/GameViewExtensions.cs

    Tools/Lurking Ninja/Forced GameView focus
    checkbox menu point turning the service on and off. Also the GameView doesn't force focus if
    Play Unfocused
    is selected.
    You still need to add the cursor lock and visibility handling in an Awake method as normal.
     
    Last edited by a moderator: Aug 4, 2023
    Ryiah and dgoyette like this.
  7. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,192
    It's nice to see a workaround for this that doesn't require some external DLL imports. Thanks for sharing. This seems to do the trick for me.

    Another little trick you can use here, to avoid needing to have this component in every scene, is to tie into
    EditorApplication.playModeStateChanged
    . This causes the script to be loaded once when Unity launches, and it triggers the game view focus every time you enter play mode. Here's your code wrapped in that approach. Now you can just drop this script into any project, and it works without adding a component to anything in the scene:

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. [InitializeOnLoad]
    5. public class AutoFocusGameViewOnPlay
    6. {
    7.     // Static constructor that gets called when unity fires up.
    8.     static AutoFocusGameViewOnPlay()
    9.     {
    10.         EditorApplication.playModeStateChanged += (PlayModeStateChange state) =>
    11.         {
    12.             // If we're about to run the scene...
    13.             if (state == PlayModeStateChange.EnteredPlayMode)
    14.             {
    15.                 var gameWindow = EditorWindow.GetWindow(typeof(EditorWindow).Assembly.GetType("UnityEditor.GameView"));
    16.                 gameWindow.Focus();
    17.                 gameWindow.SendEvent(new Event
    18.                 {
    19.                     button = 0,
    20.                     clickCount = 1,
    21.                     type = EventType.MouseDown,
    22.                     mousePosition = gameWindow.rootVisualElement.contentRect.center
    23.                 });
    24.  
    25.             }
    26.         };
    27.     }
    28. }
    29.  
     
    Lurking-Ninja likes this.
  8. dgoyette likes this.
  9. IC_

    IC_

    Joined:
    Jan 27, 2016
    Posts:
    61
    Note that static constructors in Unity are called in seemingly random fashion (I guess each recompilation does a call). Better use [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
     
  10. It is not really relevant, even if what you describe is true, these are Editor scripts with
    InitializeOnLoad
    attribute, which means the static constructor runs upon project load and upon domain reload. Doesn't matter when, it should happen before the user can hit the play button, nothing else matters.
     
    spiney199 likes this.
  11. Unifikation

    Unifikation

    Joined:
    Jan 4, 2023
    Posts:
    1,073
    It's a regression, and one you should both be aware of (and now are) and able to internally call for it to be fixed.

    Please do get it fixed!
     
  12. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,628
    As per forum rules, we do not take posts on the forum as bug reports. Here are some guidelines for reporting bugs: https://unity.com/releases/editor/qa/bug-reporting

    And no, I am not "now aware" of the bug. Yes, there's a forum post complaining about it not working but there isn't nearly enough information in that forum post to investigate and fix it. Hence asking for a bug report, so it could be processed by QA: missing details filled out, reproduced, duplicate discovery done, added to the issue tracker, when it gets fixed actually verified against the same project that was submitted to confirm that it will fix the issue for the reporter.

    Keep in mind that folks that post on the forum like me do it because we want to help but it is not our job to do so and we cannot spend significant amount of time dealing with stuff reported here. We have dedicated team that looks at bug reports and tries to reproduce them all day long: but they only look at stuff that comes through the bug reporter (rather than forums).

    For everyone else reading, if you do end up reporting a bug, if you give me a bug number I can look at its status and tell you about it. I can also go bug the relevant team if you're not getting traction to see where it lies in their priority list.

    Anyway, let's stick to the topic at hand: mouse cursor hiding/locking.
     
  13. Unifikation

    Unifikation

    Joined:
    Jan 4, 2023
    Posts:
    1,073
    That's not good enough.

    It doesn't matter what your processes are in your company and organisation.

    It only matters that this is broken, and needs to be fixed, and that your company and your organisation have caused it to be broken.

    If your processes don't permit, nor encourage staff to get things fixed, that's on you, your bosses, the management and the organisation within the company you work. It should never be placed upon users that discover these breakages. Which reminds that this should have been discovered and prevented by the organisation of your company and its quality control.

    Please just get it fixed. Internally, since that's where this was broken.
     
  14. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,396
    All big software companies require bug reports for anything issue to be rectified.

    If you think that's not good enough, go make your own software company that doesn't take bug reports. See how that pans out for you.

    Otherwise stop disrupting every thread and harassing staff every time this comes up. You're making the forums worse and worse and contribute nothing of use.
     
    nehvaleem likes this.
  15. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    648
    Creating a reproduction project with associated video of the behavior, as seen with multiple monitors present, is on my list today. I'll reply back with a report id.
     
  16. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    648
    @Tautvydas-Zilys In a separate project I can confirm the mouse constrain and lock behavior works as expected in builds. This was totally user error on my part and I messed up.

    Thank you for the quick response here in the forums!
     
    LeonhardP and Tautvydas-Zilys like this.