Addforce lasting 1 frame

Edit:
(My rigid body settings are as follows -
mass = 1
drag = 0
angular drag = 0.05
gravity = yes
is kinematic = no
interpolate = none
collision detection = discrete
only constraints on all rotations)

Hello,

I am trying to make a directional air dodge mechanic (like in smash bros) but the force I am adding is only lasting for one frame. This is only happening with my left and right (A and D) inputs. Here is the specific part of the script.

else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.D) && airdodgeamount < 1 && djumping == false)
        {
            NotShielding = false;
            gravity = 0;
            anim.SetInteger("AnimParameter", 9);
            speed = 30f;
            calculatedforce = speed * (50 * mainrb.mass);
            mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
            coroutine = WaitForAirdodge(0.167f);
            StartCoroutine(coroutine);
            gravity = 8;
            airdodgeamount++;
        }
        else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.A) && airdodgeamount < 1 && djumping == false)
        {
            NotShielding = false;
            gravity = 0;
            anim.SetInteger("AnimParameter", 9);
            speed = -30f;
            calculatedforce = speed * (50 * mainrb.mass);
            mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
            coroutine = WaitForAirdodge(0.167f);
            StartCoroutine(coroutine);
            gravity = 8;
            airdodgeamount++;
        }
        else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.W) && airdodgeamount < 1 && djumping == false)
        {
            NotShielding = false;
            gravity = 0;
            anim.SetInteger("AnimParameter", 9);
            speed = 0.1f;
            calculatedforce = speed * (50 * mainrb.mass) - mainrb.velocity.y;
            mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
            coroutine = WaitForAirdodge(0.167f);
            StartCoroutine(coroutine);
            gravity = 8;
            airdodgeamount++;
        }
        else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.S) && airdodgeamount < 1 && djumping == false)
        {
            NotShielding = false;
            gravity = 0;
            anim.SetInteger("AnimParameter", 9);
            speed = -0.05f;
            calculatedforce = speed * (50 * mainrb.mass) - mainrb.velocity.y;
            mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
            coroutine = WaitForAirdodge(0.167f);
            StartCoroutine(coroutine);
            gravity = 8;
            airdodgeamount++;
        }
        else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && airdodgeamount < 1 && djumping == false)
        {
            gravity = 0;
            NotShielding = false;
            anim.SetInteger("AnimParameter", 9);
            calculatedforce = 0 - mainrb.velocity.y;
            mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
            coroutine = WaitForAirdodge(0.167f);
            StartCoroutine(coroutine);
        }

Here is my entire script fixed update script as i have no idea where the problem could be.

void FixedUpdate()
    {
        Physics.gravity = new Vector3(0, -gravity, 0);
        
        if (touching == true && jumping == false)
        {
            anim.SetBool("IsAirborn", false);
        }
        else if (touching == false)
        {
            anim.SetBool("IsAirborn", true);
        }

        if (anim.GetBool("IsAirborn") == false && Input.GetKeyDown(KeyCode.I) && NotShielding == true)
        {
            NotShielding = false;
            anim.SetInteger("AnimParameter", 6);
            shield.SetActive(true);
            coroutine = WaitForShield(0.167f);
            StartCoroutine(coroutine);
        }
        else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.D) && airdodgeamount < 1 && djumping == false)
        {
            NotShielding = false;
            gravity = 0;
            anim.SetInteger("AnimParameter", 9);
            speed = 30f;
            calculatedforce = speed * (50 * mainrb.mass);
            mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
            coroutine = WaitForAirdodge(0.167f);
            StartCoroutine(coroutine);
            gravity = 8;
            airdodgeamount++;
        }
        else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.A) && airdodgeamount < 1 && djumping == false)
        {
            NotShielding = false;
            gravity = 0;
            anim.SetInteger("AnimParameter", 9);
            speed = -30f;
            calculatedforce = speed * (50 * mainrb.mass);
            mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
            coroutine = WaitForAirdodge(0.167f);
            StartCoroutine(coroutine);
            gravity = 8;
            airdodgeamount++;
        }
        else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.W) && airdodgeamount < 1 && djumping == false)
        {
            NotShielding = false;
            gravity = 0;
            anim.SetInteger("AnimParameter", 9);
            speed = 0.1f;
            calculatedforce = speed * (50 * mainrb.mass) - mainrb.velocity.y;
            mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
            coroutine = WaitForAirdodge(0.167f);
            StartCoroutine(coroutine);
            gravity = 8;
            airdodgeamount++;
        }
        else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && Input.GetKey(KeyCode.S) && airdodgeamount < 1 && djumping == false)
        {
            NotShielding = false;
            gravity = 0;
            anim.SetInteger("AnimParameter", 9);
            speed = -0.05f;
            calculatedforce = speed * (50 * mainrb.mass) - mainrb.velocity.y;
            mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
            coroutine = WaitForAirdodge(0.167f);
            StartCoroutine(coroutine);
            gravity = 8;
            airdodgeamount++;
        }
        else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.I) && NotShielding == true && airdodgeamount < 1 && djumping == false)
        {
            gravity = 0;
            NotShielding = false;
            anim.SetInteger("AnimParameter", 9);
            calculatedforce = 0 - mainrb.velocity.y;
            mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
            coroutine = WaitForAirdodge(0.167f);
            StartCoroutine(coroutine);
        }
        else if (anim.GetBool("IsAirborn") == false && Input.GetKeyDown(KeyCode.W) && NotShielding == true)
        {
            jumping = true;
            anim.SetBool("IsAirborn", true);
            anim.SetInteger("AnimParameter", 3);
            coroutine = WaitForJump(0.3f);
            StartCoroutine(coroutine);
        }
        else if (anim.GetBool("IsAirborn") == true && Input.GetKeyDown(KeyCode.W) && doublejumpamount < 1f && NotShielding == true)
        {
            djumping = true;
            anim.SetInteger("AnimParameter", 5);
            anim.SetBool("IsAirborn", true);
            coroutine = WaitForDJump(0.2f);
            StartCoroutine(coroutine);
            doublejumpamount++;
        }
        else if (anim.GetBool("IsAirborn") == true && Input.GetKey(KeyCode.S) && NotShielding == true)
        {
            gravity = 15;
        }
        else if (Input.GetKey(KeyCode.A) && Input.GetKey(KeyCode.LeftShift) && anim.GetBool("IsAirborn") == false && NotShielding == true)
        {
            anim.SetInteger("AnimParameter", 2);
            transform.eulerAngles = new Vector3(0, 270, 0);
            speed = -1;
            calculatedforce = speed * (50 * mainrb.mass);
            mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
        }
        else if (Input.GetKey(KeyCode.D) && Input.GetKey(KeyCode.LeftShift) && anim.GetBool("IsAirborn") == false && NotShielding == true)
        {
            anim.SetInteger("AnimParameter", 2);
            transform.eulerAngles = new Vector3(0, 90, 0);
            speed = 1;
            calculatedforce = speed * (50 * mainrb.mass);
            mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
        }
        else if (Input.GetKeyDown(KeyCode.A) && anim.GetBool("IsAirborn") == false && NotShielding == true)
        {
            anim.SetInteger("AnimParameter", 1);
            transform.eulerAngles = new Vector3(0, 270, 0);
            speed = -10;
            calculatedforce = speed * (50 * mainrb.mass);
            mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
        }
        else if (Input.GetKeyDown(KeyCode.D) && anim.GetBool("IsAirborn") == false && NotShielding == true)
        {
            anim.SetInteger("AnimParameter", 1);
            transform.eulerAngles = new Vector3(0, 90, 0);
            speed = 10;
            calculatedforce = speed * (50 * mainrb.mass);
            mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
        }
        else if (Input.GetKey(KeyCode.A) && anim.GetBool("IsAirborn") == false && NotShielding == true)
        {
            anim.SetInteger("AnimParameter", 1);
            transform.eulerAngles = new Vector3(0, 270, 0);
            speed = -2;
            calculatedforce = speed * (50 * mainrb.mass);
            mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
        }
        else if (Input.GetKey(KeyCode.D) && anim.GetBool("IsAirborn") == false && NotShielding == true)
        {
            anim.SetInteger("AnimParameter", 1);
            transform.eulerAngles = new Vector3(0, 90, 0);
            speed = 2;
            calculatedforce = speed * (50 * mainrb.mass);
            mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
        }
        else if (Input.GetKey(KeyCode.A) && anim.GetBool("IsAirborn") == true && NotShielding == true)
        {
            speed = -2;
            calculatedforce = speed * (50 * mainrb.mass);
            mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
        }
        else if (Input.GetKey(KeyCode.D) && anim.GetBool("IsAirborn") == true && NotShielding == true)
        {
            speed = 2;
            calculatedforce = speed * (50 * mainrb.mass);
            mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
        }
        else if (Input.GetKey(KeyCode.S) && NotShielding == false)
        {
            anim.SetInteger("AnimParameter", 8);
            shield.SetActive(false);
            coroutine = WaitForSpotdodge(0.2f);
            StartCoroutine(coroutine);
        }
        else if (NotShielding == true)
        {
            anim.SetInteger("AnimParameter", 0);
            gravity = 8;
        }
        else
        {
            
        }

        if (wanttojump == true)
        {
            if (Input.GetKey(KeyCode.W))
            {
                jumping = false;
                jumpspeed = 1f;
                calculatedforce = jumpspeed * (5 * mainrb.mass) - (mainrb.velocity.y * 1);
                mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
            }
            else if (!Input.GetKey(KeyCode.W))
            {
                jumping = false;
                jumpspeed = 0.7f;
                calculatedforce = jumpspeed * (5 * mainrb.mass) - (mainrb.velocity.y * 1);
                mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
            }

            anim.SetInteger("AnimParameter", 4);
            anim.SetBool("IsAirborn", true);
            wanttojump = false;
        }
        if (resetgravity == true)
        {
            gravity = 8;
            resetgravity = false;
        }
        if (wanttodjump == true)
        {
            gravity = 0;
            jumpspeed = 1;
            calculatedforce = jumpspeed * (5 * mainrb.mass) - (mainrb.velocity.y * 1);
            mainrb.AddForce(new Vector3(0, calculatedforce, 0), ForceMode.Impulse);
            anim.SetInteger("AnimParameter", 4);
            wanttodjump = false;
            coroutine = GravityDelay(0.1f);
            StartCoroutine(coroutine);
            djumping = false;
        }

        touching = false;
    }

