Request for suggestions - top down adventure camera

Hi guys.

I’m making a 2d top down zelda-like adventure game.

It looks like this:

Right now, I’ll be implementing the camera. The idea is to have a system that:

  • Scrolls freely in overworld areas
  • Scrolls on fixed screen-to-screen transitions on interiors and dungeons, a la Zelda, but!
  • Also allows for arbitrarily locking the camera into “regions” where the free scrolling switches to the screen-by screen scrolling

We are using Tiled for the map editor.

Do you have any ideas about methods to implement this behavior in a way that has the least production overhead possible? The more programmatic/dynamic the solution. the better. We had an initial idea of littering the map with bounding tiles to delimit screens where the camera wouldn’t scroll past until you left the X by Y are of tiles (all rooms will be the same size) but I would like to avoid excessive dependency on too manually placed metadata, as it’s prone to human error and is also more work.

Any ideas?

3 Likes

If they are the same size then couldn’t you just mark those rooms/tiles as “fixedCamera,” so if your character enters one of them the camera goes to what you’ve set as the fixed location?

One of the things I appreciate about Zelda’s style of scrolling vs. camera jumps is the feeling that the entire world is interconnected. I would continue to build the entire world in a way that makes sense overall and treat scrolling as the default. When you want to limit scrolling, you’re essentially setting the camera, so chunk off different sections for different cameras. I don’t know if that makes sense, but I can make an image if you like.

Btw, this is looking really good. Check your saturation levels if you can! I think that blue water is really brightly lit but the ground and rocks make it seem like it’s cloudy/foggy. Either or works, but both together is kinda meh.

Yes, that’s the high-level idea. I’m asking more for implementation tips.We have to consider the direction you are running in, where you enter and where you exit the rooms to do the transition scrolling properly, plus a bunch of other things (i.e. npcs or enemies in a dungeon room shouldn’t normally be able to leave that room on their own, even if there is more map beyond.

That would be helpful. If I understand correctly, you are saying to lay out a bunch of cameras and switch to them when the view is fixed?
I also have to consider the “scrolling” transition when moving between rooms, so a jump cut or freeze by itself wouldn’t be enough.

The sprites are wip, so we’ll address all that when we get to the graphics-tightening step. Plus, it’s not me who’s doing them :stuck_out_tongue:

Oh yeah forgot to mention but the base engine is Unity

Bounding tiles are a bad plan because you are going to have to deal with situations where there are conflicts, at some point. And this could include conflicts like “there are walls on either side and where do I even put the camera now” which is honestly just kind of a pain in the long term, especially if you decide to, at some point, change the criteria.

It’s definitely better to have different cameras that are snapped to. It has the same desired effect at a fraction of the work, and you can template a few of them quickly once you decide what the switching criteria is.

1 Like

This is the current solution I have for a Zelda style scrolling game with differently shaped rectangular rooms. Your character moves on the big colored “map” made up of rectangular “rooms”. Each room has 2 “camera constraints” that draw a bounding box around valid camera positions. Run whatever camera lerping algorithm you want and then finish it off with ConstrainCamera(). There are obviously a few problems that I haven’t addressed, but I think this should get you most of the way there.

Btw, if you figure out how to deal with L or other complexly shaped rooms, please get at me. Thanks dude.

1 Like

I strongly feel that spatial data like camera bounds should be represented by shapes; it helps with debugging, it helps visualize, and it helps you expand it to new shapes.

I don’t quite understand how much simpler you can get than bounding boxes with transitions, but I’ll share some of my favorite resources:

This goes in-depth on a non-locking camera featuring springiness, hinting, zooming. It’s basically what we did for Galak-Z.

This is a very good overview of camera methods from the cool guy who made the cool game Mushroom 11:

2 Likes

L-shaped rooms suck because the corner pushes the camera.

You have to treat all camera motion as if it is being ‘pushed’ by the player, and then the boundaries of the map will push back in whatever way they are capable of doing so. The more predictable this is, and the less reliant on deltas, the better.

So even if you lock it so you can’t view around an L shape, you have the problem that the camera must snap if the player is navigating close to the inner corner. So the end result is honestly, just, don’t do it.

Way easier to just hide what’s behind the L corner and switch to a different map for what’s actually there. Or simply not have free-roaming around one.

I already knew about both these articles. I love them. Really informative.

We don’t want or need to get too fancy with the camera. I’m thinking just to have some inner bounds in the middle of the screen for the free scrolling mode (so the character isn’t always perfectly centered and has some leeway to move around the frame, like e.g. Crystallis) and that’s pretty much where the sophistication ends.

I think we can live without L-shaped rooms so this solution seems pretty nice.

How do set this up implemementatio-wise?

Do you have some camera objects ready to snap into position and then use a rectangular trigger to switch between them?
How do you define the constraint points?

Also, how do you solve the scrolling camera stopping at the limits of the contraint before entering a fixed-room area?

I don’t know! I haven’t done it yet! If I were to rough it out it’d go something like:

On camera object have a CameraController script that in Update() first does something like MoveCameraToDesiredPosition() and then ConstrainPosition(x, y). The “trick” is that the arguments in ConstrainPosition() are dependent on where the player is. So I’m thinking x and y will change depending on the room the player is in. I’d probably manually set the constraints per room.

I think the solution for L-shaped or more complex shapes will have to come from non-rectangularly shaped rooms and constraints that seem to go a little further into the next room.