Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Problems with rigidbody physics after going from 3d physics to 2d

Discussion in 'Physics' started by Rostam24, Aug 24, 2015.

  1. Rostam24

    Rostam24

    Joined:
    Mar 5, 2014
    Posts:
    119
    So I'm changing the physics of my game from 3D to 2D... Most of the changes are going ok, except for some of the rigidbody physics. Specifically: AddForce, Velocity, and MovePosition. To be clear, these things worked just fine before.

    AddForce:
    Using AddForce with ForceMode2D.Impulse does nothing, and using Force only works with an insanely high amount of force - and even then it just seems to teleports. I tried setting velocity directly, but nothing would happen. I noticed that the button that calls jump is in Update, so I decided to test if that causes the issues. So I used a simple press space to jump script in FixedUpdate. The result: with an insanely high amount of Force, it would teleport in both Impulse and Force modes... So basically, AddForce is either doing nothing, or causing a teleport, and therefore I can only assume that something is wrong (but then again, I have 0 experience with 2d physics).

    MovePosition:
    This one makes a bit more sense: I can set it just fine from FixedUpdate. However, if I want to set it anytime the player taps the screen, then nothing happens (this used to work just fine with 3D physics). This is confusing to me, so I tried a coroutine with WaitForFixedUpdate - that didn't work either. So for now, I'm setting the transform.position directly for some of the player actions - but I'd prefer to use rigidbody.MovePosition.


    So I've been running tests for a couple of hours now, and these are the most important findings. Stuff like mass, drag, etc. doesn't solve the problem (they appear to behave like normal).
    I'm really confused about all of this. Any guesses as to what might be the problem? Or ideas for running tests that might help narrow it down?

    I really appreciate your help! Thank you :)
     
  2. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    I'm passing from 3D to 2D. I'm not an exert. In my minimum personal experience making experiments: It looks like the 2D physics is different from the 3D physics engine. So the setups and values are different. In my experience i set up each component separately first. Not having distrust based on fixed or preconceived ideas.
     
    Rostam24 likes this.
  3. Rostam24

    Rostam24

    Joined:
    Mar 5, 2014
    Posts:
    119
    Hi Alan, thank you for your advice!

    Since my last post, I've experimented from the ground up: first an empty level, then a new gameobject, and that way I slowly worked my way up. I discovered that most problems are related to a Rigidbody2d.MovePosition that I call every fixedupdate. Apparently, this nullifies any AddForce attempts that I make elsewhere...

    Guess I'll be using something else than MovePosition to solve this issue!

    So that solves most of the problems, I have since run into a new one though... If you have the time, I'd appreciate your input.
    I put together a standing punching bag for my game, using a box for the base, a box for a pole, and a capsule for the actual bag. Now when I was using 3d physics, I would use a configurable joint to make sure these 3 components move together in a realistic way.
    Any ideas on how to do this using 2d physics?
    The pole is attached to the base, and should be able to move within a certain angle. So I guess hinge joint makes most sense for this one.
    The bag is attached to the pole, and should move just a little bit for realism (although that's not necessary). I thought the spring joint would be the best choice here.
    Unfortunately, neither of these joints have a realistic way for the bag to return to an upright position (it's either too unreliable or too 'bouncy'). Suggestions? Otherwise, guess I'll write a custom script, but I'd prefer to use Unity components where possible :)
     
  4. Rostam24

    Rostam24

    Joined:
    Mar 5, 2014
    Posts:
    119
    Oh man, another issue I could use some help with... Sorry guys :-/
    So I used to use rigidbody.MovePosition for most movement, and then AddForce for other stuff like taking damage or jumping.

    Now that I can't use MovePosition anymore, how should I move my characters? Using transform.translate jitters, and setting velocity directly blocks AddForce. Any advice?
    If not, I guess I'll have to use AddForce for regular movement as well, but I'd rather not... It just seems wrong to use it for a walking animation :-/
     
  5. Rostam24

    Rostam24

    Joined:
    Mar 5, 2014
    Posts:
    119
    Man, still no progress with the character movement :-/

    I can't move the character using the physics engine (like rigidbody.moveposition or setting the velocity) in one place in my code without it blocking AddForce methods everywhere else.

    And I can't move the character directly (for instance, transform.position or translate) without the character jittering during movement. I think this option still has potential though, any suggestions on how to remove the jitter? Disabling the camera does not help, and placing the code in Update, FixedUpdate or LateUpdate does change the amount of jitter, but never removes it entirely...
     
  6. vakabaka

    vakabaka

    Joined:
    Jul 21, 2014
    Posts:
    1,153
    to remove jitter, try set your rigidbody2d to interpolate (in inspector). Or maybe you have 30 fps lock.

    for left or right move change moveSpeed.
    rigidbody2D.velocity = new Vector2 (moveSpeed, rigidbody2D.velocity.y);

    for jump
    rigidbody2D.velocity = new Vector2 (rigidbody2D.velocity.x, jumpSpeed);

    or you can use AddForce too, but dont use something like new Vector2 (0, jump); with zero you will stop moving on x.
    Use: new Vector2 (rigidbody2D.velocity.x, jump);
     
    Rostam24 likes this.
  7. Rostam24

    Rostam24

    Joined:
    Mar 5, 2014
    Posts:
    119
    Thank you very much for helping out.

    I had already set the rigidbody to interpolate, but that didn't affect the jitter when using transform to move.

    I tried changing velocity the way you wrote it down, which is very similar to how I had it in 3D physics. However, since I moved to 2D physics, there is a big issue with this: setting velocity means anything I do with AddForce gets ignored. The same applies to MovePosition, it causes anything I do with AddForce (like jumping) to be ignored...

    Last night I threw my movement script out, and started over using only AddForce. It's a bit strange writing the code in terms of acceleration instead of speed, but I got it to work. Lots of issues to deal with: like maxspeed, decreasing inertia, and also some clashes with other scripts I had running (that give temporary speed boost forward), but right now it seems to work without issues.
    I still don't think it's ideal, as this means everything I do from now on has to be done using AddForce, so I can't use MovePosition or Velocity anymore like I did before... But still, I guess I should be happy that it works now :)

    Thanks again for your help, guys! I really appreciate it.
     
  8. vakabaka

    vakabaka

    Joined:
    Jul 21, 2014
    Posts:
    1,153
    this was my moving script in game (part of it) :)
    Code (CSharp):
    1. void FixedUpdate ()
    2.     {
    3.         onGround = Physics2D.OverlapCircle(groundCheck.position, groundRadius, whatIsGround);
    4.  
    5.         if (!moveLeft && !moveRight) {
    6.             rigidbody2D.velocity = new Vector2 (0f, rigidbody2D.velocity.y);
    7.             anim.SetBool ("Run", false);
    8.         }
    9.  
    10.         if (moveLeft && !anim.GetBool ("Hitted") && !anim.GetBool ("Fire")) {
    11.             rigidbody2D.velocity = new Vector2 (-moveSpeed, rigidbody2D.velocity.y);
    12.             anim.SetBool ("Run", true);
    13.             if (isFacingRight)
    14.             Flip();
    15.         }
    16.        
    17.         if (moveRight && !anim.GetBool ("Hitted") && !anim.GetBool ("Fire")) {
    18.             rigidbody2D.velocity = new Vector2 (moveSpeed, rigidbody2D.velocity.y);
    19.             anim.SetBool ("Run", true);
    20.             if (!isFacingRight)
    21.                 Flip();
    22.         }
    23.         if (doJump && onGround && !anim.GetBool ("Hitted") && !anim.GetBool ("Fire")) {
    24.             rigidbody2D.velocity = new Vector2 (rigidbody2D.velocity.x, jumpForce);
    25.             AudioSource.PlayClipAtPoint (VampJump, gameObject.transform.position);
    26.             doJump = false;
    27.             onGround = false;
    28.             isJumping = true;
    29.             anim.SetBool ("Jump", true);
    30.         }
    31.  
    32.     }
     
  9. Rostam24

    Rostam24

    Joined:
    Mar 5, 2014
    Posts:
    119
    And what if you change the velocity for jump to right and up (instead of just up)? When I tried it with your code, the character would only go up... It didn't even matter where I would place which piece of code, the horizontal movement would be overwritten.
     
  10. vakabaka

    vakabaka

    Joined:
    Jul 21, 2014
    Posts:
    1,153
    can you post your script ? I think something can be wrong in it input. The y-movement should not overwrite the x-movement.
     
  11. Rostam24

    Rostam24

    Joined:
    Mar 5, 2014
    Posts:
    119
    No I'm sorry for not being clear, but that's not what I meant. My character doesn't just jump up: he goes up and forward. This forward motion clashes with horizontal movement (in both my old script and your script ever since I moved to physics 2d). That's why I'm now exclusively using addforce for movement: now it works just fine.
    Sorry for the confusion!
     
  12. vakabaka

    vakabaka

    Joined:
    Jul 21, 2014
    Posts:
    1,153