After some investigation and assistance from crazy_stewie
, we managed to determine the cause of the issue.
First, we disabled the render server using RenderingServer.render_loop_enabled = false
when we started the transition and drew the next frame using RenderingServer.force_draw.call_deferred()
. This helped us confirm that the frame was being rendered incorrectly for the next frame, sometime between the transition starting and when the camera position was set.
Adding a breakpoint, we were also able to confirm that the camera position was set correctly during that frame as well, but it was still rendering in the incorrect position.
We also used the following code to see when the frames were drawn:
This, coupled with other debugging prints helped point out the fact that there was a frame being rendered with the position set to the correct value, but still rendering in the incorrect place.
As it turns out, as crazy_stewie
explained, the camera can be thought of as having two different representations; the camera is just a fancy interface to a viewport in the RenderingServer
, which does the actual rendering. The function to force the camera to use the new position is align()
. Calling this function after setting the position fixes the issue.
Inspecting the code, it appears that align()
takes the global position into account when updating its internal representation before calling update_scroll()
which updates the viewport. Adding a debugging print for the update_scroll
function also reveals that it is called before the frame is rendered, but since it doesn’t take the global position into account, the viewport is not updated correctly.
Calling align()
fixes the problem. Consider the following code:
This results in the following (abridged) log:
Setting camera position to (-120, -73)
Smoothing enabled? false; Target position: (136, -49)
Smoothing enabled? false; Target position: (-120, -73)
update_scroll
Pre Draw
Post Draw
As you can see, the target position isn’t updated unless we call align
even though we set the position and update_scroll
, which updates the viewport in the RenderingServer
, will use the incorrect position (the target position) if we don’t call align.