I made a simple racing game. The camera follows the car (player) and its position and rotation is based on car's Y rotation. I want to smooth the camera rotation, but when it crosses 0 degree point, it rotates 360 degrees. Here's the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Camera : MonoBehaviour {
public Transform camera, player;
void Update() {
Vector3 cameraPosition = camera.transform.position;
float cameraRotation = camera.eulerAngles.y;
float playerRotation = player.eulerAngles.y;
Vector3 playerPosition = player.transform.position;
cameraPosition.x = (Mathf.Sin((playerRotation / 180) * Mathf.PI) * -6 + player.position.x);
cameraPosition.y = playerPosition.y + 2.5f;
cameraPosition.z = (Mathf.Cos((playerRotation / 180) * Mathf.PI) * -6 + player.position.z);
camera.transform.position = cameraPosition;
cameraRotation = cameraRotation + (playerRotation-cameraRotation)/2;
camera.localRotation = Quaternion.Euler(20f, cameraRotation, 0f);
}
}
I figured out that this rotation is caused by smoothing script:
cameraRotation = cameraRotation + (playerRotation-cameraRotation)/2;
How to prevent this unwanted rotation?
This is how I would do it:
public int smoothSpeed = 1f; // Change accordingly to increase/decrease smooth speed.
Then in update:
Vector3 directionToCar = player.position - camera.position;
Quaternion desiredRotation = Quaternion.LookRotation(directionToCar);
camera.rotation = Quaternion.Slerp(camera.rotation, desiredRotation, Time.deltaTime * smoothSpeed);
On a side node, if this camera script is attached to the camera, you don't have to make a field referencing the camera's transform. You can simply do transform.position
instead of camera.transform.position
.
A simpler solution to using the Slerp is to use Mathf.SmoothDamp, which has a variant called Mathf.SmoothDampAngle which handles the looping correctly. I've also had success doing the wraparound by hand but its not a very rewarding experience
using UnityEngine;
public class RotFollow : MonoBehaviour
{
[SerializeField] Transform carTransform;
[SerializeField] float smoothTime = .4f;
float currentYAngle;
float targetYAngle;
float angleVel;
void Update()
{
targetYAngle = carTransform.rotation.eulerAngles.y;
currentYAngle = Mathf.SmoothDampAngle(currentYAngle, targetYAngle, ref angleVel, smoothTime);
transform.rotation = Quaternion.Euler(
transform.rotation.eulerAngles.x,
currentYAngle,
transform.rotation.eulerAngles.z);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.