0
\$\begingroup\$

This is a rigidbody-based movement script. I notice that it doesn't let you jump while you're running. This problem persists whether you are using new Input System or not (I tested both ways).

Notably, the jump only doesn't work while running if you are running forward (straight forward, left-forward, or right-forward). If you try jumping while running backwards, left, or right, the jump will work. In case it matters, jump is Space and run is Shift.

What might be the reason for this happening?


    using System;
    using System.Collections.Generic;
    using UnityEngine;

    public class HumanoidLandController: MonoBehaviour {
        public Transform CameraFollow;

        [SerializeField] HumanoidLandInput _input;
        [SerializeField] CameraController _cameraController;
        [SerializeField] GameObject _playerObject; // Added for animations

        Vector3 _playerObjectOriginalLocalPosition = Vector3.zero; // Added for animations

        Rigidbody _rigidbody = null;
        CapsuleCollider _capsuleCollider = null;

        [SerializeField] Vector3 _playerMoveInput = Vector3.zero;

        Vector3 _playerLookInput = Vector3.zero;
        Vector3 _previousPlayerLookInput = Vector3.zero;
        [SerializeField] float _cameraPitch = 0.0 f;
        [SerializeField] float _playerLookInputLerpTime = 0.35 f;

        [Header("Movement")]
        [SerializeField] float _movementMultiplier = 30.0 f;
        [SerializeField] float _notGroundedMovementMultiplier = 1.25 f;
        [SerializeField] float _rotationSpeedMultiplier = 180.0 f;
        [SerializeField] float _pitchSpeedMultiplier = 180.0 f;
        [SerializeField] float _crouchSpeedMultiplier = 0.5 f;
        [SerializeField] float _runMultiplier = 2.5 f;

        [Header("Ground Check")]
        [SerializeField][Range(0.0 f, 1.8 f)] float _groundCheckRadiusMultiplier = 0.9 f;
        [SerializeField][Range(-0.95 f, 1.05 f)] float _groundCheckDistanceTolerance = 0.05 f;
        [SerializeField] float _playerCenterToGroundDistance = 0.0 f;
        public bool _playerIsGrounded {
                get;
                private set;
        } = true; // Modified for animations

        RaycastHit _groundCheckHit = new RaycastHit();

        [Header("Gravity")]
        [SerializeField] float _gravityFallCurrent = 0.0 f;
        [SerializeField] float _gravityFallMin = 0.0 f;
        [SerializeField] float _gravityFallIncrementTime = 0.05 f;
        [SerializeField] float _playerFallTimer = 0.0 f;
        [SerializeField] float _gravityGrounded = -1.0 f;
        [SerializeField] float _maxSlopeAngle = 47.5 f;



        [Header("Jumping")]
        [SerializeField] float _initialJumpForceMultiplier = 750.0 f;
        [SerializeField] float _continualJumpForceMultiplier = 0.1 f;
        [SerializeField] float _jumpTime = 0.175 f;
        [SerializeField] float _jumpTimeCounter = 0.0 f;
        [SerializeField] float _coyoteTime = 0.15 f;
        [SerializeField] float _coyoteTimeCounter = 0.0 f;
        [SerializeField] float _jumpBufferTime = 0.2 f;
        [SerializeField] float _jumpBufferTimeCounter = 0.0 f;
        [SerializeField] bool _jumpWasPressedLastFrame = false;
        public bool _playerIsJumping {
                get;
                private set;
        } = false; // Modified for animations



        private void Awake() {
                _rigidbody = GetComponent < Rigidbody > ();
                _capsuleCollider = GetComponent < CapsuleCollider > ();

                _maxAscendRayDistance = _maxStepHeight / Mathf.Cos(_maximumAngleOfApproachToAscend * Mathf.Deg2Rad);
                _maxDescendRayDistance = _maxStepHeight / Mathf.Cos(80.0 f * Mathf.Deg2Rad);

                _numberOfStepDetectRays = Mathf.RoundToInt(((_maxStepHeight * 100.0 f) * 0.5 f) + 1.0 f);
                _rayIncrementAmount = _maxStepHeight / _numberOfStepDetectRays;

                _playerFullHeight = _capsuleCollider.height;
                _playerCrouchedHeight = _playerFullHeight - _crouchAmount;

                _playerObjectOriginalLocalPosition = _playerObject.transform.localPosition; // Added for animations
        }

        private void FixedUpdate() {
                if (!_cameraController.UsingOrbitalCamera) {
                        _playerLookInput = GetLookInput();
                        PlayerLook();
                        PitchCamera();
                }

                _playerMoveInput = GetMoveInput();
                PlayerVariables();
                _playerIsGrounded = PlayerGroundCheck();

                _playerMoveInput = PlayerMove();
                _playerMoveInput = PlayerRun();

                PlayerInfoCapture();

                _playerMoveInput.y = PlayerFallGravity();
                _playerMoveInput.y = PlayerJump();

                Debug.DrawRay(_playerCenterPoint, _rigidbody.transform.TransformDirection(_playerMoveInput), Color.red, 0.5 f);
                _playerMoveInput *= _rigidbody.mass; // NOTE: For dev purposes.

                _rigidbody.AddRelativeForce(_playerMoveInput, ForceMode.Force);
                Debug.Log(_playerMoveInput.x);
        }

        private Vector3 GetLookInput() {
                _previousPlayerLookInput = _playerLookInput;
                _playerLookInput = new Vector3(_input.LookInput.x, (_input.InvertMouseY ? -_input.LookInput.y : _input.LookInput.y), 0.0 f);
                return Vector3.Lerp(_previousPlayerLookInput, _playerLookInput * Time.deltaTime, _playerLookInputLerpTime);
        }

        private void PlayerLook() {
                _rigidbody.rotation = Quaternion.Euler(0.0 f, _rigidbody.rotation.eulerAngles.y + (_playerLookInput.x * _rotationSpeedMultiplier), 0.0 f);
        }

        private void PitchCamera() {
                _cameraPitch += _playerLookInput.y * _pitchSpeedMultiplier;
                _cameraPitch = Mathf.Clamp(_cameraPitch, -89.9 f, 89.9 f);

                CameraFollow.rotation = Quaternion.Euler(_cameraPitch, CameraFollow.rotation.eulerAngles.y, CameraFollow.rotation.eulerAngles.z);
        }

        private Vector3 GetMoveInput() {
                return new Vector3(_input.MoveInput.x, 0.0 f, _input.MoveInput.y);
        }

        private void PlayerVariables() {
                _playerCenterPoint = _rigidbody.position + _capsuleCollider.center;
        }

        private Vector3 PlayerMove() {
                return ((_playerIsGrounded) ? (_playerMoveInput * _movementMultiplier) : (_playerMoveInput * _movementMultiplier * _notGroundedMovementMultiplier));
        }

        private bool PlayerGroundCheck() {
                float sphereCastRadius = _capsuleCollider.radius * _groundCheckRadiusMultiplier;
                Physics.SphereCast(_playerCenterPoint, sphereCastRadius, Vector3.down, out _groundCheckHit);
                _playerCenterToGroundDistance = _groundCheckHit.distance + sphereCastRadius;
                return ((_playerCenterToGroundDistance >= _capsuleCollider.bounds.extents.y - _groundCheckDistanceTolerance) &&
                        (_playerCenterToGroundDistance <= _capsuleCollider.bounds.extents.y + _groundCheckDistanceTolerance));
        }

        private Vector3 PlayerRun() {
                Vector3 calculatedPlayerRunSpeed = _playerMoveInput;
                if (_input.MoveIsPressed && _input.RunIsPressed && !_playerIsCrouching) {
                        calculatedPlayerRunSpeed *= _runMultiplier;
                }
                return calculatedPlayerRunSpeed;
        }

        private void PlayerInfoCapture() {
                if (_playerIsGrounded && _groundCheckHit.collider) {
                        _lastGroundCheckHit = _groundCheckHit;
                        _playerMoveInputAtLastGroundCheckHit = _playerMoveInput;
                }
        }

        private float PlayerFallGravity() {
                float gravity = _playerMoveInput.y;
                if (_playerIsGrounded || _playerIsAscendingStairs || _playerIsDescendingStairs) {
                        _gravityFallCurrent = _gravityFallMin; // Reset
                } else {
                        _playerFallTimer -= Time.fixedDeltaTime;
                        if (_playerFallTimer < 0.0 f) {
                                float gravityFallMax = _movementMultiplier * _runMultiplier * 5.0 f;
                                float gravityFallIncrementAmount = (gravityFallMax - _gravityFallMin) * 0.1 f;
                                if (_gravityFallCurrent < gravityFallMax) {
                                        _gravityFallCurrent += gravityFallIncrementAmount;
                                }
                                _playerFallTimer = _gravityFallIncrementTime;
                        }
                        gravity = -_gravityFallCurrent;
                }
                return gravity;
        }

        private float PlayerJump() {
                float calculatedJumpInput = _playerMoveInput.y;

                SetJumpTimeCounter();
                SetCoyoteTimeCounter();
                SetJumpBufferTimeCounter();

                if (_jumpBufferTimeCounter > 0.0 f && !_playerIsJumping && _coyoteTimeCounter > 0.0 f) {
                        //if (Vector3.Angle(_rigidbody.transform.up, _groundCheckHit.normal) < _maxSlopeAngle)
                        //{
                        calculatedJumpInput = _initialJumpForceMultiplier;
                        _playerIsJumping = true;
                        _jumpBufferTimeCounter = 0.0 f;
                        _coyoteTimeCounter = 0.0 f;
                        //}
                } else if (_input.JumpIsPressed && _playerIsJumping && !_playerIsGrounded && _jumpTimeCounter > 0.0 f) {
                        calculatedJumpInput = _initialJumpForceMultiplier * _continualJumpForceMultiplier;
                } else if (_playerIsJumping && _playerIsGrounded) {
                        _playerIsJumping = false;
                }
                return calculatedJumpInput;
        }

        private void SetJumpTimeCounter() {
                if (_playerIsJumping && !_playerIsGrounded) {
                        _jumpTimeCounter -= Time.fixedDeltaTime;
                } else {
                        _jumpTimeCounter = _jumpTime;
                }
        }

        private void SetCoyoteTimeCounter() {
                if (_playerIsGrounded) {
                        _coyoteTimeCounter = _coyoteTime;
                } else {
                        _coyoteTimeCounter -= Time.fixedDeltaTime;
                }
        }

        private void SetJumpBufferTimeCounter() {
                if (!_jumpWasPressedLastFrame && _input.JumpIsPressed) {
                        _jumpBufferTimeCounter = _jumpBufferTime;
                } else if (_jumpBufferTimeCounter > 0.0 f) {
                        _jumpBufferTimeCounter -= Time.fixedDeltaTime;
                }
                _jumpWasPressedLastFrame = _input.JumpIsPressed;
        }

    }
```
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Your code use a really bad structure to create movement system, well explained at youtube.com/watch?v=kV06GiJgFhc&ab_channel=iHeartGameDev . Not only is debugging the code difficult, but changing the code in the future to add another movement may also be difficult. It is recommended to use state-based system for movement script to make it easier to manage (one of the simple way to do it would be to use finite state machine). I would highly recommend to rewrite your movement script. \$\endgroup\$
    – aaa
    Jan 24 at 7:15

1 Answer 1

2
\$\begingroup\$

The code was irrelevant; it's just keyboard ghosting that causes it. Shift+W+Space doesn't work with certain keyboards

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .