Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Obi Fixed Updater causing
#1
In my game we are using physics to throwing an object. This is fairly standard as we are applying force and torque during FixedUpdate. In order to trigger an event we are checking if the rigidbody isSleeping and use that to reset a few conditions. This has been working fine for months until today, when we added an Obi rope to the scene. Once Obi Fixed Update has been added, it seems our the velocity of our rigidbody never seems to hit near 0. It's not clear how or why this is happening.

Any thoughts on why Obi Fixed update would be affecting the physics of other objects in the scene?
Reply
#2
(04-02-2021, 09:55 PM)madzilla Wrote: In my game we are using physics to throwing an object. This is fairly standard as we are applying force and torque during FixedUpdate. In order to trigger an event we are checking if the rigidbody isSleeping and use that to reset a few conditions. This has been working fine for months until today, when we added an Obi rope to the scene. Once Obi Fixed Update has been added, it seems our the velocity of our rigidbody never seems to hit near 0. It's not clear how or why this is happening.

Any thoughts on why Obi Fixed update would be affecting the physics of other objects in the scene?

It can potentially affect them in several ways, depending on your setup:

- If an actor (rope, cloth, etc) is attached to or in contact with a rigidbody (w/ the ObiRigidbody conponent) it will apply impulses to it to resolve attachments/collisions.

- If your ObiFixedUpdater has “substep Unity physics” enabled, additional substeps will be taken each physics step. FixedUpdate() is only called once per step, not once per substep.

If no actor is in contact with, attached to, or otherwise interacting with a rigidbody, and there’s no substepping enabled, then other objects in the scene are completely unaffected by Obi. In this case, there’s no reason for a rigidbody whose velocity was zero prior to adding an updater to the scene to modify its velocity in any way.

more details about your setup would be most useful Sonrisa
Reply
#3
Appreciate the quick reply! I'm new to all of this and still trying to find my way around...



A few more details on my setup. The rigidbody in motion is not attached to the rope but does contain a Obi Collider and an Obi Rigidbody so it can possibly collide with the rope. Collision appears to be working just fine. There is only one rope and one solver in the scene. Solver settings are all default.

My Obi Fixed Updater is set to Subset Unity Physics = unchecked and Substeps = 4. 

It's a pretty simple setup right now. Just a rigidbody that has a single force applied to it once in FixedUpdate.
Reply
#4
(05-02-2021, 12:53 AM)madzilla Wrote: Appreciate the quick reply! I'm new to all of this and still trying to find my way around...



A few more details on my setup. The rigidbody in motion is not attached to the rope but does contain a Obi Collider and an Obi Rigidbody so it can possibly collide with the rope. Collision appears to be working just fine. There is only one rope and one solver in the scene. Solver settings are all default.

My Obi Fixed Updater is set to Subset Unity Physics = unchecked and Substeps = 4. 

It's a pretty simple setup right now. Just a rigidbody that has a single force applied to it once in FixedUpdate.

Hi there,

Dug a bit deeper and discovered a potential a bug in Unity:
Obi does not mess with rigidbodies' sleeping state in any way. All it does is:

- Grabs rigidbody velocities at the start of a step.
- Modifies these velocities as a result of collisions, attachments, etc.
- Writes back the modified velocities at the end of a step.

If the velocity is zero (or near zero) at the start of the step and no contacts or other interactions take place, it will remain zero at the end of the step. Thing is,
setting the velocity of a rigidbody to *any* value wakes it up, even if this value is below the velocity sleeping threshold. Since the updater sets the ObiRigidbody velocity regardless of it having changed, it keeps it ever awake. Using Unity's physics debugger window makes this easy to see.

So, doing this guarantees the rigidbody will never go to sleep:

Code:
unityRigidbody.velocity = Vector3.zero;

This behavior doesn't make any sense whatsoever, specially considering it's not how PhysX (Unity's underlying physics engine) works by default: it won't wake up a rigidbody if you set its velocity to zero.

The workaround is fortunately simple, if not very elegant: force Obi to check if the velocity delta is above a threshold, if it isn't don't apply it. Replace lines 62 and 63 in ObiRigidbody.cs:

Code:
unityRigidbody.velocity += linearDelta;
unityRigidbody.angularVelocity += angularDelta;

with this:

Code:
if (Vector3.SqrMagnitude(linearDelta - Vector3.zero) > 0.000001f)
     unityRigidbody.velocity += linearDelta;
if (Vector3.SqrMagnitude(angularDelta - Vector3.zero) > 0.000001f)
     unityRigidbody.angularVelocity += angularDelta;

Will investigate this with the Unity guys, as it's quite counterintuitive. Here's the thread: https://forum.unity.com/threads/rigidbod...o.1052369/
Reply
#5
Turns out this is an omission/bug in Unity.

Under the hood, assigning to rigidbody.velocity always calls rigidbody.setVelocity passing autoWake=true in PhysX. This causes the rigidbody to wake up no matter what velocity is being assigned, even if it's below the sleeping threshold.

They will consider exposing this parameter in the future, so that autoWake can be disabled when setting velocities. See: https://forum.unity.com/threads/rigidbod...o.1052369/
Reply
#6
Thank you so much! The patch worked perfectly and we are back in business. I appreciate your help and your time at looking behind the scenes. Very surprised that we uncovered a Unity issue with such a simple use case.
Reply