Unity 3D first person movement - c#

I'm following brackeys 1st person movement tutorial. but I can't get the camera working.
I followed the tutorial correctly, But this code isn't working. gives no errors but it doesn't work. here's 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;
// 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);
}
}
This code gives no errors but doesn't work. how can i fix this?

The code you've attached is correct.
I recommend you follow the tutorial once more and pay close attention to where this script should be attached.
Having checked the tutorial myself right now I got it to work by parenting camera as a child of player, attaching MouseLook.cs to Camera game object, and setting player game object as a Player Body variable in MouseLook.cs.I recommend making sure that mouseSensitivity variable is set to 100. Next, if that won't solve your issue, it could mean a number of things.
First, your project can have Axis "Mouse X" and "Mouse Y" unset, meaning that it does not record the movement of your mouse when you move it.
Second, player or camera rotation can be overridden by some other behavior that might cause MouseLook rotation to be ignored.

Related

Character randomly rotating on the X and Z axes even thought Rigidbody constraints are enabled

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
class FirstPersonCamera : MonoBehaviour
{
public float mouseSensitivity = 100f;
public Transform playerTransform;
public Transform weaponTransform;
private float xRotation = 0;
void Start()
{
UnityEngine.Cursor.lockState = CursorLockMode.Locked; //Hides the cursor and locks it to the center
}
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, -90, 90);
transform.localRotation = Quaternion.Euler(xRotation, 0, 0);
weaponTransform.localRotation = Quaternion.Euler(xRotation, 0, 0);
playerTransform.Rotate(new Vector3(0.0f, mouseX, 0.0f));
//playerTransform.gameObject.GetComponent<Rigidbody>().MoveRotation(Quaternion.Euler(0.0f,mouseX,0.0f));
if (Input.GetKeyDown(KeyCode.Escape))
{
UnityEngine.Cursor.lockState = CursorLockMode.None;
}
}
}
This is what I'm using for player looking (mouse controls) and this keeps happening:
even though I have rigidbody X and Z rotations locked. The issue mainly seems to arise when using keyboard controls and mouse together. Here is the playerMove code as well: https://codeshare.io/wnzrYj . It shouldn't be doing anything with rotation.
I've tried removing the playerTransform.Rotate and the issue seems to disappear. I've also tried rotating the gameObject via the rigidbody but that doesn't seem to rotate the body at all.
You're causing the rotations yourself. You've added the xRotation, which will affect the pitch, but then you use Transform.Rotate, which works locally. That means that when pitched, your Rotate is no longer around the world's Y axis, but rather around the object's pitched Y-axis, adding rotation to axes you don't want.
The easiest way to solve this is to build your hierarchy properly to make sure that the rotations are applied in the order you want. I usually go with something like:
Root -> YawPivot -> Body -> PitchPivot -> Head/Camera
The Root object would have the translations (offsets/movement) applied to it. The YawPivot is only rotated around the Y axis. And the PitchPivot is only rotated around the X axis (and is usually located around the neck or head area).

Player moves at a very slow speed in Unity

I'm making a first-person movement script for the player, and everything movement-wise seems to work fine (other than an unrelated issue of the player not moving in the camera's direction), however when running in the game, the player moves at a very slow speed.
Here's the movement script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private Rigidbody RB;
[SerializeField] private GameObject cam;
private float walkVel; // Forward & backward movement
private float strafeVel; // Sideways movement
[SerializeField] public float walkSpeed = 5f;
private void Start()
{
RB = GetComponent<Rigidbody>();
}
private void Update()
{
walkVel = Input.GetAxis("Vertical");
strafeVel = Input.GetAxis("Horizontal");
}
private void FixedUpdate()
{
transform.localRotation = Quaternion.Euler(0f, cam.transform.rotation.y * Time.deltaTime, 0f);
Vector3 Up = new Vector3(RB.velocity.x, RB.velocity.y, RB.velocity.z);
RB.velocity = (transform.forward * strafeVel + transform.right * walkVel).normalized * walkSpeed * Time.deltaTime;
}
}
I'm pretty sure the issue is not related to the camera script, but here it is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCamPositioning : MonoBehaviour
{
private Vector2 camTurn;
[SerializeField] public float camSensitivity = 5f;
private void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
private void Update()
{
camTurn.x += Input.GetAxis("Mouse X") * camSensitivity;
camTurn.y -= Input.GetAxis("Mouse Y") * camSensitivity;
transform.localRotation = Quaternion.Euler(camTurn.y, camTurn.x, 0);
}
}
I tried to implement a very basic velocity script, and alternatively RB.AddVelocity to the Rigidbody, however it did not solve my problem.
I also tried simply increasing the walkSpeed variable to increase player speed, which actually solves my problem, HOWEVER I want to refrain from using this solution as previously the player moved at a relatively normal speed with walkSpeed set to 5f.
Sounds like you just need to tweak your values. Try splitting your equation into pieces and logging the individual and multiplied value so you can understand what values you see versus what values you're expecting.
I see many variables in your code that can be less than 1. strafeVel, walkVel and Time.deltaTime. In fact, in my experience, Time.deltaTime is always a very small float.
Perhaps you would prefer to use RB.velocity with += or *= along with a Mathf.Clamp() to gradually increase your speed.
All I had to do to solve my problem was remove Time.deltaTime from the RB.Velocity vector. The vector already runs in the FixedUpdate function, so I think it should work as intended now.

