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 limits doesn't work well if limit_smoothed is enabled #56336

Open
dannygaray60 opened this issue Dec 30, 2021 · 22 comments · Fixed by #63083 · May be fixed by #63773
Open

Camera2D limits doesn't work well if limit_smoothed is enabled #56336

dannygaray60 opened this issue Dec 30, 2021 · 22 comments · Fixed by #63083 · May be fixed by #63773

Comments

@dannygaray60
Copy link

Godot version

3.4.2 stable

System information

Windows 10, GLES2, Intel HD Graphics 610

Issue description

Since godot version 3.4.1 the camera limits stop working properly if limit_smoothed is enabled, while in previous versions it never gave problems. When starting the scene, you notice a movement of the camera as if it was being moved:

0.Bug.Camera.Limit.and.smoth.limit_Trim.mp4

And sometimes when setting certain limits, the camera moves slightly.

In 3.3.3 works fine:

1.good.with.3.3.3.stable.mp4

But this happens with 3.4.1 and 3.4.2

2.bad.with.3.4.2.stable.mp4

Steps to reproduce

Enable limit_smoothed and smoothing_enabled to true on Camera2D.

Minimal reproduction project

TestCamera2DLimits.zip

@dannygaray60
Copy link
Author

I already seen the previous bug report but I still have this problem , although I used force_update_scroll() and reset_smoothing() on _ready() of Camera2D

@lawnjelly
Copy link
Member

lawnjelly commented Dec 30, 2021

Unfortunately some of the artifacts have expired since then but if you look on here you can see some of the commits since 3.3.3. Interestingly #46717 was present in 3.3.3 (which is probably the biggest change), so you most likely looking at a commit after March 8th,

and to July 27th which is the date of 3.4 beta 2 which shows the new behaviour in my tests.

https://github.com/godotengine/godot/commits/3.x/scene/2d/camera_2d.cpp

Edit

Have bisected it and this seems to be the commit causing the change in behaviour:
#49409
@ekumlin

@ek68794998
Copy link
Contributor

Unfortunately I'm away for holidays so I don't have access to my Godot stuff until next week.

The first behavior you're seeing is by design based on the changes in 3.4 betas and eventually 3.4.0+. What is interesting to me is that the reset/force is not working as expected — invoking the reset should be calling literally the identical code that my change skips (when smoothing is enabled). It's possible the timing is off (i.e., the reset call is too early), but until I can run the code I can't say for sure.

As for the second issue, I've never seen anything like that in my platformer despite using limits and smoothing in tandem. Unfortunately, like the other issue, I'll have to run the repro project before I can figure out what's going on there and if it's related to my change.

I'll give these issues a look next week when I'm back at my desk if no one else is able to before then.

@ek68794998
Copy link
Contributor

I looked into this a bit. It looks like some behavior has changed since I tested and implemented the original PR #49409 back in June. Specifically, PR #50935 changed how reset_smoothing() works, meaning that it no longer executes its commands in the same order, which prevents it from working as expected in this case.

I tested this by executing reset_smoothing() twice in your example:
image

And that works as expected:
godot-56336-2xreset

Granted, this is a really ugly workaround. Unfortunately I'm not sure of the rationale for the above-mentioned PR (#50935); maybe @Vitika9 can provide some insight as to exactly what changed in this PR and perhaps what the best resolution is now.

@akien-mga
Copy link
Member

Relevant issue: #50807. CC @Razoric480

@akien-mga akien-mga added this to the 3.5 milestone Jan 5, 2022
@dannygaray60
Copy link
Author

I have applied reset_smoothing() as ekumlin said. However the problem continues if the camera limit_smoothed is enabled together with the smoothing enabled and these two options are necessary to guarantee a smooth and nice camera movement from what I have experienced as someone who loves to play platform games xD I repeat, limit_smoothed and smoothing_enabled enabled at the same time causes the problem I mentioned.

@VitikaSoni
Copy link
Contributor

VitikaSoni commented Jan 6, 2022

Unfortunately I'm not sure of the rationale for the above-mentioned PR (#50935); maybe @Vitika9 can provide some insight as to exactly what changed in this PR and perhaps what the best resolution is now.

As calling force_update_scroll() right before calling reset_smoothing() was giving the intended behavior in #50807, therefore _update_scroll() was made to be executed first.
In the case which is mentioned in this issue, the camera is already at it's limit(top and bottom). The issue is getting resolved by calling reset_smoothing() twice because in this case _update_scroll() needs to be executed after setting smoothed_camera_pos or this can also be achieved by calling force_update_scroll() after reset_smoothing().

issue.mp4

May be we need to call _update_scroll() both before and after setting smoothed_camera_pos in the reset_smoothing() method, sorry if it sounds weird.


@ek68794998
Copy link
Contributor

So it looks like the prescription (for now at least) would be to call them in a specific order (first reset, then force update), rather than calling one or the other or force → reset.

