瀏覽代碼

Fix flickering in embedded game when paused

Hilderin 9 月之前
父節點
當前提交
3580509fee
共有 2 個文件被更改,包括 47 次插入11 次删除
  1. 43 11
      editor/plugins/game_view_plugin.cpp
  2. 4 0
      editor/plugins/game_view_plugin.h

+ 43 - 11
editor/plugins/game_view_plugin.cpp

@@ -301,6 +301,7 @@ void GameView::_stop_pressed() {
 	}
 
 	_detach_script_debugger();
+	paused = false;
 
 	EditorNode::get_singleton()->set_unfocused_low_processor_usage_mode_enabled(true);
 	embedded_process->reset();
@@ -515,15 +516,26 @@ void GameView::_update_embed_menu_options() {
 }
 
 void GameView::_update_embed_window_size() {
-	if (embed_size_mode == SIZE_MODE_FIXED || embed_size_mode == SIZE_MODE_KEEP_ASPECT) {
-		//The embedded process control will need the desired window size.
-		EditorRun::WindowPlacement placement = EditorRun::get_window_placement();
-		embedded_process->set_window_size(placement.size);
+	if (paused) {
+		// When paused, Godot does not re-render. As a result, resizing the game window to a larger size
+		// causes artifacts and flickering. However, resizing to a smaller size seems fine.
+		// To prevent artifacts and flickering, we will force the game window to maintain its size.
+		// Using the same technique as SIZE_MODE_FIXED, the embedded process control will
+		// prevent resizing the game to a larger size while maintaining the aspect ratio.
+		embedded_process->set_window_size(size_paused);
+		embedded_process->set_keep_aspect(false);
+
 	} else {
-		//Stretch... No need for the window size.
-		embedded_process->set_window_size(Size2i());
+		if (embed_size_mode == SIZE_MODE_FIXED || embed_size_mode == SIZE_MODE_KEEP_ASPECT) {
+			// The embedded process control will need the desired window size.
+			EditorRun::WindowPlacement placement = EditorRun::get_window_placement();
+			embedded_process->set_window_size(placement.size);
+		} else {
+			// Stretch... No need for the window size.
+			embedded_process->set_window_size(Size2i());
+		}
+		embedded_process->set_keep_aspect(embed_size_mode == SIZE_MODE_KEEP_ASPECT);
 	}
-	embedded_process->set_keep_aspect(embed_size_mode == SIZE_MODE_KEEP_ASPECT);
 }
 
 void GameView::_hide_selection_toggled(bool p_pressed) {
@@ -787,7 +799,8 @@ void GameView::_window_close_request() {
 		embedded_process->reset();
 
 		// When the embedding is not complete, we need to kill the process.
-		if (embedded_process->is_embedding_in_progress()) {
+		// If the game is paused, the close request will not be processed by the game, so it's better to kill the process.
+		if (paused || embedded_process->is_embedding_in_progress()) {
 			// Call deferred to prevent the _stop_pressed callback to be executed before the wrapper window
 			// actually closes.
 			callable_mp(EditorRunBar::get_singleton(), &EditorRunBar::stop_playing).call_deferred();
@@ -795,6 +808,20 @@ void GameView::_window_close_request() {
 	}
 }
 
+void GameView::_debugger_breaked(bool p_breaked, bool p_can_debug) {
+	if (p_breaked == paused) {
+		return;
+	}
+
+	paused = p_breaked;
+
+	if (paused) {
+		size_paused = embedded_process->get_screen_embedded_window_rect().size;
+	}
+
+	_update_embed_window_size();
+}
+
 GameView::GameView(Ref<GameViewDebugger> p_debugger, WindowWrapper *p_wrapper) {
 	singleton = this;
 
@@ -984,6 +1011,8 @@ GameView::GameView(Ref<GameViewDebugger> p_debugger, WindowWrapper *p_wrapper) {
 	p_wrapper->set_override_close_request(true);
 	p_wrapper->connect("window_close_requested", callable_mp(this, &GameView::_window_close_request));
 	p_wrapper->connect("window_size_changed", callable_mp(this, &GameView::_update_floating_window_settings));
+
+	EditorDebuggerNode::get_singleton()->connect("breaked", callable_mp(this, &GameView::_debugger_breaked));
 }
 
 ///////
@@ -1053,15 +1082,18 @@ void GameViewPlugin::_window_visibility_changed(bool p_visible) {
 }
 
 void GameViewPlugin::_save_last_editor(const String &p_editor) {
-	if (p_editor != get_name()) {
+	if (p_editor != get_plugin_name()) {
 		last_editor = p_editor;
 	}
 }
 
 void GameViewPlugin::_focus_another_editor() {
 	if (window_wrapper->get_window_enabled()) {
-		ERR_FAIL_COND(last_editor.is_empty());
-		EditorInterface::get_singleton()->set_main_screen_editor(last_editor);
+		if (last_editor.is_empty()) {
+			EditorNode::get_singleton()->get_editor_main_screen()->select(EditorMainScreen::EDITOR_2D);
+		} else {
+			EditorInterface::get_singleton()->set_main_screen_editor(last_editor);
+		}
 	}
 }
 

+ 4 - 0
editor/plugins/game_view_plugin.h

@@ -122,6 +122,8 @@ class GameView : public VBoxContainer {
 	bool embed_on_play = true;
 	bool make_floating_on_play = true;
 	EmbedSizeMode embed_size_mode = SIZE_MODE_FIXED;
+	bool paused = false;
+	Size2 size_paused;
 
 	Rect2i floating_window_rect;
 	int floating_window_screen = -1;
@@ -186,6 +188,8 @@ class GameView : public VBoxContainer {
 	void _detach_script_debugger();
 	void _remote_window_title_changed(String title);
 
+	void _debugger_breaked(bool p_breaked, bool p_can_debug);
+
 protected:
 	void _notification(int p_what);