diff --git a/Source/Editor/Windows/GameWindow.cs b/Source/Editor/Windows/GameWindow.cs index 4f9a18218..23558c396 100644 --- a/Source/Editor/Windows/GameWindow.cs +++ b/Source/Editor/Windows/GameWindow.cs @@ -21,7 +21,8 @@ namespace FlaxEditor.Windows private readonly GameRoot _guiRoot; private bool _showGUI = true; private bool _showDebugDraw = false; - private bool _isMaximized = false; + private bool _isMaximized = false, _isUnlockingMouse = false; + private bool _cursorVisible = true; private float _gameStartTime; private GUI.Docking.DockState _maximizeRestoreDockState; private GUI.Docking.DockPanel _maximizeRestoreDockTo; @@ -460,14 +461,20 @@ namespace FlaxEditor.Windows { if (Editor.StateMachine.IsPlayMode) { - Screen.CursorVisible = true; - Focus(null); - Editor.Windows.MainWindow.Focus(); - if (Editor.Windows.PropertiesWin.IsDocked) - Editor.Windows.PropertiesWin.Focus(); + // Cache cursor + _cursorVisible = Screen.CursorVisible; + _cursorLockMode = Screen.CursorLock; Screen.CursorVisible = true; if (Screen.CursorLock == CursorLockMode.Clipped) Screen.CursorLock = CursorLockMode.None; + + // Defocus + _isUnlockingMouse = true; + Focus(null); + _isUnlockingMouse = false; + Editor.Windows.MainWindow.Focus(); + if (Editor.Windows.PropertiesWin.IsDocked) + Editor.Windows.PropertiesWin.Focus(); } } @@ -552,9 +559,11 @@ namespace FlaxEditor.Windows Root.MousePosition = center; } - // Restore lock mode + // Restore cursor if (_cursorLockMode != CursorLockMode.None) Screen.CursorLock = _cursorLockMode; + if (!_cursorVisible) + Screen.CursorVisible = false; } } @@ -563,11 +572,16 @@ namespace FlaxEditor.Windows { base.OnEndContainsFocus(); - // Restore cursor visibility (could be hidden by the game) - Screen.CursorVisible = true; + if (!_isUnlockingMouse) + { + // Cache cursor + _cursorVisible = Screen.CursorVisible; + _cursorLockMode = Screen.CursorLock; - // Cache lock mode - _cursorLockMode = Screen.CursorLock; + // Restore cursor visibility (could be hidden by the game) + if (!_cursorVisible) + Screen.CursorVisible = true; + } } /// diff --git a/Source/Engine/Engine/Screen.cpp b/Source/Engine/Engine/Screen.cpp index b6cec67c6..a527bbcfe 100644 --- a/Source/Engine/Engine/Screen.cpp +++ b/Source/Engine/Engine/Screen.cpp @@ -15,7 +15,8 @@ Nullable Fullscreen; Nullable Size; -static CursorLockMode CursorLock = CursorLockMode::None; +bool CursorVisible = true; +CursorLockMode CursorLock = CursorLockMode::None; class ScreenService : public EngineService { @@ -25,6 +26,7 @@ public: { } + void Update() override; void Draw() override; }; @@ -88,12 +90,7 @@ Float2 Screen::GameViewportToScreen(const Float2& viewportPos) bool Screen::GetCursorVisible() { -#if USE_EDITOR - const auto win = Editor::Managed->GetGameWindow(true); -#else - const auto win = Engine::MainWindow; -#endif - return win ? win->GetCursor() != CursorType::Hidden : true; + return CursorVisible; } void Screen::SetCursorVisible(const bool value) @@ -107,6 +104,7 @@ void Screen::SetCursorVisible(const bool value) { win->SetCursor(value ? CursorType::Default : CursorType::Hidden); } + CursorVisible = value; } CursorLockMode Screen::GetCursorLock() @@ -137,6 +135,14 @@ void Screen::SetCursorLock(CursorLockMode mode) CursorLock = mode; } +void ScreenService::Update() +{ +#if USE_EDITOR + // Sync current cursor state in Editor (eg. when viewport focus can change) + Screen::SetCursorVisible(CursorVisible); +#endif +} + void ScreenService::Draw() { #if USE_EDITOR