Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Saving sub-scenes will mess up the display of the main scene on the 2D screen #90301

Closed
Rindbee opened this issue Apr 6, 2024 · 5 comments · Fixed by #90317 or #90432
Closed

Saving sub-scenes will mess up the display of the main scene on the 2D screen #90301

Rindbee opened this issue Apr 6, 2024 · 5 comments · Fixed by #90317 or #90432

Comments

@Rindbee
Copy link
Contributor

Rindbee commented Apr 6, 2024

Tested versions

v4.3.dev5.official [c9c17d6] good
f47f4a0 bad

System information

Linux Mint 21.3 (Virginia) - X11 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 1050 Ti (nvidia; 535.161.07) - Intel(R) Core(TM) i5-7300HQ CPU @ 2.50GHz (4 Threads)

Issue description

Saving the sub-scene and switching to the main scene reloads the scene, and it seems like the position calculation of something is dependent on the current camera.

If there is a enabled (default value) Camera2D node in the main scene, some things in the main scene will be displayed in the wrong position after reloading. For example, the position of the camera screen rectangle. Parallax2D's screen_offset may also change.

0.mp4

Closing and reopening the scene will display correctly.

Steps to reproduce

  1. Download and use godot to open the MRP;
  2. Open main.tscn;
  3. Open sub.tscn, and save;
  4. Switch to the tab of main.tscn, it will be automatically reloaded, and the displayed content will be messed up after reloading.

Minimal reproduction project (MRP)

wrong_display.zip

@AThousandShips
Copy link
Member

CC @ajreckof @KoBeWi

@ajreckof
Copy link
Member

ajreckof commented Apr 6, 2024

it seems the Camera is always rendered at the exact same position and everything else is rendered based on there relative position as if it became the actual Camera of the 2D editor. The exact position seems to depend on the size of the 2D Editor

@Rindbee
Copy link
Contributor Author

Rindbee commented Apr 6, 2024

I discovered that the auto-reload here causes make_current() to be called when entering the scene tree, because Camera2D::_is_editing_in_editor() (i.e. is_part_of_edited_scene()) is evaluated to false.

if (!_is_editing_in_editor() && enabled && !viewport->get_camera_2d()) {
make_current();
}

godot/scene/main/node.cpp

Lines 2573 to 2576 in e5b4ef8

bool Node::is_part_of_edited_scene() const {
return Engine::get_singleton()->is_editor_hint() && is_inside_tree() && get_tree()->get_edited_scene_root() &&
get_tree()->get_edited_scene_root()->get_parent()->is_ancestor_of(this);
}

This may be due to the current editing scene root not being set to the main scene root after switching tabs but before auto-reloading.

@KoBeWi
Copy link
Member

KoBeWi commented Apr 7, 2024

is_part_of_edited_scene() technically returns true for siblings of edited scene, I think we could check straight for the root viewport instead of using scene root parent.

EDIT:
Not sure if it's possible without referencing editor stuff, so it can't be done when the method is in Node.

@Rindbee
Copy link
Contributor Author

Rindbee commented Apr 9, 2024

It doesn't seem to be fully fixed by #90317. get_tree()->get_edited_scene_root() has not changed.

1

It seems that we can not use repace_by, because the diffs have been packed before.

EditorProgress ep("update_scene", TTR("Updating Scene"), 2);
ep.step(TTR("Storing local changes..."), 0);
// Pack first, so it stores diffs to previous version of saved scene.
Error err = pscene->pack(edited_scene[p_idx].root);
ERR_FAIL_COND_V(err != OK, false);
ep.step(TTR("Updating scene..."), 1);
Node *new_scene = pscene->instantiate(PackedScene::GEN_EDIT_STATE_MAIN);
ERR_FAIL_NULL_V(new_scene, false);

So directly call EditorNode::set_edited_scene() to set new_scene, and then delete old_root to complete the replacement.

diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index 72225fd454..bdc6504417 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -722,8 +722,7 @@ bool EditorData::check_and_update_scene(int p_idx) {
 
                new_scene->set_scene_file_path(edited_scene[p_idx].root->get_scene_file_path());
                Node *old_root = edited_scene[p_idx].root;
-               edited_scene.write[p_idx].root = new_scene;
-               old_root->replace_by(new_scene, false, false);
+               EditorNode::get_singleton()->set_edited_scene(new_scene);
                memdelete(old_root);
                edited_scene.write[p_idx].selection = new_selection;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment