0
votes

I just recently asked another question and I got answered really quick so I hope its the same with this one. Anyway, I'm making this 2D platformer (super-meat-boy like) and I've added in this cool 'Dash' ability which is triggered when you press Shift. It would add an x-axis force and a little bit of some y-axis force to give it more of a jump-like feel. However, the AddForce function is so inconsistent in the game. Sometimes, the y-axis force is larger than the x-axis and sometimes the x-axis is increased by half(??). The only reason I can think of why this happens is because I have increased the gravity for proper unrealistic but good looking jumping and slightly more increased when the player dashes. Or could it be that when I dash at the peak of my jump, there's a stronger force as compared to in the beginning of the dash? I'm so confused.

Here is everything that in the update() function.

 void Update()
    {

        //Flipping and moving lightfeet
        if (Input.GetKey(KeyCode.A))
        {
            anim.SetFloat("Horizontal", 1);
            x = -1;
            scale.x = -4;
            rb.velocity = new Vector2(-speed, rb.velocity.y);
        }
        else if (Input.GetKey(KeyCode.D))
        {
            anim.SetFloat("Horizontal", 1);
            x = 1;
            scale.x = 4;
            rb.velocity = new Vector2(speed, rb.velocity.y);
        }
        else //no keys pressed
        {
            anim.SetFloat("Horizontal", 0);
            rb.velocity = new Vector2(0f, rb.velocity.y);
            anim.SetBool("Sprint", false); //even after sprinting and then stopping before to jump, sprint anim wont play

        }
        transform.localScale = scale;

        //Accumulating jump charge and increasing speed!
        if (Input.GetKey(KeyCode.Space) && rb.velocity.y == 0f) //only if space is held down and there is no vertical movement
        {
            jumpAccumulator += Time.deltaTime * 25f; //accumulates jump power over time
            if (jumpAccumulator >= maxJumpAccumulator) //maximum jump power
            {
                jumpAccumulator = maxJumpAccumulator; 
            }
            speed *= sprintSpeed; //increase speed when charging up
            if(speed >= maxSpeed) //maximum speed
            {
                speed = maxSpeed;
            }
        }


        //Ground detection
        groundHit = Physics2D.BoxCast(bcollider.bounds.center, bcollider.bounds.size, 0f, Vector2.down, 0.1f ,groundmask);
        mapHit = Physics2D.BoxCast(bcollider.bounds.center, bcollider.bounds.size, 0f, Vector2.down, 0.1f, mapMask);
        if (groundHit.collider != null || mapHit.collider != null) //When you on the ground!
        {

            anim.SetBool("Jumped", false);
            anim.SetBool("DoubleJumped", false);
            anim.SetBool("Dashed", false);
            anim.SetBool("Fall", false);
            canJump = true;
            canDoubleJump = true;
            canDash = false;
            rb.gravityScale = 15; //nomral gravity scale

            //animations for running or sprinting
            if (speed <= initialspeed)
            {
                anim.SetBool("Sprint", false);
            }
            else if (speed > initialspeed && rb.velocity.x > initialspeed && rb.velocity.y == 0 || speed > initialspeed && rb.velocity.x < -initialspeed)
            {
                anim.SetBool("Sprint", true);
            }

        }
        else if (groundHit.collider == null || mapHit.collider == null) //if LF is not on ground!
        {   
            canJump = false;
            anim.SetFloat("Horizontal", 0f);
        }

        //falling without jumping
        if (rb.velocity.y < 0 && anim.GetBool("Jumped") == false && anim.GetBool("DoubleJumped") == false && anim.GetBool("Dashed") == false)
        {
            anim.SetBool("Fall", true);
            anim.SetBool("Sprint", false);
            canDash = true;
        }


        JumpDash();
    }

    void JumpDash()
    {
        //Jump
        if (Input.GetKeyUp(KeyCode.Space) && canJump == true)
        {

            rb.velocity = Vector2.up * (jumpForce + jumpAccumulator);
            anim.SetBool("Jumped", true);
            anim.SetBool("DoubleJumped", false); //setting false to prevent bugs
            anim.SetBool("Sprint", false); //setting false to sprint here as well just to prevent bugs
            canDash = true;
            jumpAccumulator = 1;
        }
        //Double Jump
        if(Input.GetKeyDown(KeyCode.W) && canJump == false && canDoubleJump == true)
        {
            rb.velocity = Vector2.up * jumpForce;
            canDoubleJump = false;
            anim.SetBool("Jumped", false);
            anim.SetBool("DoubleJumped", true);
            anim.SetBool("Dashed", false); //disabling dash animation so it doesn't play when dashing then double jumping (because conditions for both can be true at the same time)
            anim.SetBool("Sprint", false); //setting false to sprint here as well just to prevent bugs
            anim.SetBool("Fall", false);

            doubleJumpFX.Play();
            DashFX.Stop();

        }
        //Dash
        if(Input.GetKeyDown(KeyCode.LeftShift) && canDash == true)
        {
            rb.AddForce(new Vector2(dashForce * x, dashUpForce), ForceMode2D.Impulse);
            rb.gravityScale += dashGravity; //increasing gravity for dashing
            canDash = false;
            anim.SetBool("Jumped", false);
            anim.SetBool("DoubleJumped", false);
            anim.SetBool("Dashed", true);
            anim.SetBool("Sprint", false); //setting false to sprint here as well just to prevent bugs

            doubleJumpFX.Stop();
            DashFX.Play();

        }
    }

    void OnCollisionEnter2D(Collision2D collision)
    {
        Debug.Log("Collider: " + collision.collider.name);

        if (collision.collider.name == "platform" || collision.collider.name == "mapColliders")
        {
            speed = initialspeed; //set speed to normal on hitting the ground (difference between this and raycast is this returns true for only one frame)
            anim.SetBool("Dashed", false); //setting false to this anim here again to prevent buggy animations
            anim.SetBool("Fall", false);

            doubleJumpFX.Stop();
            DashFX.Stop();
        }

        if (collision.collider.name == "Respawn area")
        {
            transform.position = new Vector2(-13f, 4f);
        }

    }
1
What type of force are you using?, Add your code, it will help people answer you - akaBase
here we go the 3 again ^^ try to attach the code you're using Serial, so it facilitates the debuging task - Lotan
I can't see where you reset the gravityScale also your code as shown makes me think you do both dash and movement velocity in the same frame when you want 1 or the other - akaBase
akaBase, take another look at the post. I've put all code in there (except for the variables that I've initialized in the beginning or else it will be much larger than necessary). Also what exactly do you mean by dash and movement velocity in the same frame? Also another clarification is that I've capped FPS to 40 to get rid of animation errors which also slightly reduced the extent of the inconsistency of the dash force. - Serial.A12
Ok so this is a very basic explaination but.. Update controls visual frames (and ok for input), FixedUpdate is for physics and both can have different FrameRates, as for what i mean by the same frame is like the tick of a clock and in that tick you are trying to do multiple things to the same thing - akaBase

1 Answers

1
votes

The inconstancy of AddForce is because you are adding onto the player's existing force. Have you tried cancelling out existing forces before calling AddForce? Just add the following line

rb.velocity = new Vector2 (0, 0);

in front of the AddForce function. Your dash function should look like this

    //Dash
    if(Input.GetKeyDown(KeyCode.LeftShift) && canDash == true)
    {
        rb.velocity = new Vector2 (0, 0);
        rb.AddForce(new Vector2(dashForce * x, dashUpForce), ForceMode2D.Impulse);
        rb.gravityScale += dashGravity; //increasing gravity for dashing
        canDash = false;
        anim.SetBool("Jumped", false);
        anim.SetBool("DoubleJumped", false);
        anim.SetBool("Dashed", true);
        anim.SetBool("Sprint", false); //setting false to sprint here as well just to prevent bugs

        doubleJumpFX.Stop();
        DashFX.Play();
    }