Might be worth considering whether we should A) take the suggestion you mentioned (update then fix camera pos then update again), B) document this specific way of doing it, or C) have a new method specifically for forcing a camera into its limits immediately with no smoothing... or, D) another suggestion I haven't thought of.

@Razoric480
Copy link
Contributor

It implies a deeper symptom, though I'm not really sure how to fix it beyond the ways already outlined.

@Zireael07
Copy link
Contributor

Regardless of what is done further, for now this should be documented.

@madmiraal
Copy link
Contributor

Is this actually a Godot bug or is it just an unexpected change in behaviour in your project following a bug fix?

It appears to me that the camera is now moving (smoothly) within the limits (and default drag margins) specified, whereas before it wasn't (a bug).
Looking at the MRP, the difference between the camera top and bottom limits are slightly less than camera viewport height (with the zoom at 0.5). I've created a white ColorRect with the dimensions of the camera limits to show this:
Camera Limits
This would cause the movement you're now seeing when moving the player up or down.

@akien-mga
Copy link
Member

Related issue: #56913.

@dannygaray60
Copy link
Author

dannygaray60 commented Jun 15, 2022

Still in version 3.4.4 stable the problem persists. Testing I have noticed that the only responsible is to checking smoothing_enabled. And that the speed of moving the camera to the player's position depends also on smoothing_speed. Putting reset_smoothing() and _update_scroll() on ready of camera don't work

2022-06-15-11-24-08.mp4

@dannygaray60
Copy link
Author

I have tried version 3.5.rc7 and the problem persists.

@akien-mga akien-mga reopened this Jul 25, 2022
@madmiraal
Copy link
Contributor

What problem exactly persists?

@dannygaray60
Copy link
Author

@madmiraal when smooth is activated to a 2d camera, at the start of the scene the camera2d moves to its starting point (the player's position) this problem was not present in godot 3.3 but with the change to godot 3.4.1 this happens:

smooth.mp4

when that initial camera movement should not happen. To avoid it, I have to deactivate the smooth and the camera will position itself on the player without any problem...

smooth_disabled.mp4

@lawnjelly
Copy link
Member

lawnjelly commented Jul 26, 2022

Just as an aside, I don't know whether it's related, I haven't really been following this topic, but just to mention that in this functionality:

real_t c = smoothing * (process_callback == CAMERA2D_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time());
smoothed_camera_pos = ((camera_pos - smoothed_camera_pos) * c) + smoothed_camera_pos;

c is not capped to 1.0.
i.e. c can end up being larger than one at low frame rates / tick rates with large smoothing values, which looks like it would cause oscillations. Low frame rates might be seen especially at startup.

@madmiraal
Copy link
Contributor

when smooth is activated to a 2d camera, at the start of the scene the camera2d moves to its starting point (the player's position)

@dannygaray60 This is the expected behaviour. It was a bug that the camera did not scroll smoothly to its new position. If you want the camera to immediately snap to the position and not move there smoothly, you need to call reset_smoothing(). With #63083, calling reset_smoothing() after adjusting the camera properties in _ready() now works correctly. If not, please let me know and provide a new MRP.

Note: #63330 captures some of the remaining bugs with limit_smoothed disabled and setting the camera properties in _ready().

@dannygaray60
Copy link
Author

I have done some tests. If the camera is positioned as the child of the player it does not give problems with smoothing enabled.

However there are games that to position the camera, make use of global_position to follow the player, as it is in my case.

Applying reset_smoothing solves the problem.

But, I am not sure if that bug is something that is correct within the smooth operation. Since in previous versions of godot this problem was not present.

So I have nothing more to say 😅

PS: Maybe it should be warned about this problem with smooth in the documentation just in case someone else uses global_position to follow the player like me.

Captura de pantalla 2022-07-26 084048

@madmiraal
Copy link
Contributor

@dannygaray60 Yes, this is the expected behaviour. If you change the camera position and you don't want it to scroll to the new position, then you call reset_smoothing(); exactly as you're doing.

Note: If, as you suggest, you make the Camera2D a child of your player or you simple place the Camera2D where you want it to start, then it enters the SceneTree at the global_position as defined in the Inspector. Since there is no change in position, there will be no scrolling, because there is nowhere to scroll from. When you set the position in _ready() (and don't use reset_smoothing() it scrolls from the position defined in the Inspector.

You are right in that this fix should be included in the release notes; since you're probably not the only one that's used to the previous broken behaviour.

@AttackButton
Copy link
Contributor

image

May I make a suggestion? Probably, it is better to rename reset_smoothing() to snap_to_position(). Also, unbind it from the smoothing property and make it work whether smoothing is enabled or not.

@Calinou
Copy link
Member

Calinou commented Feb 21, 2023

May I make a suggestion? Probably, it is better to rename reset_smoothing() to snap_to_position(). Also, unbind it from the smoothing property and make it work whether smoothing is enabled or not.

We can't rename methods anymore throughout 4.x, now that 4.0 is in release candidate stage.

@lawnjelly lawnjelly modified the milestones: 3.5, 3.x Feb 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment