- Home /
Can't stop camera from rotating on Z Axis
I'm making an fps game and attempting to rotate a camera up and down the x/y axes using mouse input. The camera continues to rotate along the z axis making gameplay impossible. I am also having trouble limiting rotation to ~180 for the y axis. It may be a dumb question but I'm fairly new. Here is my code.
using UnityEngine;
public class CameraLook : MonoBehaviour { float xSensitivity = 5.0f; float ySensitivity = 5.0f;
void Update()
{
float X = Input.GetAxis("Mouse X") * xSensitivity;
float Y = Input.GetAxis("Mouse Y") * ySensitivity;
transform.Rotate(0, X, 0);
transform.Rotate(-Y, 0, 0);
}
Answer by exploringunity · May 14, 2020 at 11:22 PM
I'd suggest setting transform.eulerAngles
once instead of using transform.Rotate
multiple times. Also, you will probably want smoothing for your camera motion.
Below is a simple camera controller that rotates smoothly on the X/Y axes. It sets a target rotation based on mouse input, and smooths between that and the current rotation. It prevents flipping over by using the Mathf.Clamp
method to limit the rotation around the X axis.
I adapted it from a built-in camera controller Unity has -- UnityTemplateProjects.SimpleCameraController
-- it's the one that is on the default camera for projects created using the Univeral Render Pipeline template, and I highly suggest studying its source code. I made the below mostly by removing features from it to make it simpler, only adding the flip-over prevention. Hope this helps!
using UnityEngine;
public class CameraController : MonoBehaviour
{
class CameraRotation
{
public float yaw, pitch, roll;
public void InitializeFromTransform(Transform t)
{
pitch = t.eulerAngles.x;
yaw = t.eulerAngles.y;
roll = t.eulerAngles.z;
}
public void LerpTowards(CameraRotation target, float rotationLerpPct)
{
yaw = Mathf.Lerp(yaw, target.yaw, rotationLerpPct);
pitch = Mathf.Lerp(pitch, target.pitch, rotationLerpPct);
roll = Mathf.Lerp(roll, target.roll, rotationLerpPct);
}
public void UpdateTransform(Transform t)
{
t.eulerAngles = new Vector3(pitch, yaw, roll);
}
}
CameraRotation targetRotation = new CameraRotation();
CameraRotation currentRotation = new CameraRotation();
[Tooltip("Time it takes to interpolate camera rotation 99% of the way to the target."), Range(0.001f, 1f)]
public float lerpTime = 0.01f;
public float xSensitivity = 1f;
public float ySensitivity = 1f;
void OnDisable() { Cursor.lockState = CursorLockMode.None; }
void OnEnable()
{
targetRotation.InitializeFromTransform(transform);
currentRotation.InitializeFromTransform(transform);
// This makes the cursor hidden -- hit Escape to get your cursor back so you can exit play mode
Cursor.lockState = CursorLockMode.Locked;
}
void Update()
{
// Update the target rotation based on mouse input
var mouseInput = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y") * -1);
targetRotation.yaw += mouseInput.x * xSensitivity;
targetRotation.pitch += mouseInput.y * ySensitivity;
// Don't allow the camera to flip upside down
targetRotation.pitch = Mathf.Clamp(targetRotation.pitch, -90, 90);
// Calculate the new rotation using framerate-independent interpolation
var lerpPct = 1f - Mathf.Exp(Mathf.Log(0.01f) / lerpTime * Time.deltaTime);
currentRotation.LerpTowards(targetRotation, lerpPct);
// Commit the rotation changes to the transform
currentRotation.UpdateTransform(transform);
}
}