Skip to content

fix: Avoid accidental PCam3D.up_target invalidation - #673

Open
BuddhaDom wants to merge 3 commits into
ramokz:mainfrom
BuddhaDom:main
Open

fix: Avoid accidental PCam3D.up_target invalidation#673
BuddhaDom wants to merge 3 commits into
ramokz:mainfrom
BuddhaDom:main

Conversation

@BuddhaDom

Copy link
Copy Markdown

The PCam3D.up_target property was getting invalidated when changing scenes in the editor.
Added a check to determine if the node is actually in the process of exiting the scene or if its tree_exiting() signal fired as part of a scene change in editor.

We began using this feature a decent amount for trippy scenes in our game and noticed we had to keep setting the property over and over. Thought it was an inherited scene or extended script issue but was able to replicate the issue in dev_scene_3d.tscn too.

I also took the liberty to comment out a portion of the script that was making the script unable to parse (I assumed it was an older implementation).

Comment on lines +1327 to +1348
# else:
# _follow_target_output_position = target_position + transform.basis.z * follow_distance
# var unprojected_position: Vector2 = _get_raw_unprojected_position()
# var viewport_width: float = get_viewport().size.x
# var viewport_height: float = get_viewport().size.y
# var camera_aspect: int = get_viewport().get_camera_3d().keep_aspect
# var visible_rect_size: Vector2 = get_viewport().get_visible_rect().size

# unprojected_position = unprojected_position - visible_rect_size / 2
# if camera_aspect == Camera3D.KEEP_HEIGHT:
# # Landscape View
# var aspect_ratio_scale: float = viewport_width / viewport_height
# unprojected_position.x = (unprojected_position.x / aspect_ratio_scale + 1) / 2
# unprojected_position.y = (unprojected_position.y + 1) / 2
# else:
# # Portrait View
# var aspect_ratio_scale: float = viewport_height / viewport_width
# unprojected_position.x = (unprojected_position.x + 1) / 2
# unprojected_position.y = (unprojected_position.y / aspect_ratio_scale + 1) / 2

# viewport_position = unprojected_position
# _set_follow_gizmo_line_position(follow_target.global_position)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Did a interpolation refactor recently, but must have missed this part.
It's fine to delete entirely rather than just commenting it out.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha, cleaned it up in cca39fa.

Comment on lines +1856 to +1857
if not Engine.is_editor_hint() or \
Engine.get_singleton(&"EditorInterface").get_edited_scene_root() == owner:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't Engine.is_editor_hint() suffice here given EditorInterface is only accessible in the editor anyway? Cannot seem to repro the issue when just using Engine.is_editor_hint() at least.

@BuddhaDom BuddhaDom Aug 8, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't quite help, at least on my end. It's not a matter of being in editor or not, it seems to be the fact that the node is "exiting tree" when you change tabs. Attaching an example of trying three different approaches on my end.
Could it possibly be device/OS specific? My Godot's v4.7.1.stable.arch_linux. Any other information I could provide to help?

2026-08-08_02-32-04.1.mp4

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay, I think the most sensible thing would be to do the same as how the _follow_target_tree_exiting does it, which is just:

func _up_target_tree_exiting() -> void:
	_has_up_target = false

That should address it?

@BuddhaDom BuddhaDom Aug 10, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That addressed it, but also happened to print out the following error on save if the node's been deleted (though this did not happen again if the scene was closed and reopened).
image
I added a NOTIFICATION_EDITOR_PRE_SAVE check in _notification() so that it clears out the variable too if it finds it's both set and outside the tree, essentially moving the original up_target = null there. (1f6d2d4)
This fixes the issue on my end: the up_target persists on scene change, and it no longer prints this error.
Would this be a preferable approach?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants