- Home /
Attaching an object to a morphing mesh.
So I've got a plant-like eye stalk that swings back and forth via blendshapes/morphing and I want to attach an object to the eyeball portion. Essentially I want to have a single point on the 3d mesh that I can parent to that moves along with the morph.
My first guess was to use a single bone, but it didn't follow the blendshape morph at all. My other guess would be to somehow detect the vertices at the eyeball area and then somehow assign the object to follow those vertices (But I have no idea how to do that).
Answer by Bunny83 · Apr 18, 2016 at 03:59 AM
Well it's a bit tricky. One solution is what @Glurth explained in his answer but you can't use .sharedMesh
nor .mesh
as this will only return the original mesh. The actual skinning might even be done on the GPU. The temporary (skinned) mesh isn't available to the scripting side.
However Unity added (along with the blendshape support i guess) the method BakeMesh. This will calculate a static mesh of the current skinned position of the mesh. This mesh can be used to find the position of a certain vertex.
Everything would be easier if you would use a "normal" bone animation as each bone is an actual gameobject where you can attach things directly.
Answer by Glurth · Apr 17, 2016 at 09:28 PM
My other guess would be to somehow detect the vertices at the eyeball area and then somehow assign the object to follow those vertices
This is how I would do it. Once you have figured out which vertex in the mesh you want to attach to, you can get the model-space value of the vertex like so:
Vector3 pos=meshFilter.sharedMesh.vertices[vertexNumber];
You can then transform that into a world position with:
pos=meshFilter.transform.TransformPoint(pos);
And there is your attachment point, in world space. You could assign it directly to your attached object's transform.position
, when you want to update the objects position. But you probably want to add some offset to the pos, and perhaps even re-orient it based on the normal.
If you want the the normal of that vertex, you would use:
Vector3 norm=meshFilter.sharedMesh.normal[vertexNumber];
norm=meshFilter.transform.TransformDirection(pos);
To figure out which vertex you want, you can use the above code and, via trial and error (or on keypress), vary VertexNumber
until you find the one you like. (Keep in mind, multiple vertices MAY have the same position, and different normals)
Thanks Glurth, just what I needed! I do have one follow up though.
You say trial and error in Unity to find the vertex, is there any way to find the vertexNumber directly through the 3d modeling program (3ds$$anonymous$$ax for me) or does unity assign the numbers on import? Either way I can do trial and error, I'm just curious. Thanks again.
Hm, just tested this out, the object doesn't seem to actually follow when the models blendshape is changed, it just sticks to where it would be on the unchanged model.
I'm not sure what the "blendshape" is, but I suspect that whatever function is doing the blending/morphing, is outputting a mesh of some kind. It SOUNDS like you are looking at the vertices of your original mesh, rather than the blended/morphed mesh. Hmm, maybe the generated mesh gets stored in meshFilter.mesh
, rather than meshFilter.shared$$anonymous$$esh
- that stuff always throws me off.
odd, I see some code of yours in my email but not your comment. In that code I saw you are using a Skinned$$anonymous$$eshRenderer. I'm NOT familiar with those... so I could be way off base here!
Answer by Redrag · Apr 20, 2021 at 12:39 PM
You can also try a cloth component. If you snap it on and off it will give you the exact position of all the vertices. Less expensive than baking the mesh from my experience.