Browse Source

Fixed bug transitioning from simulation mode to game mode in editor. (#8822)

Code to enter/exit simulation mode or game mode is not instantaneous, they cannot be called one after another at the same time without causing out of order events for creation and destruction of game entities.

To solve the problem, the code that makes the transition at the top level (`CryEdit.cpp`), it will exit simulation mode first and schedule the activation of game mode for the next frame.

Transitions tested:
- Editor mode to Game mode. Works.
- Editor mode to Simulation model. Works.
- Game mode to Simulation model. Not possible.
- Simulation mode to Game mode. Fixed by this PR.

Fixes #8714 

Signed-off-by: moraaar <[email protected]>
moraaar 3 years ago
parent
commit
d25f305783
2 changed files with 26 additions and 9 deletions
  1. 21 0
      Code/Editor/CryEdit.cpp
  2. 5 9
      Code/Editor/IEditorImpl.cpp

+ 21 - 0
Code/Editor/CryEdit.cpp

@@ -46,6 +46,8 @@ AZ_POP_DISABLE_WARNING
 #include <AzCore/StringFunc/StringFunc.h>
 #include <AzCore/Utils/Utils.h>
 #include <AzCore/Console/IConsole.h>
+#include <AzCore/EBus/IEventScheduler.h>
+#include <AzCore/Name/Name.h>
 
 // AzFramework
 #include <AzFramework/Components/CameraBus.h>
@@ -2466,6 +2468,25 @@ void CCryEditApp::OnViewSwitchToGame()
     {
         return;
     }
+
+    // If switching on game mode...
+    if (!GetIEditor()->IsInGameMode())
+    {
+        // If simulation mode is enabled...
+        uint32 flags = GetIEditor()->GetDisplaySettings()->GetSettings();
+        if (flags & SETTINGS_PHYSICS)
+        {
+            // Disable simulation mode
+            OnSwitchPhysics();
+
+            // Schedule for next frame to enable game mode
+            AZ::Interface<AZ::IEventScheduler>::Get()->AddCallback(
+                [this] { OnViewSwitchToGame(); },
+                AZ::Name("Enable Game Mode"), AZ::Time::ZeroTimeMs);
+            return;
+        }
+    }
+
     // close all open menus
     auto activePopup = qApp->activePopupWidget();
     if (qobject_cast<QMenu*>(activePopup))

+ 5 - 9
Code/Editor/IEditorImpl.cpp

@@ -866,18 +866,14 @@ bool CEditorImpl::SelectColor(QColor& color, QWidget* parent)
 
 void CEditorImpl::SetInGameMode(bool inGame)
 {
-    static bool bWasInSimulationMode(false);
-
-    if (inGame)
+    if (IsInSimulationMode())
     {
-        bWasInSimulationMode = GetIEditor()->GetGameEngine()->GetSimulationMode();
-        GetIEditor()->GetGameEngine()->SetSimulationMode(false);
-        GetIEditor()->GetGameEngine()->RequestSetGameMode(true);
+        return;
     }
-    else
+
+    if (m_pGameEngine)
     {
-        GetIEditor()->GetGameEngine()->RequestSetGameMode(false);
-        GetIEditor()->GetGameEngine()->SetSimulationMode(bWasInSimulationMode);
+        m_pGameEngine->RequestSetGameMode(inGame);
     }
 }