Detection Borders of Stage

Hi gus, im working in a 2D plataform game like Final Fight.
I have the camera follow my character in the X axis smoothing the camera moves.

My problem is when is the end of the stage with the actual programing looks like this.

i want the camera detect the end of the stage and look like this (is edited in photoshop just for show what im talking about)

i want the camera don’t follow my character in the border of the stage.

here my actual follow code.

var dampTime : float = 0.3; //offset from the viewport center to fix damping
private var velocity = Vector3.zero;
var target : Transform;

function Update() {
    if(target) {
        var point : Vector3 = camera.WorldToViewportPoint(target.position);
        var delta : Vector3 = target.position + Vector3(0,2.8,0) - camera.ViewportToWorldPoint(Vector3(0.5, 0.5, point.z));
        var destination : Vector3 = transform.position + delta;
        transform.position = Vector3.SmoothDamp(transform.position, destination, velocity, dampTime);
    }
}

thanks for the help :slight_smile:

EDIT : here is a build with the actual code working.

http://badmouse.a.lisonal.com/unity3d/

A simple solution might be to clamp the camera position’s x coordinate to the desired range after the call to SmoothDamp(). Or, you could clamp the x coordinate of the target point instead, which might give smoother results.

There is not way to do it automatic?

about your suggest you mean stg like this ?

transform.position = Vector3.SmoothDamp(transform.position - Vector3(20,0.0,0), destination, velocity, dampTime);

What do you mean by automatic?

I’m not quite sure what you’re doing there, but no, I don’t think so. What I’m suggesting is, after you perform the smooth damp as usual, clamp the x coordinate of the camera’s position to whatever range you want it to stay in (you can use e.g. Mathf.Clamp() for this). That way, the camera won’t move any farther left or right than you want it to.

My other suggestion is similar, and that’s to clamp the x coordinate of the destination position before performing the smooth damp (this should give you smoother results, I think, since the camera won’t stop abruptly when it reaches the boundary, but will rather come to a gradual stop).

with automatic i mean that the camera detect the end of the stage with out clamp the x coordinate of the destination position. depend of the stage the end of the stage is in different position so i have to change the value of the final x coordinate of each stage.

Anyway your idea sound like will work perfect, thank you!

But i don’t know how to clamp the x coordinate of the destination position.

actually my camera is in the x coordinate 0,0 and the 2 borders of the stage are in -18,0 and 18,0

How i can clamp the x coordinate ?

here my actual follow camera code.

var dampTime : float = 0.3; //offset from the viewport center to fix damping
private var velocity = Vector3.zero;
var target : Transform;

function Update() {
    if(target) {
        var point : Vector3 = camera.WorldToViewportPoint(target.position);
        var delta : Vector3 = target.position + Vector3(0,1.1,0) - camera.ViewportToWorldPoint(Vector3(0.5, 0.5, point.z));
        var destination : Vector3 = transform.position + delta;
        transform.position = Vector3.SmoothDamp(transform.position, destination, velocity, dampTime);
    }
}

you said to clamp it before the SmoothDamp but i don’t understand how to clamp it :frowning:

thank you so much for answer me so fast and for the help :slight_smile:

One way to clamp your camera could be:

if (transform.position.x <= 18  transform.position.x >= -18) {
        transform.position = Vector3.SmoothDamp(transform.position, destination, velocity, dampTime);
}

another could be:

transform.position = Mathf.Clamp(Vector3.SmoothDamp(transform.position, destination, velocity, dampTime), -18, 18);

For example. :slight_smile:

Edit: Bah, you need to use just the x-coordinate in the last example, of course.

Thanks TwiiK, this one

if (transform.position.x <= 18  transform.position.x >= -18) {
        transform.position = Vector3.SmoothDamp(transform.position, destination, velocity, dampTime);
}

works well but the problem is that the camera is locked in both borders. when the position on 18 or -18 :frowning:

In the case the character walk back the camera still locked in the borde of the stage.

That’s because the camera position becomes exactly -18 or 18 or slightly outside -18/18 so after it has been locked the script never gets inside the if statement again.

You will probably want to use Clamp in that case. Perhaps:

transform.position = Vector3.SmoothDamp(transform.position, destination, velocity, dampTime);
transform.position = Vector3(Mathf.Clamp(transform.position.x, -18, 18), transform.position.y, transform.position.z);

No idea if it works and it’s probably convoluted, but should give you a starting point. :slight_smile:

for the Mathf.Clamp() function, you can use something like this :

with _yourMinX, etc… being manually set by you, or automatically calculated with your walls X position minus (or bonus) a fixed safe value, like 5f.

Well, you have to do something to specify where the camera should stop; it’s not going to stop just because you want it to :wink:

But, there are plenty of ways you can make it easily tweakable. The easiest way would probably just be to have a couple of public (and editable in the inspector) variables somewhere such as ‘minX’ and ‘maxX’. If you want to get a little fancier and be able to set the limits visually in the scene view, you could use two tagged game objects with gizmos attached, and then just drag them into place; the camera would then query for these objects and use their x coordinates as the bounds.

I suppose you could also make your camera a rigid body and put actual colliders where you want the camera to stop; not sure how well that would work though.

But no, there’s no way to automate it in a way that won’t require any involvement on your part. How would Unity know where you wanted the camera to stop?

TwiiK, the code work well ! but im loosing the smoothing when the camera is in the border, just stop abruptly when X = 18 or -18.

n0mad, Hi! thanks for the help! but, it’s work but i want a smooth stop of the camera in the border. But the is a great Idea set the minX and MaxN from the Inspector :slight_smile:

Jesse Anders, With automatic i mean maybe using the Level Attributes or raycast from the camera can detect the walls in both sides but i never work with Level Attributes so i think you are right.

Thank you all you guys for the help, i really appreciate it :slight_smile:

This is why I suggested clamping the x coordinate of the target position rather than the camera. If I’m not mistaken, clamping the target rather than the camera should cause the camera to slow to a stop at the boundaries rather than stopping abruptly.