The movement is smooth and tweakable. how do i add to this code so that the camera stops moving when the end of the level in x or y direction is reached??
Thanks
using UnityEngine;
using System.Collections;
public class CameraFollow : MonoBehaviour {
public Controller2D target; //the player is chosen
public float verticalOffset;
public float lookAheadDstX;//the distance in front of the player that is shown
public float lookSmoothTimeX;
public float verticalSmoothTime;
public Vector2 focusAreaSize;
FocusArea focusArea;
float currentLookAheadX;
float targetLookAheadX;
float lookAheadDirX;
float smoothLookVelocityX;
float smoothVelocityY;
bool lookAheadStopped;
void Start() {
focusArea = new FocusArea (target.collider.bounds, focusAreaSize);
}
void LateUpdate() {
focusArea.Update (target.collider.bounds);
Vector2 focusPosition = focusArea.centre + Vector2.up * verticalOffset;
if (focusArea.velocity.x != 0) {
lookAheadDirX = Mathf.Sign (focusArea.velocity.x);
if (Mathf.Sign(target.playerInput.x) == Mathf.Sign(focusArea.velocity.x) && target.playerInput.x != 0) {
lookAheadStopped = false;
targetLookAheadX = lookAheadDirX * lookAheadDstX;
}
else {
if (!lookAheadStopped) {
lookAheadStopped = true;
targetLookAheadX = currentLookAheadX + (lookAheadDirX * lookAheadDstX - currentLookAheadX)/4f;
}
}
}
currentLookAheadX = Mathf.SmoothDamp (currentLookAheadX, targetLookAheadX, ref smoothLookVelocityX, lookSmoothTimeX);
focusPosition.y = Mathf.SmoothDamp (transform.position.y, focusPosition.y, ref smoothVelocityY, verticalSmoothTime);
focusPosition += Vector2.right * currentLookAheadX;
transform.position = (Vector3)focusPosition + Vector3.forward * -10;
}
void OnDrawGizmos() {
Gizmos.color = new Color (1, 0, 0, .5f);
Gizmos.DrawCube (focusArea.centre, focusAreaSize);
}
struct FocusArea {
public Vector2 centre;
public Vector2 velocity;
float left,right;
float top,bottom;
public FocusArea(Bounds targetBounds, Vector2 size) {
left = targetBounds.center.x - size.x/2;
right = targetBounds.center.x + size.x/2;
bottom = targetBounds.min.y;
top = targetBounds.min.y + size.y;
velocity = Vector2.zero;
centre = new Vector2((left+right)/2,(top +bottom)/2);
}
public void Update(Bounds targetBounds) {
float shiftX = 0;
if (targetBounds.min.x < left) {
shiftX = targetBounds.min.x - left;
} else if (targetBounds.max.x > right) {
shiftX = targetBounds.max.x - right;
}
left += shiftX;
right += shiftX;
float shiftY = 0;
if (targetBounds.min.y < bottom) {
shiftY = targetBounds.min.y - bottom;
} else if (targetBounds.max.y > top) {
shiftY = targetBounds.max.y - top;
}
top += shiftY;
bottom += shiftY;
centre = new Vector2((left+right)/2,(top +bottom)/2);
velocity = new Vector2 (shiftX, shiftY);
}
}
}
For the camera, I just add a rigidbody and a spring joint attached to my player. Then if you want it to stop at the end of the level, simply add some coliders that only affect the camera.
Just add a clamping line around line 47:
Vector2 minPosition;
Vector2 maxPosition;
...
focusPosition += Vector2.right * currentLookAheadX;
focusPosition = Vector2.Min(focusPosition , maxPosition);
focusPosition = Vector2.Max(focusPosition , minPosition);
...
Thanks everyone for the help.
I added a Box Collider2D and used its bounds to be the level limits. In that way, I can resize the Collider according to the level and it will act as the level limit for the camera.
The complete code if anyone is interested
using UnityEngine;
using System.Collections;
public class CameraFollow : MonoBehaviour {
public Controller2D target;
public float verticalOffset;
public float lookAheadDstX;
public float lookSmoothTimeX;
public float verticalSmoothTime;
public Vector2 focusAreaSize;
FocusArea focusArea;
public BoxCollider2D levelBounds;
private Vector2 minPosition;
private Vector2 maxPosition;
float currentLookAheadX;
float targetLookAheadX;
float lookAheadDirX;
float smoothLookVelocityX;
float smoothVelocityY;
bool lookAheadStopped;
void Start() {
minPosition = levelBounds.bounds.min;
maxPosition = levelBounds.bounds.max;
focusArea = new FocusArea (target.collider.bounds, focusAreaSize);
}
void LateUpdate() {
focusArea.Update (target.collider.bounds);
Vector2 focusPosition = focusArea.centre + Vector2.up * verticalOffset;
if (focusArea.velocity.x != 0) {
lookAheadDirX = Mathf.Sign (focusArea.velocity.x);
if (Mathf.Sign(target.playerInput.x) == Mathf.Sign(focusArea.velocity.x) && target.playerInput.x != 0) {
lookAheadStopped = false;
targetLookAheadX = lookAheadDirX * lookAheadDstX;
}
else {
if (!lookAheadStopped) {
lookAheadStopped = true;
targetLookAheadX = currentLookAheadX + (lookAheadDirX * lookAheadDstX - currentLookAheadX)/4f;
}
}
}
currentLookAheadX = Mathf.SmoothDamp (currentLookAheadX, targetLookAheadX, ref smoothLookVelocityX, lookSmoothTimeX);
focusPosition.y = Mathf.SmoothDamp (transform.position.y, focusPosition.y, ref smoothVelocityY, verticalSmoothTime);
focusPosition += Vector2.right * currentLookAheadX;
focusPosition = Vector2.Min (focusPosition, maxPosition);
focusPosition = Vector2.Max (focusPosition, minPosition);
transform.position = (Vector3)focusPosition + Vector3.forward * -10;
}
void OnDrawGizmos() {
Gizmos.color = new Color (1, 0, 0, .5f);
Gizmos.DrawCube (focusArea.centre, focusAreaSize);
}
struct FocusArea {
public Vector2 centre;
public Vector2 velocity;
float left,right;
float top,bottom;
public FocusArea(Bounds targetBounds, Vector2 size) {
left = targetBounds.center.x - size.x/2;
right = targetBounds.center.x + size.x/2;
bottom = targetBounds.min.y;
top = targetBounds.min.y + size.y;
velocity = Vector2.zero;
centre = new Vector2((left+right)/2,(top +bottom)/2);
}
public void Update(Bounds targetBounds) {
float shiftX = 0;
if (targetBounds.min.x < left) {
shiftX = targetBounds.min.x - left;
} else if (targetBounds.max.x > right) {
shiftX = targetBounds.max.x - right;
}
left += shiftX;
right += shiftX;
float shiftY = 0;
if (targetBounds.min.y < bottom) {
shiftY = targetBounds.min.y - bottom;
} else if (targetBounds.max.y > top) {
shiftY = targetBounds.max.y - top;
}
top += shiftY;
bottom += shiftY;
centre = new Vector2((left+right)/2,(top +bottom)/2);
velocity = new Vector2 (shiftX, shiftY);
}
}
}