Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Let us know a bit about your interests, and if you'd like to become more directly involved. Take our survey!
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

How to update a mesh collider?

Discussion in 'Editor & General Support' started by rjarrier, Oct 20, 2009.

  1. rjarrier

    rjarrier

    Joined:
    Oct 20, 2009
    Posts:
    2
    Hello,

    I'm developing a video game student project.
    A feature consists to move a bridge like Tacoma bridge

    I move the mesh with bones, so the mesh moves correctly, but the mesh collider is not updated.
    My case : http://www.vimeo.com/7163412

    The bridges has a mesh collider and the cubes have got box colliders. The mesh collider of the bridge has got less than 255 faces.

    Do you know how I could do this?
     
  2. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    Hi - welcome to the forum!

    If you are using a boned animation created in a 3D application, the MeshCollider will not be updated as the animation plays, it will just stay in the initial position. However, you can update the collider if you are animating the mesh from a script with the Mesh API - you just need to assign the mesh to the sharedMesh property of the MeshCollider each frame.
     
    DimaKuzov and TakuanDaikon like this.
  3. rjarrier

    rjarrier

    Joined:
    Oct 20, 2009
    Posts:
    2
    I tested to assign sharedMesh collider in Update:
    Code (csharp):
    1. function Update ()
    2. {
    3.     if(Input.GetButton ("Fire1"))
    4.     {
    5.         //init:
    6.         //get the bone
    7.         var bone2 = transform.Find("bone02");
    8.         //initial force
    9.         var upForce = Time.deltaTime * 10;
    10.         var rotForce = Time.deltaTime * 40;
    11.         //input
    12.         var inputH = Input.GetAxis("Horizontal2");
    13.         var inputV = Input.GetAxis("Vertical1");
    14.        
    15.         //move the bone
    16.         bone2.transform.Rotate(Vector3.right*inputH*rotForce);
    17.         bone2.transform.Rotate(Vector3.forward*inputV*upForce);
    18.     }
    19. }
    20.  
    21. function LateUpdate ()
    22. {
    23.     //update the mesh collider
    24.     var skinnedMeshRenderer = GetComponent (SkinnedMeshRenderer);
    25.     collider.sharedMesh = skinnedMeshRenderer.sharedMesh;
    26. }
    But nothing better, mesh collier is alway initial mesh pattern. Did I a mistake?
     
  4. Bursar

    Bursar

    Joined:
    Oct 18, 2009
    Posts:
    50
    I'd be interested in the answer to this, as I don't understand why mesh colliders can't be updated. If I have a tank whose turret I want to rotate via a named bone, then it sounds like I need to manually deal with updating the mesh, or do away with it and use primitives instead.
     
  5. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    31,843
    Mesh colliders need serious pre-processing to function, and are not suitable for updating in real-time. You can't get the updated mesh from a skinned mesh renderer for technical reasons that I forget exactly, but even if you could, it would still be very slow to compute the mesh collider. Something like a tank is trivial to do using primitive colliders, and that's definitely the way to go.

    --Eric
     
  6. pkamat

    pkamat

    Joined:
    Dec 13, 2009
    Posts:
    20
    not sure if you still on this. there seems to be some change with unity 3.0 Previously
    GetComponent<MeshCollider>().sharedMesh = meshFilter.mesh;

    would work but in unity3 u need to null the mesh before assigning a new one.

    GetComponent<MeshCollider>().sharedMesh = null;
    GetComponent<MeshCollider>().sharedMesh = meshFilter.mesh;
     
  7. shinriyo_twitter

    shinriyo_twitter

    Joined:
    Aug 12, 2011
    Posts:
    328
  8. chingwa

    chingwa

    Joined:
    Dec 4, 2009
    Posts:
    3,007
    pkamat, thank you! I was pulling my hair out (and I don't have much left!)
     
  9. greencindy

    greencindy

    Joined:
    May 10, 2012
    Posts:
    17
    Thank you so much!! I've been working on this for a whole day!
     
  10. karl_

    karl_

    Joined:
    Mar 4, 2010
    Posts:
    463
    Thanks for saving me a few hours of frustration!
     
  11. pm dude

    pm dude

    Joined:
    Oct 14, 2012
    Posts:
    1

    Worked for me too!

    thanks
     
  12. b4cksp4ce

    b4cksp4ce

    Joined:
    Apr 13, 2011
    Posts:
    114
    Thanks you a lot. I lost a morning for that fix.

    It's solved it but it's kind of weird though to null the mesh before re-assigning it. :confused:
     
    RadeticTecgraf likes this.
  13. dogzerx2

    dogzerx2

    Joined:
    Dec 27, 2009
    Posts:
    3,680
    WOOHOO thanks!!! great tip!
     
  14. hitmax87

    hitmax87

    Joined:
    May 27, 2013
    Posts:
    12
    pkamat, thank you very much!
     
  15. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    7,284
    Yep, I can confirm that this does indeed force the mesh collider to update...

    But I can also confirm that, in my case at least, the result really is too slow (as Eric5h5 predicted). I've got dynamic terrain sculpting, but I certainly can't call this on every frame while the terrain changes.

    Hmm, but maybe I don't need to... I may be able to call it only on mouse-up, at least for this particular case. Or, failing that, I'll have to walk the mesh myself, find the closest few vertices, and interpolate, but... ugh. That gets ugly fast.
     
  16. Sharlatan

    Sharlatan

    Joined:
    Jul 23, 2013
    Posts:
    55
    I know you posted this years but I didn't find anything else that answered my question and I hope you (or someone else who knows the answer) will still read this: If updating a MeshCollider is so costly, what alternatives and workarounds are there?

    In my case I'm working on a relatively simple "toon style" ocean (think Zelda:Wind Waker). I think I won't need very realistic and detailed wave forms so I'll try to go with just some sinus vertex deformations (probably with some perlin noise added on top) that I'll apply on a plane. But of course I'd also like to have the waves interacting with ships and such and I don't see how I'd do this without constantly updating the MeshCollider.

    Thank you very much for any pointers you can give me!

    Edit: I assume if the water isn't too stormy and sluggish enough it'd suffice to update the MeshCollider only every few frames but I'd still be quiet often i assume and hopefully there's a better way..
     
    Last edited: Dec 20, 2014
  17. chingwa

    chingwa

    Joined:
    Dec 4, 2009
    Posts:
    3,007
    I think your best bet is to only calculate wave height where/when you need it, instead of calculating it across the entire mesh. It's frustrating that updating colliders is so slooooow, because it's the obvious and easiest way to do it. So for example with a boat object you need to build a function that will calculate the wave height at the boat's position, and then perform an offset to simulate buoyancy.

    This is what I do in Suimono, and it works really well, but I still wish I could have just used the original collider. It would have saved me months of work and frustration. I know Unity 5 has an improved physics system but I haven't tested if mesh collider updates work any faster.
     
  18. TonyT

    TonyT

    Joined:
    Mar 17, 2014
    Posts:
    17
    Thanks heaps ... I was soo stuck (still relevant with Unity 5)!
     
    RadeticTecgraf likes this.
  19. Sherasoft

    Sherasoft

    Joined:
    Nov 17, 2013
    Posts:
    8
    A small syntax error with all my respect:

    GetComponent<MeshCollider>().sharedMesh = null;
    GetComponent<MeshCollider>().sharedMesh = GetComponent<MeshFilter>().mesh;
     
  20. Mjbgtaad56

    Mjbgtaad56

    Joined:
    Aug 1, 2015
    Posts:
    1
    OMG THANKYOU!!!
     
  21. roryo

    roryo

    Joined:
    May 21, 2009
    Posts:
    1,212
    pkamat, this was REALLY helpful! Thanks!
     
  22. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    887
    I was wondering why I could not get a mesh collider to update and it was the same thing - set to null first.
    Surely this is a bug!
    I guess it checks if same mesh as before passed in but should check if the data within is same too...
     
  23. Zyl

    Zyl

    Joined:
    Jan 2, 2013
    Posts:
    81
    Am on Unity 5.5 right now and I did not have to set it to null before (will do anyway just to be sure). Either way this is terribly cryptic.
     
  24. gransoporo

    gransoporo

    Joined:
    Oct 18, 2017
    Posts:
    4
    thanks a lot
    just it would be interesting to know this updating can or should be improved... is it a slow process? I would like to start and I have a basic idea using colliders, and I need to update frequently
     
  25. Lesnikus5

    Lesnikus5

    Joined:
    May 20, 2016
    Posts:
    20
    Now it does not work in Unity 5.6.1. Any idea how to do this?