Why can't I look horizontally in Unity3D after adding this line(FPS)?

I was following Brackeys's tutorial on youtube to make my character look horizontally and vertically, at first I was able to look to my right and left in with my mouse, but after I added this line near the end of void update():
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
I can look up and down but can't look to left and right anymore. Could anyone tell me how to fix it? It is confusing because it worked fine in the video tutorial.
Here's my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MouseLook : MonoBehaviour
//https://www.youtube.com/watch?v=_QajrabyTJc
{
public float MouseSensitivity = 100f;
//this variable controls the speed of the mouse
public Transform PlayerBody;
float xRotation = 0f;
// Start is called before the first frame update
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
//this line is to hide the ouse cursor in game
}
// 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;
//these 2 variables will store the movement input from mouse
//this enables us to look horizontally (rotate around Y Axis)
//InvalidOperationException: You are trying to read Input using the UnityEngine.Input class, but you have switched active Input handling to Input System package in Player Settings.
//MouseLook.Update() this is a but that will appear after this line was added, to fix this
//Project Settings > Player > Active Input Handling change it to both and add camera to playerbody
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation,-90,90f);//this line prevent player to rotate over its head/crotch
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f); *This line!*
PlayerBody.Rotate(Vector3.up * mouseX);
//line 31-33 is for the function to be able to look up and down
//remember Quaternion is about rotation
}
}
This line:
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
It in the Update void, so it will call every frame. You can't look vertically because
every in every frame, this line will make your character y rotation equal to 0
You can see more in here
To fix that you can make a variable call yRotation or something you want then make it like the xRotation but with your mouseY variable and then edit that line to
transform.localRotation = Quaternion.Euler(xRotation, yRotation, 0f);
Thank you guys!
It worked after I:
Declared this new variable
float yRotation = 0f;
Set yRotation to be equal to mouseX + itself
yRotation += mouseX;
Changed the problematic line to what #HiggHigg suggested
transform.localRotation = Quaternion.Euler(xRotation, yRotation, 0f);
Now I can look to 4 directions in FPS with my cursor, the screen kinda shivers when I move though, maybe I'll find a way to fix it later.

Camera shaking on rotating player while crouching in unity

I am having a problem with the camera following the player. When the player moves, the camera shakes and this effect is more noticeable when the player is in the crouched position. I am using root motion for the player with animations by mixamo.
Player Script:
Transform cameraT;
void Start () {
cameraT = Camera.main.transform;
}
void FixedUpdate ()
{
float sideMotion = Input.GetAxis("SideMotion");
float straightMotion= Input.GetAxis("StraightMotion");
if (Mathf.Abs(sideMotion) > 0 || Mathf.Abs(straightMotion) > 0)
{
transform.eulerAngles = new Vector3(transform.eulerAngles.x,
cameraT.eulerAngles.y);
}
}
Camera Script:
public float distanceFromPlayer=2f;
public float mouseSensitivity=6;
public Transform player;
public Vector2 pitchConstraint= new Vector2(-30,80);
Vector3 rotationSmoothVelocity;
Vector3 currentRotation;
public float rotationSmoothTime = 0.2f;
float yaw; //Rotation around the vertical axis is called yaw
float pitch; //Rotation around the side-to-side axis is called pitch
private void LateUpdate()
{
yaw += Input.GetAxis("Mouse X") * mouseSensitivity;
pitch -= Input.GetAxis("Mouse Y") * mouseSensitivity;
pitch = Mathf.Clamp(pitch, pitchConstraint.x, pitchConstraint.y);
currentRotation = Vector3.SmoothDamp
(currentRotation, new Vector3(pitch, yaw), ref rotationSmoothVelocity, rotationSmoothTime);
transform.eulerAngles = currentRotation;
transform.position = player.position - transform.forward * distanceFromPlayer;
}
For public transform I just added an empty game object to player chest level and parented it to the player. I got the rotating camera smoothly trick from an online tutorial but that exact thing won't work on player rotation though.
A character controller is attached to player without any rigidbody or collider.
You are going to want to use Lerp on the camera in order to smooth its motion from one position to another. The Scripting API has a good example of Vector3.Lerp.
So in your case, you could add a public variable for smoothing position as well. Something like positionSmoothTime. Then make a "Desired Position" variable, we'll call it destPosition.
Vector3 destPosition = player.position - transform.forward * distanceFromPlayer;
transform.position = Vector3.Lerp(transform.position, destPosition, positionSmoothTime);
This should effectively smooth it to where the stuttering should go away. Another thing that will help that someone else mentioned is using a part of the body that moves less (Like the head) as the target. This combined with the Lerp function will give you a smooth camera movement.
Another large help would be to move things into the Update() function. The reason being is FixedUpdate() doesn't get called every frame. So you could potentially get stutter as a result. If you move everything into Update() it will update every frame and help smooth things out. If you do this though you will need to multiply all movement by Time.deltaTime as shown in the example below.
Vector3 destPosition = (player.position - transform.forward * distanceFromPlayer) * Time.deltaTime;
For more examples, check the links to each function to see Unity's documentation on it. It has examples of everything I've shown here.

Unity3D C#. Using the transform.RotateAround() function while keep the distance between two objects constant

I am trying to practice making third person controllers in Unity 3D. I am a beginner, and I am completely baffled on how to make my controller functional. I have been doing hours of research, but no thread I can find seem to answer my question. I have two scripts, a CameraController, and a CharacterController. My code is below.
CameraController:
using UnityEngine;
using System.Collections;
public class CameraController : MonoBehaviour {
public GameObject target;
public float rotationSpeed;
Vector3 offset;
Vector3 CameraDestination;
// Use this for initialization
void Start () {
offset = transform.position - target.transform.position;
CameraDestination = offset + transform.position;
rotationSpeed = 50f;
transform.position = CameraDestination;
}
// Update is called once per frame
void Update () {
transform.LookAt (target.transform.position);
float h = Input.GetAxisRaw ("Horizontal");
transform.RotateAround (target.transform.position, Vector3.up, Time.deltaTime * h * rotationSpeed);
target.transform.Rotate (0f, Time.deltaTime * h * rotationSpeed, 0f);
}
}
CharacterController:
using UnityEngine;
using System.Collections;
public class CharController : MonoBehaviour {
public float playerSpeed = 10f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
float Vertical = Input.GetAxis("Vertical");
transform.position += transform.forward * Time.deltaTime * playerSpeed * Vertical;
}
}
When either the left or right arrow key is pressed, both the player and the camera rotates. If I try to attach the camera to the player as a children, the camera's rotation becomes messed up, but if I do not attach the camera to the player, the camera stops following the player. If I try to set the camera to a specific position relative to the player, it stops revolving around the player like it is intended to do. I simply can not come up with a method that works.Thank you for answering my question in advance!
When I go about this, I like to have an empty gameObject which has 2 children, the camera and then the mesh of the character.
> CharacterController
> Camera
> CharacterRig
When you want to rotate the character, rotate the CharacterController, then when you want to rotate the Camera around the character, change your code to:
transform.RotateAround (CharacterRig.transform.position, Vector3.up, Time.deltaTime * h * rotationSpeed);
This will allow your camera to rotate irrespective of any character animation and should solve your issue. This is very important if you want to implement animations later, as you don't want to parent the camera to the thing that is being animated because it will move with the animation.
P.s. Your code appears fine. Certain that it is purely the way you have set up the game objects.

Categories

Resources