I am able to move player referring to this YouTube video.
FIRST PERSON MOVEMENT in Unity - FPS Controller
However, when a player jumps, if the direction of travel is a wall, the player cannot jump well.
like this
If I jump from a distance, I can jump onto the wall.
Camera Script:
public float mouseSensitivity;
[SerializeField]
Transform playerBody = default;
float xRotation = 0f;
private void Start()
{
Cursor.lockState = CursorLockMode.Locked;
}
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);
}
Movement Script:
[SerializeField]
CharacterController CharacterController = default;
[SerializeField]
LayerMask groundMask = default;
[SerializeField]
Transform groundCheck = default;
float groundDistance = 0.4f;
bool isGrounded = false;
public float playerSpeed;
public float playerGravity;
public float playerJumpSpeed;
Vector3 velocity;
private void Update()
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if (isGrounded && velocity.y < 0)
velocity.y = -2f;
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
CharacterController.Move(move * playerSpeed * Time.deltaTime);
if (Input.GetButtonDown("Jump") && isGrounded)
{
velocity.y = Mathf.Sqrt(playerJumpSpeed * -2f * playerGravity);
}
velocity.y += playerGravity * Time.deltaTime;
CharacterController.Move(velocity * Time.deltaTime);
}
Please tell me someone
i think it has something to do with these lines.
if (isGrounded && velocity.y < 0)
velocity.y = -2f;
Also check if the wall is on the ground mask because if it is it will be make the isGrounded be true which would be why it the player is falling like that
also i would recommend using a raycast instead of this:
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
Setting Step Offset of Character controller to 0 eliminated vibration. It can no longer walk on small steps, but now I can jump well.
Related
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThirdPersonMovement : MonoBehaviour
{
public CharacterController controller;
public float speed = 6f;
public float turnSmoothTime = 0.1f;
public Transform cam;
private float verticalVelocity;
private float gravity = 14.0f;
private float jumpForce = 10.0f;
float turnSmoothVelocity;
// Update is called once per frame
void Update()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;
if (direction.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
controller.Move(moveDir.normalized * speed * Time.deltaTime);
}
if (controller.isGrounded)
{
verticalVelocity = -gravity * Time.deltaTime;
if (Input.getKeyDown(KeyCode.Space))
{
verticalVelocity = jumpForce;
}
}
else
{
verticalVelocity -= gravity * Time.deltaTime;
}
Vector3 moveVector = Vector3.zero;
moveVector.x = Input.getAxis("Horizontal") * speed;
moveVector.y = verticalVelocity;
moveVector.z = Input.getAxis("Vertical") * speed;
controller.Move(moveVector * Time.deltaTime);
}
}
It has been giving me this error for a couple weeks and I can't figure it out.
I've tried seeing if anybody else has had any issues and looking back at how others have overcome this issue, but nothing seems to be working.
C# is case-sensitive.
moveVector.x = Input.GetAxis("Horizontal") * speed;
moveVector.y = verticalVelocity;
moveVector.z = Input.GetAxis("Vertical") * speed;
I am making code for a first person physics-based character controller in Unity. The movement is mostly smooth, but when I go up a slope, instead of sliding back down, the character floats in the air slightly while slowly moving downward until it gets back to the ground. This behavior is very strange and unexpected, and I don't really know why this is happening.
The character is an empty object with a capsule and a sphere childed to it. The script is on the empty object, and the rigidbody is on the capsule which is a child to the empty.
Here is the script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
float mouseSensitivity;
private float cameraXRotation;
private float cameraYRotation;
private float movementX;
private float movementY;
private Transform playerHeadTransform;
private Transform playerBodyTransform;
private Rigidbody playerRigidBody;
private bool IsJumping;
// Start is called before the first frame update
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
playerBodyTransform = transform.GetChild(0).gameObject.GetComponent<Transform>();
playerHeadTransform = transform.GetChild(0).transform.GetChild(0).gameObject.GetComponent<Transform>();
playerRigidBody = transform.GetChild(0).gameObject.GetComponent<Rigidbody>();
playerHeadTransform.transform.rotation = Quaternion.Euler(0f, 0f, 0f);
mouseSensitivity = 750;
IsJumping = false;
}
// Update is called once per frame
void Update()
{
#region CameraStuff
float cameraMouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
float cameraMouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
cameraXRotation -= cameraMouseY;
cameraYRotation += cameraMouseX;
cameraXRotation = Mathf.Clamp(cameraXRotation, -90f, 60);
playerHeadTransform.localRotation = Quaternion.Euler(cameraXRotation, 0f, 0f);
playerBodyTransform.localRotation = Quaternion.Euler(0f, cameraYRotation, 0f);
#endregion
//Movement input variables
movementX = Input.GetAxis("Horizontal") * mouseSensitivity * Time.deltaTime;
movementY = Input.GetAxis("Vertical") * mouseSensitivity * Time.deltaTime;
}
void FixedUpdate()
{
playerRigidBody.velocity = playerBodyTransform.TransformDirection(movementX*2, 0, movementY*2);
}
}
Your player not falling down is most probably related to you setting
void FixedUpdate()
{
playerRigidBody.velocity = playerBodyTransform.TransformDirection(movementX*2, 0, movementY*2);
}
if there is gravity involved you rather want to make sure to not overwrite the Y axis and do e.g.
var currentVelocity = playerRigidbody.velocity;
var newVelocity = playerBodyTransform.TransformDirection(movementX * 2, 0, movementY * 2);
// keep the velocity on Y but only if it is currently downwards
// so you can still move up on a slope but fall down with gravity
if(currentVelocity.y < 0) newVelocity.y = currentVelocity.y;
playerRigidBody.velocity = newVelocity;
when I jump up to an object that is a cube I reach the step offset and it jitters for a little bit before falling to the ground again. I can remove the step offset altogether but that's not what I want as my game is baste around parkour. when I was making this I was following a Brackeys tutorial on YouTube. Brackeys tutorial. can anyone help me out? ,first person object , the object causing most problems, objects in scene
using System.collections;
using System.Collections.Generic;
using UnityEngine;
public class keymovement : MonoBehaviour
{
public CharacterController controller;
public float speed = 12f;
public float gravity = -10f;
public Transform groundcheck;
public float groundDistance = 0.5f;
public LayerMask groundMask;
public float jumpheight = 3f;
Vector3 velocity;
bool isgrounded;
void Update()
{
isgrounded = Physics.CheckSphere(groundcheck.position, groundDistance, groundMask);
if (isgrounded && velocity.y < 0)
{
velocity.y = -2;
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
if (Input.GetButton("jump") && isgrounded)
{
velocity.y = Mathf.Sqrt(jumpheight * -2f * gravity);
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
}
}
}
Basically, the Character controller is fighting with the velocity of the movement script because of how it checks for slopes and steps.
An easy fix is to set the controller's slopeLimit to 90f while you are jumping:
void Update()
{
isgrounded = Physics.CheckSphere(groundcheck.position, groundDistance, groundMask);
if (isgrounded && velocity.y < 0)
{
velocity.y = -2;
controller.slopeLimit = 45f;
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
if (Input.GetButton("Jump") && isgrounded)
{
velocity.y = Mathf.Sqrt(jumpheight * -2f * gravity);
controller.slopeLimit = 90f;
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
I have began developing an fps script and followed a tutorial to help with the script. Everything works great now but the only issue is any objects in the view seem to stutter whenever the player is moving and rotating at the same time.
The script for the player's movement and camera rotation is below.
Can anybody point me in the right direction?
Thank you.
{
public Transform cam;
public Rigidbody rb;
public float camRotationSpeed = 5f;
public float camMinimumY = -60f;
public float camMaximumY = 75f;
public float rotationSmoothSpeed = 10f;
public float walkSpeed = 9f;
public float runSpeed = 14f;
public float maxSpeed = 20f;
public float jumpPower = 30f;
public float extraGravity = 45;
float bodyRotationX;
float camRotationY;
Vector3 directionIntentX;
Vector3 directionIntentY;
float speed;
public bool grounded;
void Update()
{
LookRotation();
Movement();
ExtraGravity();
GroundCheck();
if(grounded && Input.GetButtonDown("Jump"))
{
Jump();
}
}
void LookRotation()
{
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
bodyRotationX += Input.GetAxis("Mouse X") * camRotationSpeed;
camRotationY += Input.GetAxis("Mouse Y") * camRotationSpeed;
camRotationY = Mathf.Clamp(camRotationY, camMinimumY, camMaximumY);
Quaternion camTargetRotation = Quaternion.Euler(-camRotationY, 0, 0);
Quaternion bodyTargetRotation = Quaternion.Euler(0, bodyRotationX, 0);
transform.rotation = Quaternion.Lerp(transform.rotation, bodyTargetRotation, Time.deltaTime * rotationSmoothSpeed);
cam.localRotation = Quaternion.Lerp(cam.localRotation, camTargetRotation, Time.deltaTime * rotationSmoothSpeed);
}
void Movement()
{
directionIntentX = cam.right;
directionIntentX.y = 0;
directionIntentX.Normalize();
directionIntentY = cam.forward;
directionIntentY.y = 0;
directionIntentY.Normalize();
rb.velocity = directionIntentY * Input.GetAxis("Vertical") * speed + directionIntentX * Input.GetAxis("Horizontal") * speed + Vector3.up * rb.velocity.y;
rb.velocity = Vector3.ClampMagnitude(rb.velocity, maxSpeed);
if (Input.GetKey(KeyCode.LeftShift))
{
speed = runSpeed;
}
if (!Input.GetKey(KeyCode.LeftShift))
{
speed = walkSpeed;
}
}
void ExtraGravity()
{
rb.AddForce(Vector3.down * extraGravity);
}
void GroundCheck()
{
RaycastHit groundHit;
grounded = Physics.Raycast(transform.position, -transform.up, out groundHit, 1.25f);
}
void Jump()
{
rb.AddForce(Vector3.up * jumpPower, ForceMode.Impulse);
}
}
This probably happens because the frame needs to update the camera rotation and the player position at the same time. i would suggest doing the rotation of the camera in fixed update. because this will run at the end of each frame.
like this:
void FixedUpdate()
{
LookRotation();
}
another thing i would suggest is to move the player while the groundcheck is being ran, because if you do it seperately i can see a bug coming up when the player moves faster then the code can run or something. so a tip would be or to run it inside the movement method, or call the method while you are calling the movement method.
this:
void Movement()
{
directionIntentX = cam.right;
directionIntentX.y = 0;
directionIntentX.Normalize();
directionIntentY = cam.forward;
directionIntentY.y = 0;
directionIntentY.Normalize();
rb.velocity = directionIntentY * Input.GetAxis("Vertical") * speed + directionIntentX * Input.GetAxis("Horizontal") * speed + Vector3.up * rb.velocity.y;
rb.velocity = Vector3.ClampMagnitude(rb.velocity, maxSpeed);
if (Input.GetKey(KeyCode.LeftShift))
{
speed = runSpeed;
}
if (!Input.GetKey(KeyCode.LeftShift))
{
speed = walkSpeed;
}
GroundCheck();
}
or litteraly copy and paste the code within your movement method.
void Update ()
{
Vector3 input = new Vector3 (0, 0, 1);
Vector3 direction = input.normalized;
Vector3 velocity = direction * speed;
Vector3 moveAmount = velocity * Time.deltaTime;
transform.position += moveAmount;
if(Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
player.AddForce (Vector3.up * jumpForce, ForceMode.Impulse);
}
}
Since Time.deltaTime varies moveAmount also varies for every jump making the distance of the jump vary slightly.
The ball is to jump between blocks separated by a fixed gap and therefore the above behaviour causes problems.
Is there any way I can fix this and make fixed length jumps?
You can use CharacterController for this. Make sure you have a CharacterController and Collider attached to your gameobject. Also if you have a rigibody attached to your game object it may cause it to behave unexpectedly so you might have to contraint it.
public CharacterController controller;
private float verticalVelocity;
private float gravity = 25.0f;
private float jumpForce = 15.0f;
void Awake () {
controller = GetComponent<CharacterController>();
}
void Update () {
if( controller == null )
return;
if( controller.isGrounded)
{
verticalVelocity = -gravity * Time.deltaTime;
if( Input.GetKeyDown(KeyCode.Space) )
{
verticalVelocity = jumpForce;
}
}
else
{
verticalVelocity -= gravity * Time.deltaTime;
}
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
Vector3 moveVector = Vector3.zero;
moveVector.x = moveHorizontal * 5.0f;
moveVector.y = verticalVelocity;
moveVector.z = moveVertical * 5.0f;
controller.Move(moveVector * Time.deltaTime);
}
Check this tutorial for reference: https://www.youtube.com/watch?v=miMCu5796KM