Thank you in advance.

Hello @DoctorChar,

I’m sorry i’m not going to spot your specific issue but if an action only last 1 step it’s usually because you overwrite it the next step (or within the same step).

That being said, in my humble opinion, you need to clean your code first cause it is hardly readable, for examples:

  • Segment your code more : handle NotShielding == false specific treatment appart from the rest so you don’t write it 15 times in the if statements
  • Factorise your code and give meaning to your code:

for example lines 105 to 164 could be rewrote like below and read must clearer:

else if (NotShielding == true &&
            (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.A) || 
             Input.GetKeyDown(KeyCode.D) ||Input.GetKeyDown(KeyCode.A)))
{
   handleADMovement();
}
         
void handleADMovement()
{
    float initialSpeedBoost = 5f;
        
    // Handle specific Airborn movement
    if (anim.GetBool("IsAirborn"))
    {
        // Invert Speed depending on A/D key
        speed = 2 * (Input.GetKey(KeyCode.A) || Input.GetKeyDown(KeyCode.A)? -1:1);
    }
    else
    {
        // Now everything under is not Airborn related

        // D Control - to be described
        if (Input.GetKey(KeyCode.D) || Input.GetKeyDown(KeyCode.D))
        {
            transform.eulerAngles = new Vector3(0, 90, 0);
            // Add an initial speed boost in case key just pressed
            speed = 2 * (Input.GetKeyDown(KeyCode.D) ? initialSpeedBoost : 1f); 
         }

         // A Control - to be described
         // Takes precedence over D Key (cf else if statements)
         // So if A & D key are pressed simultaneously, only A key will be taken into account
         if (Input.GetKey(KeyCode.A) || Input.GetKeyDown(KeyCode.A))
         {
                transform.eulerAngles = new Vector3(0, 270, 0);
                speed = -2 * (Input.GetKeyDown(KeyCode.A) ? initialSpeedBoost : 1f);
         }

         // Handle Grounded animation and Shift control
         // Shift Key control - Set anim 2 and reduce speed to 1/-1
         if (Input.GetKey(KeyCode.LeftShift))
         {
             anim.SetInteger("AnimParameter", 2);
             speed = speed / speed;
         }
         // Set anim 1 - Prob Grounded animation
         else
         {
             anim.SetInteger("AnimParameter", 1);
         }
    }
        
    // Apply force to rigidbody
    calculatedforce = speed * (50 * mainrb.mass);
    mainrb.AddForce(new Vector3(calculatedforce, 0, 0));
}