First person camera rotation tilted Unity3d c# - c#

**```
I am making a game in which you control a machine gun and attempt to kill enimies. There is no actual player, but only a camera. I needed a first person aspect to the game, so I added some simple script to level 1. If you lose, the level is reset. But, whenever you run it, the cameras rotation gets set off, even though its set to 0,0,0. After you die and respawn, for some reason, the camera is normal and the scene is reset. I also noticed that the camera is at an angle sometimes
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class CrosshairMove : MonoBehaviour
{
public float sens = 100f;
public Rigidbody rb;
public Transform cam;
float xRotation = 0f;
float yRotation = 0f;
public float sceneused = 0f;
public float currentscene = 0f;
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
void FixedUpdate()
{
float mouseX = Input.GetAxis("Mouse X") * sens * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * sens * Time.deltaTime;
xRotation -= mouseY;
yRotation -= mouseX;
//xRotation -= Mathf.Clamp(xRotation, -90f, 90f);
//transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
cam.Rotate(Vector3.up * mouseX);
cam.Rotate(Vector3.left * mouseY);
}
}

I would:
Try different gameObject for independent rotation and avoid gimbal lock. For this, you can put the camera in the child object, and when parent is rotated in its local axis, the children "suffers" that same rotation.
Clamp xrot 180º is usual thing in FPS camera
Use FixedUpdate only for physics. For anything else use normal Update
Suggested snippet with all of the above:
public GameObject parentGO; // drag ref to parent go here in the editor
void Update {
float mouseX = Input.GetAxis("Mouse X") * lookAtSensitivity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * lookAtSensitivity *
Time.deltaTime;
xRot -= mouseY;
xRot = Mathf.Clamp(xRot, -90f, 90f);
transform.localRotation = Quaternion.Euler(xRot, 0f, 0f);
parentGO.transform.Rotate(Vector3.up * mouseX);
}

Related

Unity beginner project - one scripts interrupts another

I am new to programming and currently working on a little shooter game in unity. I just implemented recoil but my "PlayerCam" script (Line 31: transform.rotation = Quaternion.Euler(xRotation, yRotation, 0);) interrupts my "Recoil" script, the Euler function to be exact. Without this line recoil works, but I cant move obviously. With it the screen just shakes a bit (reset every frame and not continuing the recoil). What do i need to change?
PlayerCam.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCam : MonoBehaviour
{
public float sensX;
public float sensY;
public Transform orientation;
float xRotation;
float yRotation;
private void Start()
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
private void Update()
{
float mouseX = Input.GetAxis("Mouse X") * sensX;
float mouseY = Input.GetAxis("Mouse Y") * 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);
}
}
Recoil.cs
using UnityEngine;
public class Recoil : MonoBehaviour
{
private Vector3 currentRotation;
private Vector3 targetRotation;
[SerializeField] private float recoilX;
[SerializeField] private float recoilY;
[SerializeField] private float recoilZ;
[SerializeField] private float snappiness;
[SerializeField] private float returnSpeed;
void Start()
{
}
void Update()
{
targetRotation = Vector3.Lerp(targetRotation, Vector3.zero, returnSpeed * Time.deltaTime);
currentRotation = Vector3.Slerp(currentRotation, targetRotation, snappiness * Time.fixedDeltaTime);
transform.localRotation = Quaternion.Euler(currentRotation);
}
public void RecoilFire()
{
targetRotation += new Vector3(recoilX, Random.Range(-recoilY, recoilY), Random.Range(-recoilZ, recoilZ));
}
}
Thank you for your help :)
I'm not sure where your Recoil class comes in as far as modifying your PlayerCam's orientation, but it sounds like your camera is being hard-reset to the value of the player's turn angles every frame, rather than combining them with the current recoil (sometimes called "punch") values.
To do a recoil/viewpunch setup correctly, you'll need to give your camera class access to an orientation that represents the current amount of rotation caused by the recoil, and combine that with the camera's current player angle setup.
Something like:
// get your current recoil offset here
Quaternion viewPunch = MyRecoil.transform.rotation;
// update the "base" rotation, aka where the player is looking
// (your existing code)
float mouseX = Input.GetAxis("Mouse X") * sensX;
float mouseY = Input.GetAxis("Mouse Y") * sensY;
yRotation += mouseX;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);
// final camera rotation = viewPunch * player angles.
// to rotate an orientation, we always do rotation * current,
// not the other way around.
// if the strength of the recoil has gone back to 0 or hasn't
// happened yet, we'll end up with the normal player angles,
// as expected.
// if your camera object is a child of another object, you may need to set localRotation instead
transform.rotation = viewPunch * Quaternion.Euler(xRotation, yRotation, 0);

Cursor lock state statement is not working in unity

I am following a first person tutorial on brackeys youtube
channel. This is the link:
https://www.youtube.com/watch?v=_QajrabyTJc
The tutorial requires me to lock my cursor but my cursor doesn't lock, I can move anywhere I would like to. The tutorial is a bit outdated so I am not sure if the code is too.
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseLook : MonoBehaviour
{
public float mouseSensitivity = 100f;
public Transform playerBody;
float xRotation = 0f;
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);
}
}
I have applied the script onto my camera if this information is needed.

Brackeys Fps Controller only moves camera up and down

The Problem
I am currently following Brackeys' First Person movement tutorial. However, I'm still stuck on the camera step as unlike most people having camera movement errors, I can only move my camera up and down (as opposed to only left and right).
The Code
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using UnityEngine;
public class mouselook : MonoBehaviour
{
public float mouseSensitivity = 100f;
public Transform playerBody;
float xRotation = 0f;
// Start is called before the first frame update
void Start()
{
}
// 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);
}
}
(the script is stored in the camera. playerBody links to a cylinder mesh.)
Every time you call transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f); you are resetting the y and z of the euler back to 0. I changed the update function to:
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
playerBody.Rotate(Vector3.up * mouseX);
playerBody.Rotate(Vector3.up * mouseX);
}
And I got more expected behavior. I didn't watch the tutorial you are talking about so it may be fixed/explained further on.

How to make the player walk in the direction it is pointing?

I made a simple movement system in Unity 3D, but I don't know how to make it so that I move in the direction my player is pointing in.
using UnityEngine;
public class PlayerControler : MonoBehaviour
{
CharacterController characterController;
public float MovementSpeed = 1f;
public float Gravity = 9.8f;
private float velocity = 0f;
void Start()
{
characterController = GetComponent<CharacterController>();
}
void Update()
{
float horizontal = Input.GetAxis("Horizontal") * MovementSpeed;
float vertical = Input.GetAxis("Vertical") * MovementSpeed;
characterController.Move((Vector3.right * horizontal + Vector3.forward * vertical) * Time.deltaTime);
if (characterController.isGrounded)
{
velocity = 0;
}
else
{
velocity -= Gravity * Time.deltaTime;
characterController.Move(new Vector3(0, velocity, 0));
}
}
}
This is the player controller.
using UnityEngine;
public class MouseControl : MonoBehaviour
{
public float horizontalSpeed = 1f;
public float verticalSpeed = 1f;
private float xRotation = 0.0f;
private float yRotation = 0.0f;
private Camera cam;
void Start()
{
cam = Camera.main;
}
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * horizontalSpeed;
float mouseY = Input.GetAxis("Mouse Y") * verticalSpeed;
yRotation += mouseX;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f);
cam.transform.eulerAngles = new Vector3(xRotation, yRotation, 0.0f);
}
}
This is the code that makes my character face where my cursor is.
Edit: This is a First-Person 3D game. The player has a CharacterControler component on it, and the Main Camera is a child of the player. The second piece of code changes the direction that the camera is facing when the cursor is moved. The first script is the movement script, and utilises the CharacterController component of the player to move. I want to make to that instead of going in four static directions every time I press a movement key, I want the player to move in proportion to the direction that the camera is facing (on the X axis). E.g: If I am facing West and I press “W” to go forwards, I want the character to go West instead of North.
Instead of the global vectors Vector3.forward and Vector3.right in
characterController.Move((Vector3.right * horizontal + Vector3.forward * vertical) * Time.deltaTime);
rather use your local direction vectors Transform.forward and Transform.right
characterController.Move((transform.right * horizontal + transform.forward * vertical) * Time.deltaTime);
#derHugo was right, but I forgot to update the angles in the player movement script, so it always thought that I was rotated 0,0,0.
using UnityEngine;
public class PlayerControler : MonoBehaviour
{
Vector3 angles;
CharacterController characterController;
MouseControl mouseControl;
public float MovementSpeed = 1f;
public float Gravity = 9.8f;
private float velocity = 0f;
void Start()
{
characterController = GetComponent<CharacterController>();
mouseControl = GetComponent<MouseControl>();
}
void Update()
{
angles = new Vector3(mouseControl.xRotation, mouseControl.yRotation, 0f);
transform.eulerAngles = angles;
float horizontal = Input.GetAxis("Horizontal") * MovementSpeed;
float vertical = Input.GetAxis("Vertical") * MovementSpeed;
characterController.Move((transform.right * horizontal + transform.forward * vertical) * Time.deltaTime);
if (characterController.isGrounded)
{
velocity = 0;
}
else
{
velocity -= Gravity * Time.deltaTime;
characterController.Move(new Vector3(0, velocity, 0));
}
}
}
Updated code
Note: I had to made the X and Y rotation variables public.
[HideInInspector]public float xRotation = 0.0f;
[HideInInspector]public float yRotation = 0.0f;

Unity/C# Weird glitch in FPS controller

i have a weird glitch, when i walk down from a corner (i dont press jump), the player will falling down with very fast speed. If i jump, then everything goes normal. (Its Quill18 FPS controller, i learn from there so thats why i dont use the built in controller instead)
using UnityEngine;
using System.Collections;
[RequireComponent (typeof(CharacterController))]
public class FirstPersonController : MonoBehaviour
{
public float movementSpeed = 5.0f;
public float mouseSensitivity = 5.0f;
public float jumpSpeed = 20.0f;
float verticalRotation = 0;
public float upDownRange = 60.0f;
float verticalVelocity = 0;
CharacterController characterController;
// Use this for initialization
void Start()
{
// Screen.lockCursor = true;
characterController = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
// Rotation
float rotLeftRight = Input.GetAxis("Mouse X") * mouseSensitivity;
transform.Rotate(0, rotLeftRight, 0);
verticalRotation -= Input.GetAxis("Mouse Y") * mouseSensitivity;
verticalRotation = Mathf.Clamp(verticalRotation, -upDownRange, upDownRange);
Camera.main.transform.localRotation = Quaternion.Euler(verticalRotation, 0, 0);
// Movement
float forwardSpeed = Input.GetAxis("Vertical") * movementSpeed;
float sideSpeed = Input.GetAxis("Horizontal") * movementSpeed;
verticalVelocity += Physics.gravity.y * Time.deltaTime;
if (characterController.isGrounded && Input.GetButton("Jump"))
{
verticalVelocity = jumpSpeed;
}
Vector3 speed = new Vector3(sideSpeed, verticalVelocity, forwardSpeed ;
speed = transform.rotation * speed;
characterController.Move(speed * Time.deltaTime);
}
}
The problem is that every frame you're running this line:
verticalVelocity += Physics.gravity.y * Time.deltaTime;
Thus, you're gaining "momentum" each second, and it wont stop ever until you jump because you're "resetting" the Y velocity to a normal value. I've ran into this problem before, and it can be fixed simply by only adding the Y velocity when you're not grounded. You can use Raycast to check if you have ground, and if you dont, increase verticalVelocity by that amount.

Categories