I have a simple script to move and look around when I turn the camera doesn't turn with the character how do I make them turn together.
using System.Collections.Generic;
using UnityEngine;
public class PlayerFollow : MonoBehaviour
{
public Transform PlayerTransform;
private Vector3 _cameraOffset;
public float rotationSpeed = 1;
public Transform Target, Player;
float mouseX, mouseY;
[Range(0.01f, 1.0f)]
public float SmoothFactor = 0.5f;
public bool LookAtPlayer = false;
// Start is called before the first frame update
void Start()
{
_cameraOffset = transform.position - PlayerTransform.position;
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
// Update is called once per frame
void LateUpdate()
{
CamControl();
Vector3 newPos = PlayerTransform.position + _cameraOffset;
transform.position = Vector3.Slerp(transform.position, newPos, SmoothFactor);
/*if(LookAtPlayer){
transform.LookAt(PlayerTransform);
}*/
}
void CamControl()
{
mouseX += Input.GetAxis("Mouse X") * rotationSpeed;
mouseY += Input.GetAxis("Mouse Y") * rotationSpeed * -1;
mouseY = Mathf.Clamp(mouseY, -35, 60);
transform.LookAt(Target);
Target.rotation = Quaternion.Euler(mouseY, mouseX, 0);
Player.rotation = Quaternion.Euler(0, mouseX, 0);
}
}
[Picture Of Workspace]
I think You should make the camera child of the player and then attach this code to the player.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController characterController;
public float speed;
private Vector3 camRotation;
private Transform cam;
private Vector3 moveDirection;
[Range(-45, -15)]
public int minAngle = -30;
[Range(30, 80)]
public int maxAngle = 45;
[Range(50, 500)]
public int sensitivity = 200;
private void Awake()
{
cam = Camera.main.transform;
}
void Update()
{
Move();
Rotate();
}
private void Rotate()
{
transform.Rotate(Vector3.up * sensitivity * Time.deltaTime * Input.GetAxis("Mouse X"));
camRotation.x -= Input.GetAxis("Mouse Y") * sensitivity * Time.deltaTime;
camRotation.x = Mathf.Clamp(camRotation.x, minAngle, maxAngle);
cam.localEulerAngles = camRotation;
}
private void Move()
{
float horizontalMove = Input.GetAxis("Horizontal");
float verticalMove = Input.GetAxis("Vertical");
if (characterController.isGrounded)
{
moveDirection = new Vector3(horizontalMove, 0, verticalMove);
moveDirection = transform.TransformDirection(moveDirection);
}
moveDirection.y -= gravity * Time.deltaTime;
characterController.Move(moveDirection * speed * Time.deltaTime);
}
}
Please do not forget to add a Character Controller to the player, and then assign it in the inspector.
Related
this is my PlayerMovement script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController controller;
public float turnSmoothTime = 0.1f;
float turnSmoothVelocity;
public float Speed = 10f;
private Vector3 moveDirection;
public float groundDistance = 0.4f;
public float gravity = -9.81f;
public float jumpPower = 3.5f;
public float directionY;
bool isGrounded;
public Animator anim;
public Transform cam;
private void Update()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
moveDirection = new Vector3(horizontal, 0f, vertical).normalized;
if (controller.isGrounded)
{
if (Input.GetKeyDown(KeyCode.Space))
{
directionY = jumpPower;
}
else
{
directionY = 0;
}
}
if (!controller.isGrounded)
{
directionY += gravity * Time.deltaTime;
}
moveDirection.y = directionY;
if (moveDirection.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(moveDirection.x, moveDirection.z) * Mathf.Rad2Deg;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
controller.Move(moveDirection * Speed * Time.deltaTime);
}
bool hasHorizontalInput = !Mathf.Approximately(horizontal, 0f);
bool hasVerticalInput = !Mathf.Approximately(vertical, 0f);
bool isWalking = hasHorizontalInput || hasVerticalInput;
}
}
I want to make smooth jump system using by characterController.
My code works fine in the ground state, but when I press space(for jump), it returns the current rotation y value to 0.
(I think this problem is because the jump's position value is y, but the movement's rotation value is also y.)
how do i solve it? I want the rotation value not to change even if I jump.
I solved.
It was a code execution order issue.
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;
if (controller.isGrounded && Input.GetButton("Jump"))
{
movingDirection.y = jumpSpeed;
}
movingDirection.y -= gravity * Time.deltaTime;
controller.Move(movingDirection * Time.deltaTime * speed);
if (direction.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
controller.Move(direction * speed * Time.deltaTime);
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField] Transform playerCamera = null;
[SerializeField] float xSensitivity = 4.0f;
[SerializeField] float ySensitivity = 4.0f;
[SerializeField] float moveSpeed = 6.0f;
[SerializeField] float gravity = -13.0f;
[SerializeField][Range(0.0f, 0.1f)] float moveSmoothTime = 0.05f;
[SerializeField][Range(0.0f, 0.2f)] float mouseSmoothTime = 0.03f;
[SerializeField] bool lockCursor = true;
float cameraPitch = 0.0f;
float velocityY = 0.0f;
CharacterController controller = null;
Vector2 currentDir = Vector2.zero;
Vector2 currentDirVelocity = Vector2.zero;
Vector2 currentMouseDelta = Vector2.zero;
Vector2 currentMouseDeltaVelocity = Vector2.zero;
public Vector3 jump;
public float jumpForce = 8.0f;
public bool isGrounded;
Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
jump = new Vector3(0.0f, 2.0f, 0.0f);
controller = GetComponent<CharacterController>();
if(lockCursor)
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
}
// Update is called once per frame
void Update()
{
UpdateMouseLook();
UpdateMovement();
OnCollisionStay();
UpdateJump();
}
void UpdateMouseLook()
{
Vector2 targetMouseDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
currentMouseDelta = Vector2.SmoothDamp(currentMouseDelta, targetMouseDelta, ref currentMouseDeltaVelocity, mouseSmoothTime);
cameraPitch -= currentMouseDelta.y * ySensitivity;
cameraPitch = Mathf.Clamp(cameraPitch, -70.0f, 70.0f);
playerCamera.localEulerAngles = Vector3.right * cameraPitch;
transform.Rotate(Vector3.up * currentMouseDelta.x * xSensitivity);
}
void UpdateMovement()
{
Vector2 targetDir = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
targetDir.Normalize();
currentDir = Vector2.SmoothDamp(currentDir, targetDir, ref currentDirVelocity, moveSmoothTime);
if (controller.isGrounded)
velocityY = 0.0f;
velocityY += gravity * Time.deltaTime;
Vector3 velocity = (transform.forward * currentDir.y + transform.right * currentDir.x) * moveSpeed + Vector3.up * velocityY;
controller.Move(velocity * Time.deltaTime);
}
void OnCollisionStay()
{
isGrounded = true;
}
void UpdateJump()
{
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
rb.AddForce(jump * jumpForce, ForceMode.Impulse);
isGrounded = false;
Debug.Log("JUMP");
}
}
}
In my script I can't seem to get the UpdateJump function to work as intended. When I press space I get the console message but the rb.AddForce appears to do nothing. what is the reason that I can't get my player controller to jump and how can I go about fixing this and making sure it doesn't occur again further down the line.
I'm trying to create a smooth mouse look for my First-Person game. using the new input system like so:
public class MouseLook : MonoBehaviour
{
[SerializeField] float sensitivityX = 8f;
[SerializeField] float sensitivityY = 0.5f;
float mouseX, mouseY;
[SerializeField] Transform playerCamera;
[SerializeField] float xClamp = 75f;
float xRotataion = 0f;
private void Update()
{
transform.Rotate(Vector3.up, mouseX * Time.fixedDeltaTime);
xRotataion -= mouseY;
xRotataion = Mathf.Clamp(xRotataion, -xClamp, xClamp);
Vector3 targetRotation = transform.eulerAngles;
targetRotation.x = xRotataion;
playerCamera.eulerAngles = targetRotation;
}
public void ReceiveInput(Vector2 mouseInput)
{
mouseX = mouseInput.x * sensitivityX;
mouseY = mouseInput.y * sensitivityY;
}
}
Here is the InputManager class :
Vector2 mouseInput;
private void Awake()
{ groundMovement.MouseX.performed += ctx => mouseInput.x = ctx.ReadValue<float>();
groundMovement.MouseY.performed += ctx => mouseInput.y = ctx.ReadValue<float>();
}
private void Update()
{
movement.ReceiveInput(horizontalInput);
mouseLook.ReceiveInput(mouseInput);
}
private void OnEnable()
{
controls.Enable();
}
private void OnDestroy()
{
controls.Disable();
}
However, for some reason the mouse movement is jittery. So I wanted to use my code I was using before for the old input system which is this:
[SerializeField][Range(0.0f, 0.5f)] float mouseSmoothTime = 0.03f;
[SerializeField] float mouseSensitivity = 3.5f;
float cameraPitch = 0.0f;
Vector2 currentMouseDelta = Vector2.zero;
Vector2 currentMouseDeltaVelocity = Vector2.zero;
private void Update()
{
Vector2 targetMouseDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
currentMouseDelta = Vector2.SmoothDamp(currentMouseDelta, targetMouseDelta, ref currentMouseDeltaVelocity, mouseSmoothTime);
cameraPitch -= currentMouseDelta.y * mouseSensitivity;
cameraPitch = Mathf.Clamp(cameraPitch, -90.0f, 90.0f);
playerCamera.localEulerAngles = Vector3.right * cameraPitch;
transform.Rotate(Vector3.up * currentMouseDelta.x * mouseSensitivity);
}
But how can I configure this for the new input system and still be able to use this ?
public void ReceiveInput(Vector2 mouseInput)
{
mouseX = mouseInput.x * sensitivityX;
mouseY = mouseInput.y * sensitivityY;
}
Upgrade it as below. With the method below you can have mouse delta like the same as in the old system:
Vector2 targetMouseDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
Vector2 targetMouseDelta = Mouse.current.delta.ReadValue()*Time.smoothDeltaTime;
I'm using the mouse for looking around and it is working properly when looking up and down, but when looking left or right it moves really slow and it has jittery movement. I don't see why.
Here is my Movement class:
public class Movement : MonoBehaviour
{
[SerializeField] CharacterController controller;
[SerializeField] float speed = 15f;
Vector2 horizontalInput;
[SerializeField] float jumpHeight = 3.5f;
bool jump;
[SerializeField] float gravity = -30f; //-9.81
Vector3 verticalVelocity = Vector3.zero;
[SerializeField] LayerMask groundMask;
bool isGrounded;
private void Update()
{
isGrounded = Physics.CheckSphere(transform.position, 0.1f, groundMask);
if (isGrounded)
{
verticalVelocity.y = 0;
}
Vector3 horizontalVelocity = (transform.right * horizontalInput.x + transform.forward *
horizontalInput.y ) * speed;
controller.Move(horizontalVelocity * Time.deltaTime);
// Jump: v = sqrt(-2 * jumpheight* gravity)
if (jump)
{
if (isGrounded)
{
verticalVelocity.y = Mathf.Sqrt(-2f * jumpHeight * gravity);
}
jump = false;
}
verticalVelocity.y += gravity * Time.deltaTime;
controller.Move(verticalVelocity * Time.deltaTime);
}
public void ReceiveInput(Vector2 _horizontalInput)
{
horizontalInput = _horizontalInput;
}
public void OnJumpPressed()
{
jump = true;
}
}
MouseLook class:
public class MouseLook : MonoBehaviour
{
[SerializeField] float sensitivityX = 8f;
[SerializeField] float sensitivityY = 0.5f;
float mouseX, mouseY;
[SerializeField] Transform playerCamera;
[SerializeField] float xClamp = 85f;
float xRotataion = 0f;
private void Update()
{
transform.Rotate(Vector3.up, mouseX * Time.deltaTime);
xRotataion -= mouseY;
xRotataion = Mathf.Clamp(xRotataion, -xClamp, xClamp);
Vector3 targetRotation = transform.eulerAngles;
targetRotation.x = xRotataion;
playerCamera.eulerAngles = targetRotation;
}
public void ReceiveInput(Vector2 mouseInput)
{
mouseX = mouseInput.x * sensitivityX;
mouseY = mouseInput.y * sensitivityY;
}
}
Because I'm using the new input system here is my InputManager class:
public class InputManager : MonoBehaviour
{
[SerializeField] Movement movement;
[SerializeField] MouseLook mouseLook;
PlayerControls controls;
PlayerControls.GroundMovementActions groundMovement;
Vector2 horizontalInput;
Vector2 mouseInput;
private void Awake()
{
controls = new PlayerControls();
groundMovement = controls.GroundMovement;
// groundMovement.[action].performed += context => do something
groundMovement.HorizontalMovement.performed += ctx => horizontalInput = ctx.ReadValue<Vector2>();
groundMovement.Jump.performed += _ => movement.OnJumpPressed();
groundMovement.MouseX.performed += ctx => mouseInput.x = ctx.ReadValue<float>();
groundMovement.MouseY.performed += ctx => mouseInput.y = ctx.ReadValue<float>();
}
private void Update()
{
movement.ReceiveInput(horizontalInput);
mouseLook.ReceiveInput(mouseInput);
}
private void OnEnable()
{
controls.Enable();
}
private void OnDestroy()
{
controls.Disable();
}
}
I tried setting sensitivityX to a larger number but the jitter effect is still there.
How would I fix that and make it smooth?
I updated my code, my current problem is just that the movement of the player doesn't work anymore and I would like to know what I have to do so that I can adjust the height of the jump and that when this height is reached, gravity comes through again
Code:
//Private Variables
private CharacterController _chaCont;
private float currentGravity;
private Vector3 finalMovement;
//Globally delared
//Public Variables
public float speed;
public float gravity;
public float jumpSpeed;
// Start is called before the first frame update
void Start()
{
_chaCont = gameObject.GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
finalMovement = jump() + ApplyGravity();
}
_chaCont.Move(finalMovement * Time.deltaTime);
}
Vector3 ApplyGravity()
{
Vector3 gravityMovement = new Vector3(0, -currentGravity, 0);
currentGravity += gravity * Time.deltaTime;
if (_chaCont.isGrounded)
{
if (currentGravity > 1f)
currentGravity = 1f;
}
return gravityMovement;
}
Vector3 Movement()
{
Vector3 moveVector = Vector3.zero;
moveVector += transform.forward * Input.GetAxis("Vertical");
moveVector += transform.right * Input.GetAxis("Horizontal");
moveVector *= speed;
return moveVector;
}
Vector3 jump()
{
Vector3 jumpVector = Vector3.zero;
jumpVector += transform.up * Input.GetAxis("Jump");
jumpVector *= jumpSpeed;
return jumpVector;
}
}
Good Night. Have you tried the input system C# provides should be like below code.
//Private Variables
private CharacterController _chaCont;
private float currentGravity;
private Vector3 finalMovement; //Globally delared
//Public Variables
public float speed;
public float gravity;
// Start is called before the first frame update
void Start()
{
_chaCont = gameObject.GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
Vector3 initialMovement = Movement();
if(Input.GetKeyDown(KeyCode.Space)){
finalMovement = initialMovement + ApplyGravity();
}
else{
finalMovement = initialMovement;
}
_chaCont.Move(finalMovement * Time.deltaTime);
}
Vector3 ApplyGravity()
{
Vector3 gravityMovement = new Vector3(0, -currentGravity, 0);
currentGravity += gravity * Time.deltaTime;
if (_chaCont.isGrounded)
{
if (currentGravity > 1f)
currentGravity = 1f;
}
return gravityMovement;
}
Vector3 Movement()
{
Vector3 moveVector = Vector3.zero;
moveVector += transform.forward * Input.GetAxis("Vertical");
moveVector += transform.right * Input.GetAxis("Horizontal");
moveVector *= speed;
return moveVector;
}