Hello Guest

Author Topic: Limit camera movement and zoom to stay within tile map bounds  (Read 11195 times)

Neeko

  • 2D Toolkit
  • Jr. Member
  • *
  • Posts: 59
    • View Profile
    • Overdeveloped
I'm using the tk2dCamera to zoom in and out to ensure that all players are always within view as they move, as well as moving the camera so that it's center between the left and right most players. Basically, it's a camera very similar to Super Smash Bros or any other fighting game. You can read more about the specific implementation details here http://overdevelop.blogspot.com/2014/01/single-camera-system-for-four-players.html.

What I'd like to achieve is to make sure that the camera never moves or zooms out farther than the bounds of the tile map.

I've been banging my head on this for a few days and I'm failing to come up with a working solution. One possible solution was to obtain vectors to the corners of the camera bounds, and when its distance was negative to that of the corners of the tile map, stop moving. This worked, but zooming became an issue and it ultimately fell apart.

Has anyone implemented something similar? The fact that the camera zooms (increases in size) is the part that's really tripping me up.

As always, thanks!
« Last Edit: March 10, 2014, 02:27:54 pm by Neeko »

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Limit camera movement and zoom to stay within tile map bounds
« Reply #1 on: March 11, 2014, 01:41:57 pm »
It should be fairly straightforward.
1. Make sure you're using centred tk2dCamera and not have the origin at the bottom left to save you a lot of bother.
2. Get the extrema of camera extents when scale = 1 and origin = 0,0,0 and save it somewhere. tk2dCamera.ScreenExtents
3. Work out the minimum and maximum positions for the tile map in world space.
4. For a given scale, you need to work out the new extents. since your origin is centred, you can simply multiply the extents to get the new extents.
5. Move the camera to make sure its clamped based on the extents you calculated in #4.

Don't keep getting ScreenExtents from the camera, as that depends on the scale you'll be chasing a moving target.

Neeko

  • 2D Toolkit
  • Jr. Member
  • *
  • Posts: 59
    • View Profile
    • Overdeveloped
Re: Limit camera movement and zoom to stay within tile map bounds
« Reply #2 on: March 26, 2014, 12:10:21 pm »
Steps 1-3 I'm getting, but I'm not understanding the rest.

Firstly, when you say scale, do you mean tk2dCamera.ZoomFactor?

I'm also not understanding using the screen extents. So I save reference to the tk2dCamera.ScreenExtents (as cameraExtents) when it's at 0,0,0 and ZoomFactor of 1 (at 1080p, this gives me (x:-960.00, y:-540.00, width:1920.00, height:1080.00)).

For step 4, in my Update, I multiply the new extents like so

Code: [Select]
float scale = tk2dCamera.ZoomFactor;
Rect newExtents = new Rect(cameraExtents.xMin * scale,
    cameraExtents.yMin * scale,
    cameraExtents.width * scale,
    cameraExtents.height * scale);

But this gives me a very large Rect ((x:-202560.00, y:-113940.00, width:405120.00, height:227880.00) when ZoomFactor is 211, for example). I'm not understanding how to use this to clamp the camera bounds?
« Last Edit: March 26, 2014, 12:25:24 pm by Neeko »

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Limit camera movement and zoom to stay within tile map bounds
« Reply #3 on: March 26, 2014, 12:37:22 pm »
scale = 1/zoomFactor.
That should get you the correct numbers?

antman

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Limit camera movement and zoom to stay within tile map bounds
« Reply #4 on: April 17, 2014, 07:38:28 am »
3. Work out the minimum and maximum positions for the tile map in world space.
What is the best way to do this?  I'm not able to get the bounds of the renderer and collider for my tilemap from the renderData for some reason (they are both null...)

Neeko

  • 2D Toolkit
  • Jr. Member
  • *
  • Posts: 59
    • View Profile
    • Overdeveloped
Re: Limit camera movement and zoom to stay within tile map bounds
« Reply #5 on: April 17, 2014, 02:55:02 pm »
Okay thanks, that seems to be getting the appropriate numbers.

Based on what you recommended, here is my current solution, but it's not 100% just yet.

Code: [Select]
float scale = 1 / tk2dCamera.ZoomFactor;
Rect newExtents = new Rect(cameraExtents.x * scale,
    cameraExtents.y * scale,
    cameraExtents.width * scale,
    cameraExtents.height * scale);

float clampedX, clampedY;
// To ensure we clamp against both the min and max boundaries,
// We first clamp against the minimum boundaries first.
clampedX = Mathf.Clamp(newExtents.xMin, minXBound.transform.position.x, maxXBound.transform.position.x);
clampedY = Mathf.Clamp(newExtents.yMin, minYBound.transform.position.y, maxYBound.transform.position.y);
// Then clamp against the maximum boundaries.
clampedX = Mathf.Clamp(newExtents.xMax, minXBound.transform.position.x, maxXBound.transform.position.x);
clampedY = Mathf.Clamp(newExtents.yMax, minYBound.transform.position.y, maxYBound.transform.position.y);               

targetPosition = new Vector3(clampedX, clampedY, Distance);

To note, minXBound, minYBound, maxXBound and maxYBound are simply empty GameObjects in my scene that I positioned to represent the bounds in which to keep the camera within; I'm using these because the game area might be smaller than the actual tile map size.

There are a lot of times when the camera should be moving/zooming out to keep a player within view, even when the players are within the appropriate boundaries, but it doesn't. I'll keep messing with it, but please call me out on any glaring issue you might notice.

Edit: It's probably just easier to share my entire camera controller script. Warning: Some of it is ugly! https://gist.github.com/MadballNeek/71af494a096f232c548c
« Last Edit: April 17, 2014, 03:32:58 pm by Neeko »

wagenheimer

  • 2D Toolkit
  • Jr. Member
  • *
  • Posts: 50
    • View Profile
Re: Limit camera movement and zoom to stay within tile map bounds
« Reply #6 on: June 18, 2014, 02:48:35 pm »
I simply want my camera to be locked on the edges of my TileMap (I don't want to show any empty space). Someone managed to make it work?

Neeko

  • 2D Toolkit
  • Jr. Member
  • *
  • Posts: 59
    • View Profile
    • Overdeveloped
Re: Limit camera movement and zoom to stay within tile map bounds
« Reply #7 on: June 18, 2014, 02:56:20 pm »
I simply want my camera to be locked on the edges of my TileMap (I don't want to show any empty space). Someone managed to make it work?

I assume then there's no movement code for the camera? If that's the case, you'll just have to fiddle around with the tk2dCamera.ZoomFactor property to get it to show the desirable area of your tilemap. At least that's how I've approached it. You could probably come up with a way to dynamically calculate the zoom but I'm lazy sometimes  :P

wagenheimer

  • 2D Toolkit
  • Jr. Member
  • *
  • Posts: 50
    • View Profile
Re: Limit camera movement and zoom to stay within tile map bounds
« Reply #8 on: June 18, 2014, 03:09:55 pm »
There is movement for the camera (it follows the player), but no scale.