1
\$\begingroup\$

I have an object Hand, with a rigid body attached to it. In every Update() call, the user's hand controller rotation and position are tracked.

In my scene, there is an object Pin, with a mesh collider attached to it.

In OnTriggerEnter() (inside the Hand class), Pin becomes re-parented to Hand. (Pin's original parent is something else.)

My scene also contains other objects with colliders. However, these other objects do not get re-parented -- only Pin does.

Once this re-parenting takes place, OnTriggerExit() (in the Hand class) is called immediately. This is surprising to me -- I had expected OnTriggerStay() (in the Hand class) to be invoked instead, since Hand is still in contact with Pin.

Is such behaviour by design? Is there an elegant way of working around such behaviour?

UPDATE:

In response to this comment:

Does the pin object have a parent before it becomes a part of the hand?

Yes. As mentioned in my post, Pin's original parent is something else.

Or is it placed inside another collider? And does the pin leave any of these collider areas when the parenting takes place?

As mentioned in my post, Pin itself has a mesh collider component attached to it. Perhaps I am not understanding the question correctly...

You can prevent the hand's script from getting this OnTriggerExit by adding a seperate rigidbody to the pin.

I added a separate rigid body to the pin (setting isKinematic to true), but OnTriggerExit() inside the Hand class is still called immediately after Pin gets re-parented.

MORE INFORMATION:

  • Pin's original parent (before it gets re-parented to Hand) does not itself have a collider component.
  • When OnTriggerExit(Collider collider) gets called immediately after the re-parenting takes place, the collider argument passed to the method is the Pin itself.
\$\endgroup\$
  • \$\begingroup\$ Does the pin object have a parent before it becomes a part of the hand? Or is it placed inside another collider? And does the pin leave any of these collider areas when the parenting takes place? In this case it makes sense to have the OnTriggerExit called. You can prevent the hand's script from getting this OnTriggerExit by adding a seperate rigidbody to the pin \$\endgroup\$ – Aj_ Apr 4 '18 at 10:50
  • \$\begingroup\$ Thank you for your comment. I will update my question to make things clearer. \$\endgroup\$ – user112729 Apr 4 '18 at 10:50
  • \$\begingroup\$ "And does the pin leave any of these collider areas when the parenting takes place?" - What I mean is whether or not the pin's collider was in contact with another collider and does this contact break when the parenting takes place. I feel like the answer is yes since it was already a child of something else. Try adding a kinematic rigidbody to the pin. This will prevent the hand's script from getting the OnTriggerExit call \$\endgroup\$ – Aj_ Apr 4 '18 at 11:03
  • \$\begingroup\$ Thank you for your reply. I have added a separate rigid body to the pin (setting isKinematic to true), but OnTriggerExit() is still called in the Hand class. \$\endgroup\$ – user112729 Apr 4 '18 at 11:06
  • \$\begingroup\$ @Aj_ I have added more information to the question. \$\endgroup\$ – user112729 Apr 4 '18 at 11:12
1
\$\begingroup\$

Re-parenting is a somewhat complicated operation in the physics world. In older versions of Unity it was recommended to disable colliders before changing parents, then re-enable them afterward, because it was a noticeably slow operation.

The physics system more or less has to remove the object from the whole world (triggering OnTriggerExits), then re-insert it into a new place. Even if that place ends up being equivalent, the physics engine either can't or just doesn't guarantee that up-front, so it conservatively handles all collision exit/enter events along the way to make absolutely sure no collision changes get missed.

So, it's generally a good idea not to reparent objects as a means to change their physics behaviour at runtime. Instead, you may want to consider using Joints to attach physics objects when you want them to move together.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy