Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by birns92 · Jun 03, 2016 at 08:33 AM · animationmeshmayameshcolliderskinnedmeshrenderer

Can a mesh Collider work with an animated skinned Mesh.

Can I assign a Mesh Collider to a skinned Mesh and have it follow the mesh during animation? To help demonstrate my question I have created a simple animation of a cone which is skinned to a joint. The Joint animates to simply move the cone up. As you can see the Collider has been assigned to the cone.

alt text

But once the cone moves, the collider does not.

alt text

A simple solution to this one animation is to simply parent the Cone to the Joint. Or to assign the Copy the Cone's Mesh Collider and assign it to the Joint. But these two options would only be efficient for an example as small as the one I have demonstrated. In my current Project I am working with the human anatomy and animations where there are hundreds of skinned mesh objects. From what I have read, this might be impossible but I am curious if Unity has made this possible in recent years. Thank you very much in advance for any help.

cone1.jpg (120.7 kB)
cone2.jpg (93.9 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

5 Replies

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by birns92 · Jun 23, 2016 at 07:03 PM

From my own experience trying to update a mesh collider frame by frame is terribly slow, instead I found a work around by simply updating the mesh collider when I need it per theANMATOR2b suggestion. I tweaked the script I found here and added it to each game object with a mesh collider I would like to update.

 using UnityEngine;
 using System.Collections;
 
 public class SkinnedCollisionHelper : MonoBehaviour
 {
     // Public variables
     // Instance variables
     private CWeightList[] nodeWeights; // array of node weights (one per node)
     private Vector3[] newVert; // array for the regular update of the collision mesh
     private Mesh mesh; // the dynamically-updated collision mesh
     private MeshCollider collide; // quick pointer to the mesh collider that we're updating
                                   // Function:    Start
                                   //      This basically translates the information about the skinned mesh into
                                   // data that we can internally use to quickly update the collision mesh.
     void Start()
     {
         SkinnedMeshRenderer rend = GetComponent(typeof(SkinnedMeshRenderer)) as SkinnedMeshRenderer;
         collide = GetComponent(typeof(MeshCollider)) as MeshCollider;
         if (collide != null && rend != null)
         {
             Mesh baseMesh = rend.sharedMesh;
             mesh = new Mesh();
             mesh.vertices = baseMesh.vertices;
             mesh.uv = baseMesh.uv;
             mesh.triangles = baseMesh.triangles;
             newVert = new Vector3[baseMesh.vertices.Length];
             short i;
             // Make a CWeightList for each bone in the skinned mesh         
             nodeWeights = new CWeightList[rend.bones.Length];
             for (i = 0; i < rend.bones.Length; i++)
             {
                 nodeWeights[i] = new CWeightList();
                 nodeWeights[i].transform = rend.bones[i];
             }
 
             // Create a bone weight list for each bone, ready for quick calculation during an update...
             Vector3 localPt;
             for (i = 0; i < baseMesh.vertices.Length; i++)
             {
                 BoneWeight bw = baseMesh.boneWeights[i];
                 if (bw.weight0 != 0.0f)
                 {
                     localPt = baseMesh.bindposes[bw.boneIndex0].MultiplyPoint3x4(baseMesh.vertices[i]);
                     nodeWeights[bw.boneIndex0].weights.Add(new CVertexWeight(i, localPt, bw.weight0));
                 }
 
                 if (bw.weight1 != 0.0f)
                 {
                     localPt = baseMesh.bindposes[bw.boneIndex1].MultiplyPoint3x4(baseMesh.vertices[i]);
                     nodeWeights[bw.boneIndex1].weights.Add(new CVertexWeight(i, localPt, bw.weight1));
                 }
 
                 if (bw.weight2 != 0.0f)
                 {
                     localPt = baseMesh.bindposes[bw.boneIndex2].MultiplyPoint3x4(baseMesh.vertices[i]);
                     nodeWeights[bw.boneIndex2].weights.Add(new CVertexWeight(i, localPt, bw.weight2));
                 }
 
                 if (bw.weight3 != 0.0f)
                 {
                     localPt = baseMesh.bindposes[bw.boneIndex3].MultiplyPoint3x4(baseMesh.vertices[i]);
                     nodeWeights[bw.boneIndex3].weights.Add(new CVertexWeight(i, localPt, bw.weight3));
                 }
             }
 
             UpdateCollisionMesh();
         }
         else
         {
             Debug.LogError(gameObject.name + ": SkinnedCollisionHelper: this object either has no SkinnedMeshRenderer or has no MeshCollider!");
         }
     }
 
     // Function:    UpdateCollisionMesh
     //  Manually recalculates the collision mesh of the skinned mesh on this
     // object.
     public void UpdateCollisionMesh()
     {
         if (mesh != null)
         {
             // Start by initializing all vertices to 'empty'
             for (int i = 0; i < newVert.Length; i++)
             {
                 newVert[i] = new Vector3(0, 0, 0);
             }
 
             // Now get the local positions of all weighted indices...
             foreach (CWeightList wList in nodeWeights)
             {
                 foreach (CVertexWeight vw in wList.weights)
                 {
                     newVert[vw.index] += wList.transform.localToWorldMatrix.MultiplyPoint3x4(vw.localPosition) * vw.weight;
                 }
             }
 
             // Now convert each point into local coordinates of this object.
             for (int i = 0; i < newVert.Length; i++)
             {
                 newVert[i] = transform.InverseTransformPoint(newVert[i]);
             }
 
             // Update the mesh (& collider) with the updated vertices
             mesh.vertices = newVert;
             mesh.RecalculateBounds();
             collide.sharedMesh = mesh;
         }
     }
 }
 
 class CVertexWeight
 {
     public int index;
     public Vector3 localPosition;
     public float weight;
     public CVertexWeight(int i, Vector3 p, float w)
     {
         index = i;
         localPosition = p;
         weight = w;
     }
 }
 
 class CWeightList
 {
     public Transform transform;
     public ArrayList weights;
     public CWeightList()
     {
         weights = new ArrayList();
     }
 }

I called the update collision mesh function from another script and implemented it into another function like this

  SkinnedCollisionHelper[] items = FindObjectsOfType<SkinnedCollisionHelper>();
         foreach (SkinnedCollisionHelper item in items)
         {
             item.UpdateCollisionMesh();
         }

I use a play animation, and a pause animation function in my game. I simply add the previous short script into my pause function and whenever in the game I click pause, the mesh updates to fit. This is how I implement that into my Play and Pause Animation script.

 using UnityEngine;
 using System.Collections;
 using System;
 
 public class Play_Pause : MonoBehaviour
 {
     public Animation anim;
     public void Play()
     {
         GetComponent<Animation>().Play();
         anim = GetComponent<Animation>();
         foreach (AnimationState state in anim)
         {
             state.speed = 1F;
         }
     }
 
     public void Pause()
     {
         SkinnedCollisionHelper[] items = FindObjectsOfType<SkinnedCollisionHelper>();
         foreach (SkinnedCollisionHelper item in items)
         {
             item.UpdateCollisionMesh();
         }
 
         anim = GetComponent<Animation>();
         foreach (AnimationState state in anim)
         {
             state.speed = 0F;
         }
     }
 }

This does require you to have a Pause feature in your game. At least for my situation this works great. Hopefully it can be useful for anyone else who may have something similar

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image leodluz · Jan 03, 2017 at 12:27 AM 0
Share

I'm was tried that, work slower than Skinned$$anonymous$$eshRenderer.bake$$anonymous$$esh(); But, thanks. :)

avatar image Byol · Mar 20, 2017 at 10:09 PM 0
Share

Great! Thank you. You provided very clear and excellent solution. I solved my challenges with your code. Thanks again.

avatar image
3

Answer by Zodiarc · Jun 03, 2016 at 01:17 PM

I would simply add a capsule collider to every bone that may collide with other game objects (assuming the mesh is rigged). With good clooision layer setup you could even use a single collider to look for collisions with the terrain and the bobe colliders for collision between other non static objects. Assuming you would have a giant creature and a small player you would have cheap collision detection between those two and the environment but the player would still be able to run between the creature's legs without clipping into them.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by Hanz-Olo · Jan 30, 2017 at 10:53 AM

Mesh colliders on moving objects is a strain to the physics simulation. Changing the mesh collider frame by frame to match the animation of a mesh utterly kills it. It is great to see some code that does it, but I wouldn't let this near a commercial product. Best practice : If it moves and needs collision geometry; Use primitive colliders. Only use mesh colliders on complex static objects.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by theANMATOR2b · Jun 03, 2016 at 01:14 PM

Looks like it's not impossible - but pretty 'slow' http://forum.unity3d.com/threads/how-to-update-a-mesh-collider.32467/#post-401202

Might consider an asset to help in your instance. Mega-Fliers or something similar. Probably the best approach.

Also in your case - consider optimization techniques - swapping out complete/combined meshes for individual meshes only when needed.

Seems like a complicated/complex project. Fun!

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by chingwaifunggames · Jul 11, 2019 at 03:48 AM

I just wanna say thanks to birns92. your code works perfectly on Unity2019.1.7! you save my day! thank you!

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

90 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Two nearly identical animated meshes....why does one work and one does not. 1 Answer

Changing skin weights in maya destroys character prefab 0 Answers

Make mesh collider constantly change 1 Answer

Problem with collision detection in an animated object 1 Answer

Best practices for a giant moving environement/enemy 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges