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

Camera2d has a one frame delay #28492

Closed
krdluzni opened this issue Apr 28, 2019 · 13 comments
Closed

Camera2d has a one frame delay #28492

krdluzni opened this issue Apr 28, 2019 · 13 comments

Comments

@krdluzni
Copy link
Contributor

Godot version:

3.1.1.stable.official

OS/device including version:

Windows 10

Issue description:

Camera2D with no margin or smoothing, attached to a Sprite with a simple movement script, follows the Sprite, but with a one frame delay on its position. This is most visible during the very start of the motion, and the very end.

Expected behaviour:
Camera2D follows the sprite exactly.

Other notes:
This looks like it's a result of internal node functionality happening on NOTIFICATION_INTERNAL_PROCESS before gamecode-driven position updates happen on NOTIFICATION_PROCESS.

Minimal reproduction project:

Random.zip
Launch, and use arrow keys to move. Watch at the start and end of movement to see the issue.

@aaronfranke
Copy link
Member

I notice this on my WIP PR for 2.5D demos. However, it's not the worst thing in the world, it kind of shows the velocity based on how close the character is to the edge of the screen.

@MightyPrinny
Copy link
Contributor

MightyPrinny commented May 6, 2019

IIRC you can use force_update_scroll to make it update immediately.

@krdluzni
Copy link
Contributor Author

krdluzni commented May 7, 2019

Indeed, that is a functioning workaround, but imo it shouldn't be necessary. If the camera is parented to something, and all the special margin/smoothing options are turned off, the natural expectation is that the effective position updates like any other transform, I think.

@ghost
Copy link

ghost commented Oct 16, 2019

@MightyPrinny Thanks for sharing the work around.

Also ran into this, don't know when this started exactly, but hadn't had this issue in older work. Even children attached to Camera2D will jitter about when the camera moves.

@bojidar-bg
Copy link
Contributor

This looks like it's a result of internal node functionality happening on NOTIFICATION_INTERNAL_PROCESS before gamecode-driven position updates happen on NOTIFICATION_PROCESS.

Camera2D should be updated in NOTIFICATION_TRANSFORM_CHANGED if there is no smoothing, so that's strange.

@ghost
Copy link

ghost commented Oct 16, 2019

@bojidar-bg Strange indeed, here is what I'm seeing at least. When starting and stopping, the attached node and the draw position lurches back and forth.

ezgif com-video-to-gif (2)

@NoodleSushi
Copy link

@MightyPrinny omg thank you so much force_update_scroll() worked well for me!

@Itachi217
Copy link

Still reproduceable in Godot 3.2.3.

@lawnjelly
Copy link
Member

It turns out this problem is very apparent with transform snapping, see #43554. I put full explanation there but it is caused by:

void Camera2D::_notification(int p_what) {
		case NOTIFICATION_TRANSFORM_CHANGED: {

			if (!is_processing_internal() && !is_physics_processing_internal())
				_update_scroll();

It is failing this check, not updating the scroll immediately, and only doing so in the next INTERNAL_PROCESS or INTERNAL_PHYSICS_PROCESS.
It can be 'fixed' by changing this check to always pass.
Presumably force_update_scroll() does something similar manually. I wonder if there is a reason why it cannot be updated immediately whether a race condition or something.

@ghost
Copy link

ghost commented Nov 30, 2020

@lawnjelly

We tested how many times does the _update_scroll(); is called under NOTIFICATION_TRANSFORM_CHANGED
and we find nothing, it never get called once.

We tested your idea, simply removing the "if statement" fixed it.

We think that NOTIFICATION_INTERNAL_PHYSICS_PROCESS and NOTIFICATION_INTERNAL_PROCESS has no use.

@lawnjelly
Copy link
Member

I did briefly talk about this with reduz. Although there does seem to be something problematic here, it is highly likely that the if statement was there for a reason - fixing it in this way could create another bug elsewhere.

Order of operations problems are often like this unfortunately, and it would probably require a fair bit of research and understanding to know whether this was a sensible fix. For now, certainly, @MightyPrinny 's workaround works.

@ghost
Copy link

ghost commented Dec 1, 2020

@lawnjelly

it is highly likely that the if statement was there for a reason

True, we thought the same thing.

fixing it in this way could create another bug elsewhere.

True, we are going to use this solution, and check if it will create any problem in our end.
the only problem we are expecting is overcalling the _update_scroll() which will effect performance.
as NOTIFICATION_TRANSFORM_CHANGED maybe called more times then NOTIFICATION_INTERNAL_PHYSICS_PROCESS.

In the other side, NOTIFICATION_INTERNAL_PHYSICS_PROCESS is called all time, regardless if something moved or not.

But we will leave it for devs to confirm our hypothesis.
Thank you.

-TechnoArt Studio

@akien-mga
Copy link
Member

Fixed by #46697.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
10 participants