Search Unity

Help with Rigibody 2d Add force

Discussion in '2D' started by fosmark13, Feb 24, 2015.

  1. fosmark13

    fosmark13

    Joined:
    Feb 16, 2015
    Posts:
    91
    hi there, i´m doing a game where the character detects an edge and stop there and if the player press the Up button then he goes up adding a force in X and Y axis, so i write the code for each situation except that when the player touches the edge collider and presses the up button the rigibody only applies force to the Y axis and not the X, heres my script:

    if (touchingEdge) {

    //When the player touches the edge collider

    rBody2D.gravityScale = 0;

    rigidbody2D.velocity = newVector2 (0, 0);

    anim.SetBool ("touchingEdge", true);


    //When he is touching the edge and any of the buttons is pressed to get him down


    if (Input.GetButton ("Horizontal") || Input.GetButton ("Jump") || (Input.GetAxis("Vertical")< 0)) {


    doubleJumpForce = 0;

    jumpForce = 0;

    rBody2D.gravityScale = 1;

    rigidbody2D.AddForce (newVector2 (0, jumpForce));

    rigidbody2D.velocity = newVector2 (rigidbody2D.velocity.x, rigidbody2D.velocity.y);


    touchingEdge = false;

    anim.SetBool ("touchingEdge", touchingEdge);




    }

    //When he is touching the edge and the Up Button is pressed and he goes up

    if ((Input.GetAxis("Vertical") > 0)){



    rigidbody2D.AddForce (newVector2 (ledgeForceX, ledgeForceY));

    movingUp =true;

    anim.SetBool("movingUp",movingUp);



    }

    //When goes up or down


    } else if (grounded || !grounded){


    movingUp= false;

    anim.SetBool("movingUp",movingUp);

    touchingEdge =false;

    jumpForce=400f;

    doubleJumpForce=30f;

    rigidbody2D.velocity = newVector2 (rigidbody2D.velocity.x, rigidbody2D.velocity.y);


    }

    Any idea why this happens?? Thanks
     
  2. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    What is this supposed to do? It only resets the velocity to the same value it alread is...

    Code (CSharp):
    1. rigidbody2D.velocity = new Vector2 (rigidbody2D.velocity.x, rigidbody2D.velocity.y);
    Also, since you're setting:
    Code (CSharp):
    1. rigidbody2D.velocity = newVector2 (0, 0);
    earlier on, shouldn't the velocity be zero when you reach the statement above?
     
  3. fosmark13

    fosmark13

    Joined:
    Feb 16, 2015
    Posts:
    91
    yes when te player reach the "edge collider" it resets the velocity of both to zero, because when the player touches the "edge collider" he stops jus there, but when the button up is pressed it suppose to add force on both axis the X and the Y whit this:

    if ((Input.GetAxis("Vertical") > 0)){



    rigidbody2D.AddForce (newVector2 (ledgeForceX, ledgeForceY));


    }

    so what is wrong? like i wrote before it only adds force to the Y axis but not the X
     
  4. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    Is the ledgeForceX directed in the correct direction? So that it doesn't try to move into the collider and therefore gets its velocity reset to zero.
     
  5. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
  6. fosmark13

    fosmark13

    Joined:
    Feb 16, 2015
    Posts:
    91
    i have them like

    Code (CSharp):
    1. public float ledgeForceX = 280f;
    2.     public float ledgeForceY = 350f;
     
  7. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    OK, so that would set your object to move upwards and to the right. There is nothing to the right that your object could hit, so that the it gets blocked?
     
  8. fosmark13

    fosmark13

    Joined:
    Feb 16, 2015
    Posts:
    91
    There's absolutely nothing in its way and the ledgeForceY works fine Only the ledgeForceX doesn't
     
  9. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    That's why I wondered if there was something in its path that blocked it. Strange, from what I can see from your code, it ought to work! Have you tried setting the velocity directly, instead of using AddForce?
     
  10. fosmark13

    fosmark13

    Joined:
    Feb 16, 2015
    Posts:
    91
    What i Did is when the edgecheck touches the edge collider the velocity resets to zero so what i should do is define that when the input button "horizontal" is pressed set a different velocity? Any code example of how to do that?
     
  11. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    You're already doing something similar in other places (although the code there is a bit strange), try something like this.
    Code (CSharp):
    1. rigidbody2D.velocity = Vector2.one;
    That should give your object a slight speed towards up and the right. You might want to multiply Vector2.One with some speed factor for it to move a little bit faster...
     
  12. fosmark13

    fosmark13

    Joined:
    Feb 16, 2015
    Posts:
    91
    ok i tried it but it only applies force to the Y axis not to the X
     
  13. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    Damn, that's really weird. Could it be some other code that is interfering?

    BTW: I noticed that in all the other if:s you set touchingEdge to false, but not in the one that is problematic. Is it supposed to be that way?
     
  14. fosmark13

    fosmark13

    Joined:
    Feb 16, 2015
    Posts:
    91
    you are right i didn´t have the touchingEdge back to false but i think that you where right before... now i checked what you said about something blocking its path and actually there is something... the thing is that the player is climbing a platform and it does the force but like the platform is there and he is hanging from it, it is blocking the player and the X force just doesn´t happen, if i move the collider then it actually happens.

    So what can i do there, i put an example image of what is happening thanks a lot
     

    Attached Files:

  15. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    Ah, yes, then it certainly is the edge collider that gets in the way. So, the question is; once the player begins climbing up the edge, is it possible to interrupt the climb or change direction? Or does the player push up and then he climbs up all the way without any possible interaction?
     
  16. fosmark13

    fosmark13

    Joined:
    Feb 16, 2015
    Posts:
    91
    When Is pushed up and can not be interrupted, once he pushes the button he climbs up all the way with no other posible interaction
     
  17. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    Then it might be easiest to do it using a coroutine. Something like this:
    Code (CSharp):
    1.     IEnumerator ClearEdge()
    2.     {
    3.         rigidbody2D.AddForce(new Vector2(0, ledgeForceY));
    4.         // Wait for however long it takes for the player to get above the edge
    5.         yield return new WaitForSeconds(1f);
    6.         rigidbody2D.AddForce(new Vector2(ledgeForceX, 0));
    7.     }
    8.  
    You call this from your code with:
    Code (CSharp):
    1.     StartCoroutine(ClearEdge));
    You probably want to lock out any possibility of other movement while the coroutine is running.
     
    fosmark13 likes this.
  18. fosmark13

    fosmark13

    Joined:
    Feb 16, 2015
    Posts:
    91
    woooo!!! PGJ that worked just great!!!! now it does the movement right, i just have to calculate the correct time to implement the next addforce but it is great!!! thank you man you are vey talented!! and that thing you said before... how i lock any possibility of other movement?
     
  19. PGJ

    PGJ

    Joined:
    Jan 21, 2014
    Posts:
    899
    The easiest way to lock out movement, is probably to use a bool to indicate that no user input is allowed. Set it at the start of the coroutine and reset it at the end of the coroutine. Something like this:

    Code (CSharp):
    1.  
    2. bool disableMovement = false;
    3.  
    4. IEnumerator ClearEdge()
    5. {
    6.     disableMovement = true;
    7.     rigidbody2D.AddForce(new Vector2(0, ledgeForceY));
    8.     // Wait for however long it takes for the player to get above the edge
    9.     yield return new WaitForSeconds(1f);
    10.     disableMovement = false;
    11.     rigidbody2D.AddForce(new Vector2(ledgeForceX, 0));
    12. }
    13.  
    Then you just have to check disableMovement in your movement code.