# Looking for advice/ideas to improve my 2D camera "look ahead" scripting

Hi everyone,

I have another really “dumb” script I wrote for a 2D platformer that mostly does what I want it to do. I say dumb, because it’s… not elegant at all.

It’s a camera follow script of the player sprite, and I added code for it to move the camera slightly ahead of the player when they are moving to allow seeing further ahead for potential dangers. The part I need advice on, is the look ahead portion.

NOW, I know there is a third party solution that probably does exactly what I want (CineMachine), but I would rather just have my own code if possible.

Here’s the code…

``````using UnityEngine;
using System.Collections;

{

Transform player; // Declare a Transform component, calling it player

public Vector3 offset; // Declare a Vector3 component, called offset

private Vector3 velocity = Vector3.zero; // define another Vector3, with the function zero (easy way to say Vector3 (0,0,0) )

public float smoothSpeed = .15f; // create a public float smoothSpeed and set it
public float horizontalValue; // create a public float for a horizontal movement amount

void Start()
{
player = GameObject.FindWithTag("Player").GetComponent<Transform>(); // grab the player's transform values

offset = new Vector3(0f, 0f, -1f); // set a base offset to be used by the look ahead function
}

void Update()
{

// stuff below is for the camera "look ahead"

horizontalValue = Input.GetAxis("Horizontal"); // first, define what the horizontalValue float is equal to. InputAxis can be a positive or negative float number

if (horizontalValue >= 0 && horizontalValue >= 0.1f) // if the horizontalValue is between positive 0 and 0.1 (meaning, moving to the right)...
{

offset = new Vector3(0.1f, 0f, -1f); // move the offset forward a little
}

if (horizontalValue >= 0.11f && horizontalValue >= 0.2f) // if the horizontalValue is...
{

offset = new Vector3(0.2f, 0f, -1f); // move the offset a little more
}

if (horizontalValue >= 0.21f && horizontalValue >= 0.3f) // repeat
{

offset = new Vector3(0.3f, 0f, -1f); // repeat
}

if (horizontalValue >= 0.31f && horizontalValue >= 0.4f)
{

offset = new Vector3(0.4f, 0f, -1f);
}

if (horizontalValue >= 0.41f && horizontalValue >= 0.5f)
{

offset = new Vector3(0.5f, 0f, -1f);
}

if (horizontalValue >= 0.51f && horizontalValue >= 0.6f)
{

offset = new Vector3(0.6f, 0f, -1f);
}

if (horizontalValue >= 0.61f && horizontalValue >= 0.7f)
{

offset = new Vector3(0.7f, 0f, -1f);
}

if (horizontalValue >= 0.71f && horizontalValue >= 0.8f)
{

offset = new Vector3(0.8f, 0f, -1f);
}

if (horizontalValue >= 0.81f && horizontalValue >= 0.9f)
{

offset = new Vector3(0.9f, 0f, -1f);
}

if (horizontalValue >= 0.91f && horizontalValue >= 1f)
{

offset = new Vector3(1.2f, 0f, -1f);
}

if (horizontalValue <= 0 && horizontalValue <= -0.1f) // if the horizontalValue is between 0 and negative 0.1 (moving to the left)...
{

offset = new Vector3(-0.1f, 0f, -1f); // move the offset forward a little
}

if (horizontalValue <= 0.11f && horizontalValue <= -0.2f) // if the horizontalValue is...
{

offset = new Vector3(-0.2f, 0f, -1f); // move the offset a little more
}

if (horizontalValue <= 0.21f && horizontalValue <= -0.3f) // repeat
{

offset = new Vector3(-0.3f, 0f, -1f); // repeat
}

if (horizontalValue <= 0.31f && horizontalValue <= -0.4f)
{

offset = new Vector3(-0.4f, 0f, -1f);
}

if (horizontalValue <= 0.41f && horizontalValue <= -0.5f)
{

offset = new Vector3(-0.5f, 0f, -1f);
}

if (horizontalValue <= 0.51f && horizontalValue <= -0.6f)
{

offset = new Vector3(-0.6f, 0f, -1f);
}

if (horizontalValue <= 0.61f && horizontalValue <= -0.7f)
{

offset = new Vector3(-0.7f, 0f, -1f);
}

if (horizontalValue <= 0.71f && horizontalValue <= -0.8f)
{

offset = new Vector3(-0.8f, 0f, -1f);
}

if (horizontalValue <= 0.81f && horizontalValue <= -0.9f)
{

offset = new Vector3(-0.9f, 0f, -1f);
}

if (horizontalValue <= 0.91f && horizontalValue <= -1f)
{

offset = new Vector3(-1.2f, 0f, -1f);
}
}

void FixedUpdate()
{
Vector3 camPosition = player.position + offset; // create and set a Vector 3 value called camPosition. camPosition is a combination of the player's transform position and the offset position

transform.position = Vector3.SmoothDamp(transform.position, camPosition, ref velocity, smoothSpeed); // position of the transform of the camera will equal a Vector3 with SmoothDamp function (and we need 4 values for SmoothDamp to calculate)

}

}
``````

