Hi, new to Unity, new to coding here. I’m sure I will leave out pertinent information.
Problem: I don’t want the player to be able to change x or z velocities while jumping or falling. Rather, I want the player to continue with the last x/z velocity inputs while isGrounded
. I am using a Character Controller for movement.
Attempted solution: I thought maybe I could update a new Vector3 fallingMove
from Vector3 move
while player isGrounded
. While player !isGrounded
, call controller.Move()
using fallingMove
as parameter instead of move
.
Outcome: x and z velocities are 0 while falling/jumping. In essence, player falls straight down.
Thank you in advance for any help or advice. My movement script is below. My attempted solution is inside PlayerMove()
.
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerMovement : MonoBehaviour
{
public InputMaster controls;
public CharacterController controller;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
public float groundSpeed = 12;
public float gravity = -9.81f;
public float jumpHeight = 3;
bool cameraGrabbed;
bool playerGrabbed;
bool isAutoRunning;
bool isGrounded;
Vector2 cursorPosition;
Vector2 movementInput;
Vector3 fallingVelocity;
Vector3 move;
Vector3 fallingMove;
void Awake() {
controls = new InputMaster();
// started called on button press
controls.Player.GrabCamera.started += _ => GrabCamera();
controls.Player.GrabPlayer.started += _ => GrabPlayer();
// performed called on button release
controls.Player.GrabCamera.performed += _ => ReleaseCamera();
controls.Player.GrabPlayer.performed += _ => ReleasePlayer();
controls.Player.Jump.started += _ => Jump();
controls.Player.AutoRun.started += _ => AutoRun();
controls.Player.AutoRunCancel.started += _ => AutoRunCancel();
}
void Start() {
//Cursor.lockState = CursorLockMode.Confined;
}
void GrabCamera() {
cameraGrabbed = true;
if (playerGrabbed) {
AutoRunCancel();
}
}
void GrabPlayer() {
playerGrabbed = true;
if (cameraGrabbed) {
AutoRunCancel();
}
}
void ReleaseCamera() {
cameraGrabbed = false;
}
void ReleasePlayer() {
playerGrabbed = false;
}
// Update is called once per frame
void Update() {
PlayerMove();
FreeFall();
}
void AutoRun() {
if (isAutoRunning == false) {
isAutoRunning = true;
}
else {
isAutoRunning = false;
}
}
void AutoRunCancel() {
isAutoRunning = false;
}
void PlayerMove() {
Vector2 movementInput = controls.Player.KeyboardMovement.ReadValue<Vector2>();
if (cameraGrabbed == true && playerGrabbed == true) {
movementInput.y = 1;
}
if (isAutoRunning == true) {
movementInput.y = 1;
}
movementInput = movementInput.normalized;
float moveX = movementInput.x;
float moveZ = movementInput.y;
if (isGrounded) {
Vector3 move = transform.right * moveX + transform.forward * moveZ;
Vector3 fallingMove = move;
controller.Move(move * groundSpeed * Time.deltaTime);
}
else {
controller.Move(fallingMove * groundSpeed * Time.deltaTime);
}
}
void Jump() {
if (isGrounded) {
fallingVelocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
}
void FreeFall() {
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if (isGrounded && fallingVelocity.y < 0) {
fallingVelocity.y = -2f;
}
fallingVelocity.y += gravity * Time.deltaTime;
controller.Move(fallingVelocity * Time.deltaTime);
}
void OnEnable() {
controls.Enable();
}
void onDisable() {
controls.Disable();
}
}