Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  (5.3) ObiCloth passes through colliders when instantiated as prefab
#1
Just purchased and am really impressed with Obi Cloth overall.

I am using it to build a run time level editor in Unity. 

I have a prefab for a character that is lying down with a blanket on top. The blanket is an ObiCloth. The configuration of the cloth was copy and pasted from the ClothStaticMeshCollider sample scene.

My prefab works when I drag and drop the prefab from the "Project" window in the IDE at both build and run time. The cloth properly collides with the colliders, etc... Looks great.

However, when I try to instantiate the same exact prefab from a script, the cloth passes directly through the colliders, and drops through the ground and into the bottomless abyss.  

This script is triggered at runtime when I point and click where I want the object with the cloth applied to it to appear.

I instantiate the prefab with something like the below snippet:


Code:
// NOTE:
// "type" is set at build time in the inspector
// to the same prefab that works when I drag and drop it into a scene
Public GameObject type;
GameObject w = Instantiate(type);


The prefab is made up of (1) my character model, (2) a bunch of capsule colliders w/ ObiColliders for the character, (3) a plane with another collider w/ ObiCollider, and (4) the Obi cloth.

When I inspect the instantiated prefab all the components and hierarchy are the same when it's instantiated via script or IDE.

I've tried programmatically adding the solver, and changing the phases for the colliders. In both cases I found a way to make it work when I drag at drop the prefab from the Project window in the IDE into my scene. However, I've still not managed to get the obicloth blanket to work when the prefab is instantiated at run-time via script.

Before I dive any deeper I thought I'd check in to see if there is a known fix for this issue.

Any ideas on how to get my prefab to work when programmatically instantiated?

Thank you for your help!
Reply
#2
Hi there!

Collider geometry might not be updating, if they're instantiated while disabled. As you know, Obi uses the ObiCollider wrapper component to make Unity's collider data available to the particle system. ObiCollider updates this data whenever Unity's transform.changed is set to true. That could explain why the colliders do not "wake up" after being instantiated trough code, but do when dragged into the scene.

To know the exact cause of this, I would have to go over your code and see where the container prefabs are being instantiated/moved in relation to the physics update cycle. A quick fix would be slightly modifying ObiColliderBase.cs, make the "dirty" protected variable public, and then set it to true when you want to force a refresh (probably right after instantiating the prefab):

Code:
obiCollider.dirty = true;

The collider will be updated in the next physics step no matter what, and the "dirty" flag set automatically back to false.

Let me know if this solves the issue!

Also, in upcoming versions we've ditched this "dirty" flag. Instead, colliders are always checked for changes (in parallel) and then updated only if a change has been detected.
Reply
#3
(23-06-2020, 10:42 AM)josemendez Wrote: Hi there!

Collider geometry might not be updating, if they're instantiated while disabled. As you know, Obi uses the ObiCollider wrapper component to make Unity's collider data available to the particle system. ObiCollider updates this data whenever Unity's transform.changed is set to true. That could explain why the colliders do not "wake up" after being instantiated trough code, but do when dragged into the scene.

To know the exact cause of this, I would have to go over your code and see where the container prefabs are being instantiated/moved in relation to the physics update cycle. A quick fix would be slightly modifying ObiColliderBase.cs, make the "dirty" protected variable public, and then set it to true when you want to force a refresh (probably right after instantiating the prefab):

Code:
obiCollider.dirty = true;

The collider will be updated in the next physics step no matter what, and the "dirty" flag set automatically back to false.

Let me know if this solves the issue!

Also, in upcoming versions we've ditched this "dirty" flag. Instead, colliders are always checked for changes (in parallel) and then updated only if a change has been detected.

Thank you for the quick response! I'll give that a try today and provide an update here.
Reply
#4
(23-06-2020, 05:38 PM)caldorf Wrote: Thank you for the quick response! I'll give that a try today and provide an update here.

Setting obiCollider.dirty = true worked!

I initially tried setting dirty = true in the Start() method of the script I attached to the root object of my prefab, which did not work. However, doing it in Update did work. 

For this prototyping stage this achieves my goal.

Setting dirty to true in Update() is probably not a long term solution, so I'll likely need to dig a layer deeper when performance becomes more important. 

Let me know if the above sparks any ideas on how to improve my current solution.

Thanks again for the quick response!
Reply