Search Unity

Rigidbody.constraints is in local space in Unity5 vs Global space in other versions. Please fix

Discussion in 'Physics' started by Blorfy, Mar 14, 2015.

  1. Blorfy

    Blorfy

    Joined:
    Aug 28, 2012
    Posts:
    25
    So I upgraded to Unity 5 yesterday, and the process has been mostly smooth. But our flight model went completely haywire, and after a bunch of digging I found the following. I am hoping this is an oversight because to me it makes no sense to me at all to change constraints to local space. Constraints are about keeping an object in valid position and orientation vs the world, not itself.

    http://docs.unity3d.com/ScriptReference/Rigidbody-constraints.html

    the important bit is: Note that the constraints are applied in the local space of the Rigidbody.

    This is new to Unity5, and my game can't be the only one that this breaks. I am assuming this has to be an error on someone's part. I submitted a bug earlier about this, but when I checked the documentation and it listed that the constraints are applied in local space, I had to bring this up so it gets fixed. Note: Unity 4 and I believe 3 all use Global space for this, which makes a lot more sense since we are constraining vs a global environment, the game.
     
  2. skirtz1

    skirtz1

    Joined:
    Mar 8, 2015
    Posts:
    20
    Constrains in local space are MORE functional than constrains in global space, and are obvious and proper choice. The global constraint are wrong and do not make sense. If the constraints where in global coordinates, let say you constrain X coord for pitch, and instantiate two models: one with no rotation, the other rotated at Y for 90 degrees. Then the first will have constrained pitch, the secodn will have constrained roll.
     
  3. Blorfy

    Blorfy

    Joined:
    Aug 28, 2012
    Posts:
    25
    Games tend to take place on planes, and we want to restrict movements relative to those planes to make the gameplay work. These constraints need to be relative to the world we are making so we can have a sensible way to define rules on how we move around the world. If we ever rotate an object, we are no longer able to restrict movement sensibly. With Unity 5, any rotated object will now act differently from all others.

    Here is the case in my game.

    Our game takes place on the Y = 0 plane. We have ships on that plane. We constrain them in X and Z. We don't want them to pitch or roll on their own, but we do want them to turn. Now when a ship turns, it is allowed to bank (in Z) by moving the rotation. This is purely cosmetic all we really care about is the object's root position. When we apply a torque to the ship to turn it, we want to turn around Y (as it has always done in Unity 4, and I believe 3) If we wanted to apply a torque locally we could use relative torque to achieve that, but we want to apply a turning force to a rotated object in the world to spin it in Y no matter the orientation, which is now no longer a trivial matter. We have lost a set of physics functionality with this change, and I assume it was made in error. It is not mentioned in the Release notes and is either a mistake or a misguided change that will break peoples' physics implementations. Changes like this should not be made when there was already a simple method in place to achieve the other behavior (being relative torques)

    Randomly changing how a piece of physics code like this works breaks peoples' games and should not be done without consultation. This isn't a fix for a bug but an entire shift in how the physics behaves in the engine.

    Note: Your case is valid, but constraints like this come in pairs. You would not just constrain in X you would constrain in X and Z, which solves the problem. With constraints you are really selecting your desired rotation axis. In the case of a top down 2D type game it is Y for us, leaving X and Z constrained.
     
    Last edited: Mar 14, 2015
  4. Fu11English

    Fu11English

    Joined:
    Feb 27, 2012
    Posts:
    258
    Interesting change if it is indeed intended and not a bug. Also something I can make use of for my needs :)

    Wouldn't putting a configurable joint on your rigidbody, locking the desired axis / rotations and then setting 'configured in world space' give you the same effect?

    I haven't jumped into Unity 5 yet so haven't tried anything but I think that would work.
     
  5. Blorfy

    Blorfy

    Joined:
    Aug 28, 2012
    Posts:
    25
    The problem I have is that there are currently methods in place that people have been using since at least Unity 4 to deal with local space constraints, and code in place to deal with global space constraints, this code has not changed in years and projects are built around them.

    In our case, many systems are now broken, and these systems have worked for well and according to spec for literally years. The game is built around them working the way they did. Our ships are now behaving in all kinds of weird ways because we can not simply tell them, no matter what orientation you are currently banking through, you know what I don't want, I don't want you dipping into the playing plane, let alone what shockwaves are now doing to the ships.

    I am at a bit of a loss for what to do here because if Unity simply fixes this so it works the way it always has, then all these systems suddenly work again. If I take the project offline for a week and rework all these systems, and THEN Unity makes the changes I have to revert. I just need an answer so I can make a plan on how to deal with this.

    Personally I think most people coming to Unity 5 are doing so with established projects. In our case we have been working on our game full time for 2.5 years and it is nearly complete, so this change is pretty devastating.

    If someone really has their heart set on local constraints at Unity, please give us a globalSpace flag on the rigidbody to make the constraints work as they have in the past. (preferable defaulted to on)
     
  6. Fu11English

    Fu11English

    Joined:
    Feb 27, 2012
    Posts:
    258
    I understand your frustrations. Is the configurable joint - setup in world space not an option as I suggested?
     
  7. Blorfy

    Blorfy

    Joined:
    Aug 28, 2012
    Posts:
    25
    I am unsure as we have never needed to use joints in the past to deal with simple physics interactions. This could work, but sticking a joint on every physics entity in the game seems like it may lead to problems of its own. Again, if a solution was in place for years that people were using successfully, why change it. At least give us some way to access the original functionality.
     
  8. Fu11English

    Fu11English

    Joined:
    Feb 27, 2012
    Posts:
    258
    But the configurable joint *should* give you the desired functionality simply by clicking a few boxes in the inspector...

    Though I agree they should probably allow the rigidbody constraints to be configured in either world or local space.
     
  9. Blorfy

    Blorfy

    Joined:
    Aug 28, 2012
    Posts:
    25
    I spent some time on the configurable joint approach with one of the ships, but the joint was unable to properly lock the ship down as the constraints do. The joints seem to have some inherent springiness that was always coming into play. I was perpetually rising off the Y=0 plane as well and there was a lot of quick thrashing. I don't think the joints will do it in my case. I tried going from no constraints and slowly adding them to the joint, but as they were added the behavior got more and more wild. I think that the joints are meant to sort out physics interactions on an object themselves and do a good job, but I am applying physics too the objects in script which is interfering with what the joints want to do, leading to some pretty wild behavior.
     
  10. Fu11English

    Fu11English

    Joined:
    Feb 27, 2012
    Posts:
    258
    Try setting projection mode to position and rotation. Then set both projection distance and angle to 0. This should prevent the joints from being spongy.

    Also increasing solver iteration count will help but is obviously more costly on performance.
     
  11. Blorfy

    Blorfy

    Joined:
    Aug 28, 2012
    Posts:
    25
    gave it a try. The thrashing actually got worse when I locked X and Z in world. I don't think joints like having their rigid bodies touched on fixed update. The strange springy climb in Y was also there. I do appreciate your attempts to help though.
     
  12. Fu11English

    Fu11English

    Joined:
    Feb 27, 2012
    Posts:
    258
    Silly question but you have disabled the previously used rigidbody constraints before working with the config joint? :)

    I have a bike in Unity 4 built with several rigidbodys both constrained to each other and the world. It behaves correctly including adding various forces via script. I do use the max solver count though.

    Keep in mind there may be bugs in Unity 5. People do seem to be having trouble with various physics issues.
     
  13. Blorfy

    Blorfy

    Joined:
    Aug 28, 2012
    Posts:
    25
    Yup my partner and I were both twiddling the config joint at the same time trying things. The rigidbody constraints are all off. It just does not work in our case at all. We went from a perfectly working flight model that felt awesome to a mess because of one random change. I am in the process of writing a new flight model, still hoping Unity will give us the old constraint functionality back in some form.
     
  14. Fu11English

    Fu11English

    Joined:
    Feb 27, 2012
    Posts:
    258
    Do you have the Axis settings on the config joint set correctly?

    The other thing you could try is make a kinematic rigidbody gameobject, alligned to the world axis. Then on your ships config joint choose the new gameobject as the connected body. See if that plays nicely. Other than that I'm stumped.
     
  15. Blorfy

    Blorfy

    Joined:
    Aug 28, 2012
    Posts:
    25
    The real root of the problem right now is here:

    myRigidbody.MoveRotation(Quaternion.Lerp(myRigidbody.rotation, finalRot, Time.fixedDeltaTime/ maxBankSeconds));

    This handles the banking. Quaternion.Lerp wants to shortcut through the X plane to get to the final rotation. When the constraints used to work in world coordinates, they simply stopped this component of the Lerp from happening and everything worked. Now any banking ship will nose dive into the Y=0 plane as this Lerp cuts through X.

    If I turn the lerp off and just move the rotation to the finalRot, then all works as expected, BUT of course the object snaps to its final rotation and looks bad.
     
    Last edited: Mar 14, 2015
  16. MatthewW

    MatthewW

    Joined:
    Nov 30, 2006
    Posts:
    1,356
    Reading your game setup description: If banking is purely cosmetic, you should consider separating your physics objects from your visual objects (and apply the bank to the visual object only and tune as you would like independent of physics)...
     
  17. Blorfy

    Blorfy

    Joined:
    Aug 28, 2012
    Posts:
    25
    Cosmetic wasn't the right word. The banking is important because it is a multiplayer physics object with collision. Here is a video. There is lots of banking in it.



    Been trying a variety of things to regain the flight characteristics all day but its not there yet. I have resolved the nose dipping by forcing X rotation to be 0 every fixed update, but I am also having a problem with the rotation torques losing their strength at high bank values, which doesn't make sense because they are world space torques. I even tried applying the torque in local space, but nope.

    Quaternion finalRot = Quaternion.identity;
    Vector3 finalAngles = new Vector3(0, myRigidbody.rotation.eulerAngles.y, finalZ);
    finalRot.eulerAngles = finalAngles;

    myRigidbody.MoveRotation(Quaternion.Lerp(myRigidbody.rotation, finalRot, Time.fixedDeltaTime / maxBankSeconds));

    Vector3 currentEuler = myRigidbody.rotation.eulerAngles;
    currentEuler.x = 0;
    Quaternion currentRot = Quaternion.identity;
    currentRot.eulerAngles = currentEuler;
    myRigidbody.rotation = currentRot;

    myConstantForce.torque = Vector3.up * torqueMult;

    //same as above.
    //myRigidbody.AddRelativeTorque(transform.InverseTransformDirection(Vector3.up) * torqueMult);
     
  18. Alf203

    Alf203

    Joined:
    Dec 7, 2012
    Posts:
    461
    This change from Global to Local was intentional from Unity and is not considered a bug. It was changed in order to use some new feature of Physx 3 in order to fix some old issues related to sleeping rigidbodies.

    So you'll probably have to code your own constraints if you plan on having global ones.
     
  19. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    local makes much more sense than global.
     
  20. Blorfy

    Blorfy

    Joined:
    Aug 28, 2012
    Posts:
    25
    Yup I got the same mail from Unity this morning, thanks for the info though. I sent them a Unity 4 and 5 project with the different behaviors. I have rewritten the flight model to compensate.