Home > Net >  Input.GetKeyDown(KeyCode.Mouse0) not working as intended
Input.GetKeyDown(KeyCode.Mouse0) not working as intended

Time:03-11

I'm new to programming and i had this problem coming up, whenever i use Input.GetKeyDown(KeyCode.Mouse0) to attack with my character, it fires maybe 3 out of 10 times, i tried changing many variables and trying to put the code in diferent places but i couldn't find the fix to it

here's the code :

private void Update()
{
    dirX = Input.GetAxisRaw("Horizontal") ;

    rb.velocity = new Vector2(moveSpeed * dirX , rb.velocity.y) ;

    if(Input.GetButtonDown("Jump") && (IsGrounded()))
    {
        rb.velocity = new Vector3(rb.velocity.x,jumpForce,0);
    }
    
    UpdateAnimationState();

    if(attackTime <= 0)
    {
        if(Input.GetKeyDown(KeyCode.Mouse0))
        {
            anim.SetBool("attacking", true);
            Collider2D[] enemiesToDamage = Physics2D.OverlapCircleAll( attackLocation.position, attackRange, enemies );
            for (int i = 0; i < enemiesToDamage.Length; i  )
            {
                enemiesToDamage[i].GetComponent<Enemy_health>().TakeDamage(damage);
            }
        }

        attackTime = startTimeAttack;
    }   
    else
    {
        attackTime -= Time.deltaTime;
        anim.SetBool("attacking", false);
    }

    if(attackTime <= 0)
    {
        if( Input.GetKeyDown(KeyCode.Mouse0))
        {
            if(rb.velocity.y > .01f || rb.velocity.y < -.01f)
            {
                anim.SetBool("jumpattacking", true);
                Collider2D[] damage = Physics2D.OverlapCircleAll( attackLocation.position, attackRange, enemies );
                for (int i = 0; i < damage.Length; i  )
                {
                    Destroy( damage[i].gameObject );
                }
            }
        }

        attackTime = startTimeAttack;
    }   
    else
    {
        attackTime -= Time.deltaTime;
        anim.SetBool("jumpattacking", false);
    }
}

private void OnDrawGizmosSelected()
{
    Gizmos.color = Color.red;
    Gizmos.DrawWireSphere(attackLocation.position, attackRange);
}

CodePudding user response:

How should the jumpattacking case be ever reached?

  • Either the attackTime is higher than 0 or the first attacking case already kicks in and sets attackTime = startTimeAttack immediately - regardless of the input!

    → You rather want to start the cooldown only if you actually attacked!

  • And then still the jumpattacking could not be reached because the attacking case already consumes your input first and sets the timer.

  • Finally the way you are using the animator Bool parameters looks like you would be better using Tigger instead which is used for one time changing to a certain state and reset the trigger.

    I don't know how your animator is configured but it might be that since you immediately reset the bool parameters in the next frame it immediately transitions back to the idle state.

What you should probably do is rather merging both cases together like e.g.

private void Update()
{
    dirX = Input.GetAxisRaw("Horizontal") ;

    rb.velocity = new Vector2(moveSpeed * dirX , rb.velocity.y) ;

    if(Input.GetButtonDown("Jump") && IsGrounded())
    {
        rb.velocity = new Vector3(rb.velocity.x, jumpForce, 0);
    }
    
    UpdateAnimationState();

    if(attackTime <= 0)
    {
        if(Input.GetKeyDown(KeyCode.Mouse0))
        {
            // simply store this in a variable instead of implementing the same code twice
            // Use the absolute to simply check the magnitude regardless of the sign
            var isJumping = Mathf.Abs(rb.velocity.y) > 0.01f;

            // Use ternary for switching between the two bools according to the isJumping
            anim.SetBool(isJumping ? "jumpattacking" : "attacking", true);
            // disable the according other bool (?)
            // As said rather using Trigger would already solve this
            //anim.SetBool(isJumping ? "attacking" : "jumpattacking", false);
            var enemiesToDamage = Physics2D.OverlapCircleAll(attackLocation.position, attackRange, enemies);
            foreach (var enemy in enemiesToDamage)
            {
                // again decide for the resulting action according to isJumping
                if(isJumping)
                {
                    Destroy(enemy.gameObject);
                }
                else
                {
                    enemy.GetComponent<Enemy_health>().TakeDamage(damage);
                }
            }

            // You only want to do this once you actually consumed the User input
            attackTime = startTimeAttack;
        } 
    }   
    else
    {
        attackTime -= Time.deltaTime;

        // rather using Trigger parameters wold make these unnecessary
        anim.SetBool("attacking", false); 
        anim.SetBool("jumpattacking", false);
    }
}
  • Related