Input on player controller not responsive

So I am setting up a third person player controller and everything works well except the jumping. If my player is idle jumping works fine but when I am moving the input is not being read and the player can’t jump. I figure this is because of the if(direction.magnitude >= 0.1f) is being read and because its being read every frame. I am curious how to get around this. do I just set up a Jump() method inside that if and outside it making sure its read regardless? I have tried moving the code around but it does not work. Any help would be awesome, thanks.

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

public class PlayerMove_Attack : MonoBehaviour
{
    //player movement variables
    public CharacterController controller;
    public Transform cam;
    public float speed = 6f;
    public float gravity = -9.8f;
    public float jumpHeight = 8f;
    public float turnSmoothTime = 0f;
    float turnSmoothVeloctiy;
    Vector3 velocity;

    //player animation variables
    public Animator animator;
    bool isIdle, isRunning, isJumping, isBacking, isAttacking, canDoubleJump, canAttack;

    //attack cooldown so the player cant spam attack animation
    float attackCooldown;
  

    void Start()
    {
             isIdle = true;
             isRunning = false;
             isBacking = false;
             isJumping = false;
             isAttacking = false;
             canDoubleJump = false;
             canAttack = true;
    }

    void Update()
    {
        float horizontal = Input.GetAxisRaw("Horizontal");
        float vertical = Input.GetAxisRaw("Vertical");
        Vector3 direction = new Vector3(horizontal, 0, vertical).normalized;

        //velocity with gravity allows the player to fall
        //this resets velocity so it is not always adding up in the background
        if(controller.isGrounded)
        {
            velocity.y = -2f;
            isJumping = false;
            canDoubleJump = false;
        }
          

        if(direction.magnitude >= 0.1f)
        {
            isRunning = true;
            isIdle = false;

            //target angle takes the x and z axis to get a y angle of movement
            //this is how we move diagonally
            float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
            float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVeloctiy, turnSmoothTime);
            transform.rotation = Quaternion.Euler(0f, angle, 0f);

            Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
            controller.Move(moveDir * speed * Time.deltaTime);
        }
        else
        {
            isIdle = true;
            isRunning = false;
        }

        //check to see if the jump key is pressed (space bar in this case)
        if(controller.isGrounded)
        {
            if(Input.GetKeyDown(KeyCode.Space) && controller.isGrounded)
            {
                isRunning = false;
                isJumping = true;
                canDoubleJump = true;

                velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
            }
        }

        else if(canDoubleJump && Input.GetKeyDown(KeyCode.Space))
        {
            velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);

            isRunning = false;
            canDoubleJump = false;
        }

        if(Input.GetKeyDown(KeyCode.Mouse0) && canAttack == true)
        {
            isAttacking = true;
            isRunning = false;
            isIdle = false;
            isJumping = false;
            canAttack = false;

            controller.Move(Vector3.zero);

            StartCoroutine(WaitToAttack()); //this helps not spam the attack animation
        }

        if(animator.GetBool("isAttacking"))
            isAttacking = false;

        //this is our gravity
        //note needs to be after jump
        velocity.y += gravity * Time.deltaTime;
        controller.Move(velocity * Time.deltaTime);

        animator.SetBool("isRunning", isRunning);
        animator.SetBool("isBacking", isBacking);
        animator.SetBool("isJumping", isJumping);
        animator.SetBool("canDoubleJump", canDoubleJump);
        animator.SetBool("isAttacking", isAttacking);
        animator.SetBool("isIdle", isIdle);
    }

    private IEnumerator WaitToAttack()
    {
        yield return new WaitForSeconds(.6f);
        canAttack = true;
    }
}

Please use code tags: Using code tags properly

I recommend liberally sprinkling Debug.Log() statements through your code to display some values in realtime.

This should help you reason about the behavior you are seeing.

1 Like

It is reaching the first if and passing over everything in there

I have it working, its the GetKeyDown method. just needs to be GetKey

Try to restructure things to keep the if/then tests simpler, testing only one condition at a time. For instance in line 74 and line 76 you superfluously check isGrounded, which is just visual noise when you are trying to reason about the logic.

Print the values in real time, see what they are. If they are wrong, find out where they are coming from and so on up the trail of data. Follow the data.

1 Like