Inversion of mouse in Unity - c#

I have this code:
using UnityEngine;
public class MouseLook : MonoBehaviour
{
float speed = 120f;
public Transform playerBody;
float xRotation = 200f;
float yRotation = 200f;
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * speed * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * speed * Time.deltaTime;
playerBody.Rotate(Vector3.left * mouseY);
playerBody.Rotate(Vector3.up * mouseX);
xRotation -= mouseX;
yRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -25f, 30f);
yRotation = Mathf.Clamp(yRotation, -35f, 40f);
transform.localRotation = Quaternion.Euler(yRotation, xRotation, 0f);
}
}
The only problem is that when using it, the mouse is inverted on the X-axis. That is, when the mouse moves to the right, the camera moves to the left and vice versa. There is no such inversion with the Y-axis.
What wrong with this code?

When rotating an object around X axis, positive angles rotate down and negative angles rotate up. When rotating an object around Y axis, positive angles rotate right and negative angles rotate left.
Screen coordinates in Unity go from bottom left (0,0) to top right (x,y). When you move your mouse upward you get positive y values, when you move your mouse downward you get negative y values. Notice, that this is inverse of object rotation. That's why this line: yRotation -= mouseY; works fine (it inverts y values before rotating the object). However, for x values inversion isn't necessary since Screen space and Object space already align. You can just use: xRotation += mouseX; instead.
I don't know exactly what you are trying to achieve, but this looks weird to me: xRotation = Mathf.Clamp(xRotation, -25f, 30f);, because it clamps rotation to the left to 25 degrees and to the right to 30 degrees. Is this on purpose?
Try this code:
using UnityEngine;
public class MouseLook : MonoBehaviour
{
float speed = 120f;
public Transform playerBody;
float xRotation = 0f;
float yRotation = 0f;
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * speed * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * speed * Time.deltaTime;
playerBody.Rotate(Vector3.left * mouseY);
playerBody.Rotate(Vector3.up * mouseX);
xRotation += mouseX;
yRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -25f, 30f);
yRotation = Mathf.Clamp(yRotation, -35f, 40f);
transform.localRotation = Quaternion.Euler(yRotation, xRotation, 0f);
}
}

Related

Wierd camera snapping

I was testing my game, and then when I ran the code the camera started doing weird snapping that made camera movement difficult. Here is the script:
public class CameraMovement : MonoBehaviour
{
public float sensX;
public float sensY;
public bool killSwitch;
public Transform orientation;
float yRotation;
float xRotation;
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
private void Update()
{
float mouseX = Input.GetAxisRaw("Mouse X") * Time.deltaTime * sensX;
float mouseY = Input.GetAxisRaw("Mouse Y") * Time.deltaTime * sensY;
yRotation += mouseX;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);
transform.rotation = Quaternion.Euler(xRotation, yRotation, 0);
orientation.rotation = Quaternion.Euler(0, yRotation, 0);
}
}
I tried reloading but that didn't work. I'm really confused because it was working a minute ago.
If you've setup your Input Manager settings incorrectly, you'll likely see a 'Sensitivity' default of 1000. Which would cause your mouse to be returns hugely large numbers when moving around.
Instead, try a sensitivity of 1 in the Input Manager, and then fine tune it in your Component through the Inspector. The CameraMovement component sensX and sensY were set to 10 in the animation below.

How do I fix my camera's xRotation's Clamping?

I made a first person camera using parts of Brackeys Guide, I have camera moving on both the axis but the line for the xRotation clamp doesn't work when I run the game. How can I fix this?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseLook : MonoBehaviour
{
public float mouseSensitivity = 200f;
public Transform playerBody;
public Transform cam;
private float xRotation = 0f;
// Start is called before the first frame update
void Start()
{
Cursor.lockState = CursorLockMode.Locked; // stops you from click out off the sceen
}
// Update is called once per frame
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime; // mouse imput
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime; // mouse imput
xRotation = mouseY;
xRotation = Mathf.Clamp(xRotation, -80f, 73f); // stops you from breaking your neck
Quaternion localRotation = Quaternion.Euler(xRotation, 0f, 0f); // left and right movement
playerBody.Rotate(Vector3.up * mouseX); // left and right movement
cam.Rotate(Vector3.left * mouseY); // up and down movement
}
Setting new specific variables like roty and rotx, and clamping them individually.
It may be that the Vector3 vector has no value, if a value is generated, it can be
private Vector3 m_Dir
void Update () {
this.m_Dir = new Vector3 (localRotation, Vector3.up * mouseX,
tVector3.left * mouseY);
playerBody.Rotate(m_Dir);
cam.Rotate(m_Dir);
}
There are two main problems in the Update method:
xRotation = mouseY is not correct, since mouseY represents the delta angle you want to rotate in this frame, while xRotation represents the current angle at which the camera is rotated. You have to do a sum to get the next pitch of the camera, so xRotation += mouseY.
The quaternion localRotation is created but not actually used in the rotating logic, you still rotate the camera with cam.Rotate(Vector3.left * mouseY). Replace it with cam.localRotation = localRotation.
The final code should look like this:
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
// note: you shouldn't hardcode the min and max values,
// use some values that you can change in the inspector
xRotation = Mathf.Clamp(xRotation + mouseY, -80f, 73f);
cam.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
playerBody.Rotate(Vector3.up * mouseX);

