- Home /
Player sprints, but doesn't return to normal speed
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class PlayerMovement : MonoBehaviour {
public CharacterController controller;
//**** WALKSPEED AND NORMALSPEED NEED TO BE THE SAME
public float walkSpeed = 12f;
public float jumpHeight = 100f;
public float sprintSpeed = 18f;
public float moveSpeed = 0f;
public float gravity = -9.81f;
Vector3 velocity;
Vector3 moveDirection;
public Transform groundDetector;
public float groundDistance = 0.4f;
public LayerMask groundMask;
bool isGrounded;
void Start()
{
controller = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
isGrounded = Physics.CheckSphere(groundDetector.position, groundDistance, groundMask);
float moveX = Input.GetAxis("Horizontal");
float moveZ = Input.GetAxis("Vertical");
if (isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
if (isGrounded && Input.GetKeyDown(KeyCode.Space))
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
//Sprint if player is holding left-shift and "W" at the same time, should return to walking speed when left-shift is let go.
moveDirection = new Vector3(moveX, 0, moveZ);
Debug.Log(moveDirection);
if (Input.GetKeyDown(KeyCode.LeftShift) && moveZ == 1 && isGrounded)
{
walkSpeed = sprintSpeed;
}
if(moveZ == -1)
{
Debug.Log("Moving backwards");
}
Vector3 move = transform.right * moveX + transform.forward * moveZ;
controller.Move(move * walkSpeed * Time.deltaTime); ;
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
}
Answer by Ermiq · Feb 22, 2021 at 10:50 AM
You set walkSpeed to sprintSpeed and never set it back to walkSpeed. Also, you never check if the Shift has been released. So, your code will never get back to walkSpeed.
Also, notice that GetKeyDown() returns true only once in the one exact frame update when the button has been pressed. In any other moment it's always false.
In your case you need to use GetKey() instead. This one will continuously return true in every frame while the user holds the button pressed, and will return false in any other frame when the button is not held down (released).
Also, to not mess things up you'd better use one more variable, to have non-changable walkSpeed and sprintSpeed and add a new currentSpeed as the one that will be assigned with 12f or 18f depending on does the character sprint or not.
if (Input.GetKey(KeyCode.LeftShift) && moveZ == 1 && isGrounded)
{
currentSpeed = sprintSpeed;
}
else
{
currentSpeed = walkSpeed;
}
...
controller.Move(move * currentSpeed * Time.deltaTime);
Answer by Megaboy238 · Feb 21, 2021 at 11:25 PM
You have set walkSpeed as sprintSpeed overwriting it, i think you were meant to set moveSpeed = sprintSpeed and the in controller.Move(move moveSpeed Time.deltaTime);
and there is a double ; at the end of that line
I tried changing it to "moveSpeed = sprintSpeed" and also changed the other line to "controller.Move(move moveSpeed Time.deltaTime)", but then another problem occurs where the player doesn't move till I press "W + left-shift", probably because I've set moveSpeed to 0?
try this or something like it
if (Input.GetKeyDown(KeyCode.LeftShift) && moveZ == 1 && isGrounded)
{
moveSpeed = sprintSpeed;
}
else if(moveZ == 1)
{
moveSpeed = walkSpeed;
}
else
{
moveSpeed = 0f;
}
Yes correct, sorry thought walkSpeed was controlled elsewhere :)
Answer by rh_galaxy · Feb 21, 2021 at 11:25 PM
You never assign walkSpeed which is a class variable another value after "walkSpeed = sprintSpeed;". So letting go of the KeyCode.LeftShift on the keyboard does nothing, sprintSpeed will stay on.
Your answer
Follow this Question
Related Questions
Object slide like ice without collision 1 Answer
How to use Configurable Joints and DragRigidBody Script with a door 0 Answers
Isometric movement 3 Answers
whay cant i move with this script???? 3 Answers