Have you got a video of what it currently does?

by elegant could you not make all these guys else if? Or do they all need to be checked and adjusted on the same frame?

Check this out for great analysis of the various 2D camera framing techniques:

I can make a video of it, and yes, I am hoping to get an idea on how I can, instead of all the ifs that check the horizontalValue (and moving the offset depending on the horizontal range), have a calculation or a smooth ramp up to get the offset to be ahead of the player.

I’ll post the video in just a sec

Here’s a video of how it is working right now. I’m not 100% happy (I want to try and eliminate the jerkiness, make the offset a little bigger at max movement, and try and add a movement delay, is in, the camera will only move ahead after some a small delay), but it’s mostly doing what I am trying to do

In case anyone is interested, I was able to finally create a very smooth, clean 2D follow + look ahead camera system. I tried a bunch of different examples for smoothly changing a float and cobbled together this. I think I’m 95% happy with it (though, maybe I can get the “return” motion to be a bit faster)

here’s the code if anyone wants it

``````using System.Collections;
using System.Collections.Generic;
using UnityEngine;

{
Transform player; // declare a transform component (to be that of the player's character)
PlayerMovement pm; // declare the PlayerMovement script as pm

public float xOffset; // declare a float to be used as the x axis offset
public float yOffset; // declare a float to be used as the y axis offset

public float followSpeed; // declare a float called Follow Speed

void Start()
{
player = GameObject.FindWithTag("Player").GetComponent<Transform>(); // define what the declared transform component (of the player) equals
pm = GameObject.FindWithTag("Player").GetComponent<PlayerMovement>(); // define what the declared PlayerMovement component equals
xOffset = 0f; // set what the default xOffset is
yOffset = .7f; // set what the default yOffset is
followSpeed = 12f; // set what the Follow Speed is
}

void Update()

// below setup is for the "look up" feature. This game uses it's own key for jumping, and the up key is free for other things, so it looks up
{
if (Input.GetKeyDown("up")) // if the player presses the "up arrow" key
{
yOffset = 2f; // the y axis offset (vertical axis) is moved up, allowing the player to see further above

}

else if (Input.GetKeyUp("up")) // when the "up arrow" key is released...
{

}

// below setup for the "look ahead" camera offset
// first, we have a public horizontal velocity float in our movement script (horizontalVel) which in that script is in Update as horizontalVel = Input.GetAxis("Horizontal");

if (pm.horizontalVel >= 0.11f) // if horizontalVel is greater than .11f (meaning, moving to right)
{
xOffset = Mathf.Lerp(xOffset, 2.55f, 1 * Time.deltaTime); // the xOffset will equal a Mathf.Lerp value (current value, target value, and time factor). The target value is 2.55

}

else if (pm.horizontalVel == 0) //if horizontalVel is 0f
{
xOffset = Mathf.Lerp(xOffset, 0f, 1 * Time.deltaTime); //do a new mathf.lerp, with the target value 0f
}

if (pm.horizontalVel <= -0.11f) // now, if the player is moving to the left (negative horizontalVel)
{
xOffset = Mathf.Lerp(xOffset, -2.55f, 1 * Time.deltaTime); // the target offset is a negative value

}

}

void FixedUpdate()
{
float xTarget = player.position.x + xOffset; // create a float called xTarget and have it equal to the player x position + xoffset
float yTarget = player.position.y + yOffset; // create a float called yTarget and have it equal to the player y position + yoffset

float xNew = Mathf.Lerp(transform.position.x, xTarget, Time.deltaTime * followSpeed); //a new x position using a linear calculation
float yNew = Mathf.Lerp(transform.position.y, yTarget, Time.deltaTime * followSpeed); //same but for y

transform.position = new Vector3(xNew, yNew, transform.position.z); // camera transform position will equal a new Vector3 set(x value, y value, and z value)
}

}
``````