Camera Rotation based on Keydown

So i am really really new to Unity and C# and i was just trying out some things. Now i want to kinda polish the overall control experience. So i want the Camera to rotate 5° on the Z axis when the Button A is pressed.
Thats what i tried:
if (Input.GetKeyDown(KeyCode.A))
{
if (zRotation < 5f)
{
transform.localRotation = Quaternion.Euler(zRotation, 5f, 5f);
}
}
It somewhat works, the camera rotates to 5° on the Z but only for i split second and then returns to it's normal state.
Full Code of the Camera Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class mouseLook : MonoBehaviour
{
public float mouseSensitivity = 100f;
public Transform playerBody;
float xRotation = 0f;
float zRotation = 0f;
// Start is called before the first frame update
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
// Update is called once per frame
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
playerBody.Rotate(Vector3.up * mouseX);
if (Input.GetKeyDown(KeyCode.A))
{
if (zRotation < 5f)
{
transform.localRotation = Quaternion.Euler(zRotation, 5f, 5f);
}
}
}
}
I want the Camera to rotate 5° on the Z axis when the Button A is pressed.
You don't need any variables to achieve this, it should be as simple as:
void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
cameraTransform.Rotate(0, 0, 5);
}
}

Unity camera flicks across screen, first person

Hello I am new to UNITY I have written some code for a first person camera however sometimes when I am looking around it will flick what way the camera is facing. This is my code
public float mouseSensitivity = 200f;
public Transform playerBody;
float yRotation = 0f;
// Start is called before the first frame update
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
// Update is called once per frame
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
yRotation -= mouseY;
yRotation = Mathf.Clamp(yRotation, -90f, 90f);
transform.localRotation = Quaternion.Euler(yRotation, 0f, 0f);
playerBody.Rotate(Vector3.up * mouseX);
}
I have a video to show my issue as well https://youtu.be/nMopJzNyYr4 for is the question is not clear.
I have a capsule as my parent it is the players actual body and then my camera is a child to the playerBody ( my capsule )
Try it without the deltaTime multiplication. GetAxis on a mouse axis gives you a difference in mouse position, which should not be multiplied by deltaTime or any other time delta unless you are interested in a measurement of Absement which you probably are not!!
You are more interested in a distance measurement, so you can just use
float mouseABC = Input.GetAxis("Mouse ABC") * mouseSensitivity;.
Alternatively, if you were to want the speed of the mouse movement, you would actually rather divide by time.deltaTime such as float mouseHorizontalVelocity = Input.GetAxis("Mouse X") * mouseSensitivity / Time.deltaTime;.

Camera behaviour weird when rotating around player

I am going for a RuneScape-style camera that rotates around the player using WASD. Rotating horizontally works fine but when I mix the two (as in pitching up or down) the camera rotates around the player really awkwardly, the camera might invert or will sort of gimbal I guess.
Here's my code:
public float pitch;
public float zoomSpeed = 4f;
public float minZoom = 5f;
public float maxZoom = 15f;
public Transform target;
public Vector3 offset;
public float yawSpeed = 100f;
private float currentZoom = 10f;
private float currentYaw = 0f;
private float currentPitch = 0f;
void Update()
{
currentZoom -= Input.GetAxis("Mouse ScrollWheel") * zoomSpeed;
currentZoom = Mathf.Clamp(currentZoom, minZoom, maxZoom);
currentYaw -= Input.GetAxis("Horizontal") * yawSpeed * Time.deltaTime;
currentPitch -= Input.GetAxis("Vertical") * yawSpeed * Time.deltaTime;
Debug.Log("Yaw: " + currentYaw + " Pitch: " + currentPitch);
}
void LateUpdate()
{
transform.position = target.position - offset * currentZoom;
transform.LookAt(target.position + Vector3.up * pitch);
transform.RotateAround(target.position, Vector3.up, currentYaw);
transform.RotateAround(target.position, Vector3.forward, currentPitch);
}
Any help would be gladly appreciated!
It looks to me that you are using currentPitch, but rotating it around the forward axis? Which would create roll on the world foward axis?
If your up vector is always world up, then the yaw you have will work. But what you want to do is recalculate the right vector from your current location to your target after you apply the yaw.
void LateUpdate() {
transform.position = target.position - offset * currentZoom;
transform.LookAt(target.position + Vector3.up * pitch);
transform.RotateAround(target.position, Vector3.up, currentYaw);
transform.RotateAround(target.position, Vector3.Cross((target.position - transform.position).normalized, Vector3.up), currentPitch);
}

Categories

Resources