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;.
Related
im having an issue with the rotation of the camera around player getting too much damping. i do try to manipulate those speed value but it doesnt work at all. i think thats need something combination between slerp and lerp together, and i just dont know how. Btw im trying to create a third person game and the camera scripts make me stuck, and also i try to create my own scripts rather than using cinemachine. Really hope u guys can help me out.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Camera : MonoBehaviour
{
public float MouseX, MouseY;
public Transform Player;
public float SmoothTime;
public float DefaultZoom = 5f;
public float ZoomSpeed;
Vector3 NewPosition;
Quaternion NewRotation;
//----------------------------------------------------------------------------------------------------
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
Player = GameObject.Find("Player").transform;
}
//----------------------------------------------------------------------------------------------------
void Update()
{
MouseX += Input.GetAxis("Mouse X") * 100f * Time.deltaTime;
MouseY -= Input.GetAxis("Mouse Y") * 100f * Time.deltaTime;
MouseY = Mathf.Clamp(MouseY, -75, 75);
DefaultZoom += Input.GetAxis("Mouse ScrollWheel") * 100f * Time.deltaTime;
DefaultZoom = Mathf.Clamp(DefaultZoom, 3f, 9f);
DefaultZoom = Mathf.Lerp(Vector3.Distance(transform.position, Player.position), DefaultZoom, ZoomSpeed * Time.deltaTime);
}
void LateUpdate()
{
NewRotation = Quaternion.Euler(MouseY, MouseX, 0f);
transform.rotation = Quaternion.Slerp(transform.rotation, NewRotation, Time.deltaTime * SmoothTime);
NewPosition = Player.position - (transform.forward * DefaultZoom);
transform.position = Vector3.Lerp(transform.position, NewPosition, Time.deltaTime * SmoothTime);
}
}
You are using Lerp wrong, both for rotation and position. Lerp isn't actually intended for smoothing, but is used for that purpose never the less, since it is very quick to program.
To fix your problem quickly (tho at the cost of being frame rate dependent), simply remove the Time.deltaTime and make sure that the smooth variable is kept between 0 and 1. The underlying reason is that Time.deltaTime is jumpy (or jittery) by nature and it passes that property directly to Lerp.
I was trying to make a test game in 3D Unity. In the game enemy throw rock and you try to escape. But every time it instantiates a sphere while i am moving my camera(it is tps) it suddenly moves like five times faster in one frame. When i am rotating camera from downwards to upwards at normal speed it suddenly start looking to the sky. I dont get it. Here is the instantiate code:
IEnumerator throwRock()
{
if (IsRockThrowable)
{
IsRockThrowable = false;
GameObject rockk = Instantiate(rock, transform.position, transform.rotation) as GameObject;
rockk.GetComponent<Rigidbody>().AddForce(transform.forward * 100, ForceMode.Impulse);
yield return new WaitForSeconds(2.5f);
IsRockThrowable = true;
}
}
And here is the camera movement code:
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);
}
Can you explain why it happens? Thanks for your attention
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);
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);
}
}
Have this camera working perfect on my target object with one caveat. Can't seem to get the character to look up and down. Left and right move perfectly, up and down don't move at all. What am I doing wrong with the "Mouse Y" part?
public GameObject target;
public float rotateSpeed = 7;
Vector3 offset;
void Start() {
offset = target.transform.position - transform.position;
}
void LateUpdate() {
float horizontal = Input.GetAxis("Mouse X") * rotateSpeed * Time.deltaTime;
float verticle = Input.GetAxis("Mouse Y") * rotateSpeed * Time.deltaTime;
target.transform.Rotate(0, horizontal, 0);
float desiredAngle = target.transform.eulerAngles.y;
Quaternion rotation = Quaternion.Euler(0, desiredAngle, verticle);
transform.position = target.transform.position - (rotation * offset);
transform.LookAt(target.transform);
}
You're not using verticle in your Transform.Rotate call (vertical?).
Edit: Sorry, I just stopped looking once I got to the first problem, looking further there's another problem that's similar to the one I addressed in this question. The "order of operations" is wrong (see the new comments):
public GameObject target;
public float rotateSpeed = 7;
Vector3 offset;
void Start() {
offset = target.transform.position - transform.position;
}
void LateUpdate() {
float horizontal = Input.GetAxis("Mouse X") * rotateSpeed * Time.deltaTime;
float verticle = Input.GetAxis("Mouse Y") * rotateSpeed * Time.deltaTime;
//You didn't use verticle before. Depending on your model/setup you might verticle as the 3rd (Z) parameter to get rotation in the right direction
target.transform.Rotate(verticle, horizontal, 0); //This line rotates the transform
float desiredAngle = target.transform.eulerAngles.y;
Quaternion rotation = Quaternion.Euler(0, desiredAngle, verticle);
transform.position = target.transform.position - (rotation * offset);
transform.LookAt(target.transform); //This sets the absolute rotation of the transform. This call will "override" the above call to Rotate
}
To give more information you'll have to give an explanation of what your end goal is with this code, because looking closer I'm seeing "oddities" with what the code sample is trying to do.
The last line of code (transform.Lookat) overrides the previous code ... basically says 'always look at the target no matter what else happens'.