- Home /
The question is answered, right answer was accepted
Prevention of air movement
I can not figure out how to prevent air movement in my code for an fps, I have tried else statements throughout lines 40-59 but only get to the point to where after jumping the character completely freezes and does not retain forward velocity until they ground themselves again. I feel like this would be a simple fix but I have spent two hours just trying to fix this and can't really find anything online relating to my exact issue. If this has been addressed feel free to let me know, I have only been practicing for a week.
`
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController controller;
//Basic movement script-----------------------------------------------
public float walkSpeed = 12f;
public float gravity = -9.81f;
public float jumpHeight = 3f;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
Vector3 velocity;
bool isGrounded;
//Basic movement script-------------------------------------------
//Sprint script------------------------------------------------------------
PlayerMovement basicMovementScript;
public float speedBoost = 10f;
//Sprint script------------------------------------------------------------
void Start()
{
//Sprint script----------------------------------------------------------
basicMovementScript = GetComponent<PlayerMovement>();
//Sprint script-----------------------------------------------------------------
}
// Update is called once per frame
void Update()
{
//Basic movement script-----------------------------------------
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;
controller.Move(move * walkSpeed * Time.deltaTime);
if (Input.GetButtonDown("Jump") && isGrounded)
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
//Basic movement script------------------------------------------
//Sprint script-----------------------------------------------------------
if (Input.GetKeyDown(KeyCode.LeftShift))
basicMovementScript.walkSpeed += speedBoost;
else if (Input.GetKeyUp(KeyCode.LeftShift))
basicMovementScript.walkSpeed -= speedBoost;
//Sprint script-------------------------------------------------------------
}
}
`
I removed all basicMovement references in the script and took out the void start getComponent for any people reading this code now, I'm not sure exactly why I put those in there.
Answer by pauldarius98 · Feb 24, 2021 at 07:34 PM
What you could do would be to move x and z as private variables inside the class and update them only when the player is grounded. Doing it like this, when the player is no longer grounded the x and z values will represent the last value of the Horizontal and Vertical axis while the player was still grounded and the player will still keep the same direction but you won't be able to controll him in air. I will leave the code with the changes below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController controller;
//Basic movement script-----------------------------------------------
public float walkSpeed = 12f;
public float gravity = -9.81f;
public float jumpHeight = 3f;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
Vector3 velocity;
bool isGrounded;
float x = 0f;
float z = 0f;
//Basic movement script-------------------------------------------
//Sprint script------------------------------------------------------------
PlayerMovement basicMovementScript;
public float speedBoost = 10f;
//Sprint script------------------------------------------------------------
void Start()
{
//Sprint script----------------------------------------------------------
basicMovementScript = GetComponent<PlayerMovement>();
//Sprint script-----------------------------------------------------------------
}
// Update is called once per frame
void Update()
{
//Basic movement script-----------------------------------------
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if (isGrounded)
{
x = Input.GetAxis("Horizontal");
z = Input.GetAxis("Vertical");
if (velocity.y < 0)
{
velocity.y = -2f;
}
}
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * walkSpeed * Time.deltaTime);
if (Input.GetButtonDown("Jump") && isGrounded)
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
//Basic movement script------------------------------------------
//Sprint script-----------------------------------------------------------
if (Input.GetKeyDown(KeyCode.LeftShift))
basicMovementScript.walkSpeed += speedBoost;
else if (Input.GetKeyUp(KeyCode.LeftShift))
basicMovementScript.walkSpeed -= speedBoost;
//Sprint script-------------------------------------------------------------
}
}
Thank you very much, you made it simple and easy to understand and perfectly fixed my problem.
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Why is one line of code correct but the other gives Errors? (Solved) 2 Answers
IF Statement Being Ignored 3 Answers
Change size of an object up to a limit 2 Answers