I’m new to Unity, and trying to make the camera follow a rolling ball and rotate with it on the y axis so that the camera stays behind the ball and always faces in the ball’s direction of motion. This is my current script:
public class CameraMover : MonoBehaviour
{
public Transform tf;
public Transform ballTransform;
public Vector3 distanceBetweenBallAndCam;
float yRotation;
// Start is called before the first frame update
void Start()
{
distanceBetweenBallAndCam = tf.position - ballTransform.position;
}
// Update is called once per frame
void Update()
{
tf.position = ballTransform.position + distanceBetweenBallAndCam;
yRotation = ballTransform.eulerAngles.y;
tf.eulerAngles = new Vector3(tf.eulerAngles.x, yRotation, tf.eulerAngles.z);
}
}
As it is, the camera follows the ball fine, but encounters some problems on the rotation. When the ball is rolling straight down a ramp and is only rotating on the x or z axis, the camera rotates 180 degrees every half rotation of the ball. When it begins rotating on the y axis, the same problem continues to apply, with the additional issue of the camera not properly moving behind the ball. Is there a way to easily fix these problems or do I need to restart my script from scratch? Thanks in advance.
Cinemachine is a unity package that allows you to make a following camera with a smooth effect. You can find lot of videos about it and documentation here.
I don’t know exactly your project technical aspect but if you use rigid body, you can’t control the rotation of your Y-axis even with freeze it. Otherwise, you can use your velocity to know is wich direction your ball go and control your camera :
public class CameraMover : MonoBehaviour
{
public Transform tf;
public Transform ballTransform;
public Rigidbody rgBall;
// Start is called before the first frame update
void Start()
{
rgBall = ballTransform.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
// Dot product of two normalized vector is equals to cos of theire angle.
float yRotation = -Mathf.Acos(Vector3.Dot(rgBall.velocity.normalized, Vector3.right)) * Mathf.Rad2Deg;
tf.eulerAngles = new Vector3(0, yRotation, 0);
}
}
To rotate around the ball I use an intermediate object with your script inside and camera in child
you can use this script:
using UnityEngine;
using System.Collections;
public class CompleteCameraController : MonoBehaviour
{
public GameObject player; //Public variable to store a reference to the player game object
private Vector3 offset; //Private variable to store the offset distance between the player and camera
// Use this for initialization
void Start()
{
//Calculate and store the offset value by getting the distance between the player's position and camera's position.
offset = transform.position - player.transform.position;
}
// LateUpdate is called after Update each frame
void LateUpdate()
{
// Set the position of the camera's transform to be the same as the player's, but offset by the calculated offset distance.
transform.position = player.transform.position + offset;
}
}