Having a camera follow a player and viewing direction (JS)

I have a sphere in my game that is the (third person) player. The sphere moves (rolls around), and I would like the camera to follow the sphere and look towards the direction the sphere is moving, and rotate according to the player’s movements.

I’ve managed to get the camera to follow the sphere’s location, with an offset I’ve specified, but I can’t figure out how to get it to mimic the spheres rotations as well. I’ve tried parenting the camera to the player, but that didn’t work as the camera ends up rotating the full 360 degrees around the player, which is really nauseating.

How can I have the camera follow the player and react to its movements but only horizontally, and not vertically? In other words, the sphere rolls around a lot, but I only want the camera to move along a horizontal axis when it rotates with the player, not spin wildly.

Any help (preferably in Javascript) is appreciated. Thanks.

If what you want is just to keep the camera facing always the direction of movement, you must calculate its direction based on the last position. To avoid inaccuracies produced by very small displacements, you can set a minimum distance to refresh the view direction (adjust the distance variable in the Inspector if needed):

using UnityEngine;
using System.Collections;

public class CameraScript : MonoBehaviour
{
public Transform ballObject;
public float distance = 0.1f; // min distance to refresh view direction

``````  Vector3 lastPos;
Vector3 viewDir;

void Start(){
// ensure forward direction at start
lastPos = ballObject.transform.position - transform.forward * distance;
}

void Update()
{
Vector3 ballPos = ballObject.transform.position;
Vector3 newDir = ballPos - lastPos;  // direction from last position
newDir.y = 0;    // keep the camera on horizontal plane
if (newDir.magnitude>distance){  // only recalculate after min distance
viewDir = newDir;
lastPos = ballPos;
}
transform.position = ballPos;
transform.forward = Vector3.Slerp(transform.forward, viewDir.normalized, Time.deltaTime);
}
}
``````