Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

RelativeJoint 2D funny behaviour when rotating 360°

Discussion in 'Physics' started by joschi27, Nov 13, 2017.

  1. joschi27


    Jul 31, 2016
    Hello everyone!

    I'm creating a game where the player climbs around a 2d world with a pickaxe. The player is just a cube. The pickaxe is a child of the player and connected to the player with a relativejoint 2d.

    Everything works out great, except that when I tell the relativejoint that the target angle is now 180 instead of -180 (A full rotation basically) the relativejoint rotates my object around 360 degrees in the other direction. I tried using other joints, but what I'd like to achieve (a set angle in degrees and a distance while still dragging the player behind) isn't possible with those I think. I also tried detecting the moment the hammer reaches the -180 or 180 point and enabling/disabling the joint, or rotating the hammer around the other way.

    I got the game to work in 3d using a Hinge Joint, in 2d that's not possible because there somehow isn't a spring on the hinge joint.

    Basically, the goal is to have a consistent height and speed you can pull and jump to.

    I'm completely lost. Thank you for any help!
    ForgeSheep likes this.
  2. ForgeSheep


    Oct 31, 2018
    This can be solved by making sure the players rotation never makes big changes (so that if you keep rotating in the same direction the angle will keep increasing, past 360). When using this solution you do need to keep in mind the angle is no longer between 180 and -180.

    I made the angle wind up by adding an int "_loops",
    Code (CSharp):
    1. var prevRotation = _rb2D.rotation;
    before the angle changes, and

    Code (CSharp):
    1. _rb2D.rotation = (((_rb2D.rotation % 360) + 360) % 360) + _loops * 360;
    2.         if ((prevRotation - _rb2D.rotation) % 360 > 180) {
    3.             _loops++;
    4.             _rb2D.rotation += 360;
    5.         }
    6.         else if ((prevRotation - _rb2D.rotation) % 360 < -180) {
    7.             _loops--;
    8.             _rb2D.rotation -= 360;
    9.         }
    after the angle changes.
  3. joschi27


    Jul 31, 2016
    Thank you for your answer! This is exactly what I did after a while if I remember correctly. I thought this was kind of shoddy, because if you make 5'000'000 turns in one direction the value might flip ;). It seems like the RelativeJoint2D just has no "clamp" with the angles.. Every other joint does, this one doesn't, and I couldn't find anything about it in the documentation.