+1 vote

I'm currently trying to implement screen shake in my 2D platformer game. In this game, most of the rooms are the size of the viewport, and the camera limits are set around each room, so the camera (which is centered on the player) only appears to move when the player transitions to a different room.

The problem is that the traditional method of implementing screen shake in Godot (i.e. modulating the offset property in Camera2D) doesn't work here because offset apparently obeys the limits of the camera. Ideally, the camera position itself would obey the limits and the offset wouldn't so that I could apply screen shake effects without having to give up my nice camera limits.

Is this possible to do with the current camera limit/offset system? Or will I have to implement the limits/offset from scratch? I've noticed that many similar games (like Celeste and Hollow Knight) have screen shake effects even when the player has reached a room's camera limits, so I'm hoping this is possible to do simply in Godot as well.

Thanks in advance for the help!

EDIT: After some discussion on Diet Estus' similar thread, it was determined that the current behavior of the camera offset following the camera limits was indeed a bug. There's now a pending pull request to fix the issue that's slated for inclusion in the upcoming 3.2 release.

asked Jul 4, 2019 in Engine by AUD_FOR_IUV (41 points)
edited Jul 6, 2019 by AUD_FOR_IUV

I asked essentially the same question earlier tonight. There should be a workaround involving directly shifting the default CanvasLayer. Just haven't perfected it yet because I don't quite understand the Transform2D's attributes. https://godotengine.org/qa/47882/how-to-implement-screenshake-near-camera-limit

Interesting, I might look into this later. Very eager to see the result if you manage to figure it out!

1 Answer

0 votes

Perhaps you could disable/widen the camera limits when shaking?
Something like this:

const camera_limit_left_default = 100 
const camera_limit_right_default = 100 
const camera_limit_down_default = 100 
const camera_limit_up_default = 100 

const shake_limit = 20

func shake():
    var cam = $Player/Camera2D
    # widen the limits
    cam.limit_left += shake_limit
    cam.limit_right += shake_limit
    cam.limit_down += shake_limit
    cam.limit_up += shake_limit
    # TODO shake like crazy here
    # reset the limits
    cam.limit_left = camera_limit_left_default
    cam.limit_right = camera_limit_right_default
    cam.limit_down = camera_limit_down_default
    cam.limit_up = camera_limit_up_default
answered Jul 4, 2019 by Kaligule (47 points)

That's my current approach, and it technically works, but there's a bit of jitter when the limits reset back to their original values. Maybe I could tween back to the old limits or something, but in my experience tweening camera limits results in weird behavior sometimes.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.