-
-
Notifications
You must be signed in to change notification settings - Fork 21.7k
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
Eliminates SpringArm update lag when changing SpringArm length #36930
Eliminates SpringArm update lag when changing SpringArm length #36930
Conversation
I've updated it to stop unnecessary gizmo updates. The start of the method is now if (p_length == spring_length) {
return;
} because there is nothing to update if the new length is the same as the current length. |
The implementation seems good now, but I'm not sure if the bug described is actually valid. Like all physics code,
So forcing a recalculation here might actually go against Godot's design. |
The issue is that any code dependent on the position of a child of the SpringArm node won't be updated until the frame after the SpringArm length updates. Example:
This leads to the camera position lagging the angle by one frame, when they should be updated during the same frame (at least for it to look good). The other option is to make the process_spring() function public instead of private and let the developer call it when needed. Though, this adds more burden onto the developer to identify and avoid this issue. It also "might actually go against Godot's design" because it would allow process_spring() to be called outside of the physics frame. If the priority is to adhere to "Godot's design" over responsive implementation, then I'll just have to create a custom SpringArm object that isn't bound by the physics frame. |
This might no longer be needed after #37911. SpringArm was running |
I've taken an older version of my project (where the issue still existed) and removed everything except what's necessary to reproduce the issue. I tested the simplified project using a custom build with the changes from #37911 and #37964, but the issue still remained. I've attached the project if you want to check it out for yourself. Important notes:
|
This change will result in the same crash seen in #32876 and fixed by #37911 and #37964. Unfortunately, to be able to check for collisions, With regards the example project provided, the reason the spring length adjustment is seen in the frame after the camera angle is changed, is because the spring length is being adjusted in the frame after the camera angle is changed. This is due to the way the scripts are constructed in the example project. The camera angles are adjusted in the I've used the following single script on the
|
Closing as this change is incorrect, as described in the previous comment. |
Desciption
If the SpringArm's length is updated, its children won't update until the next frame because the process_spring() function won't be called again until the next frame. Any code that needs the position of its children to update in the same frame as the SpringArm length is updated won't get the values based on the updated length until the next frame.
The fix makes the set_length() function only change the SpringArm length when the new length is different than the current length and calls the process_spring() function to update the SpringArm and its children with the new length, which eliminates the lag.
Before/After Example
The zip file contains 1 second videos of where the bug occurs, before and after the fix (the videos are from 3.2, but affected code is also present in 3.1, 3.2, and 4.0).
The update lag is most apparent when the camera is rotating while the length changes. In the videos, when the camera rotates to its maximum rotation above the character, the SpringArm zooms out the camera a little after the rotation has stopped because the SpringArm's update lags doesn't update its children until 1 frame after the length is updated.
The effect of the update lag can be seen by looking at the shadow to the left of the character in both videos and comparing them.
The update lag can also be seen in the output. The top value is the new length, and the next two values are two calculations of the length to a child object of the SpringArm. Because the SpringArm didn't update in the same frame the length was changed, the second and third values lag the first (in the before video).
SpringArm_Update_Bug_Before_After_Fix.zip
Affected Versions
3.1, 3.2, and 4.0