- Home /
SkinnedMeshRenderer: Change Bones at start without changing mesh or blendshape results.
I'm trying to modify a SkinnedMeshRenderer at runtime but am running into a problem I can't figure out how to solve.
My team has provided me with a bone-rigged mesh of an average person. They also gave me some blendshapes that modify this mesh to match the shape of an individual person. So if I know a person's values for the blendshapes, I can make the character's mesh look like them. However, the problem I'm having is that the bones do not get modified, so if a person has short legs, the mesh becomes short correctly, but the bones are still the "Average" length. and when I try to animate the character, it gets all warped because it's animating long bones, but the mesh "expects" them to be short.
I'm trying to figure out how to make the bones match the mesh. I can actually perfectly calculate where the bones should be in the new mesh I have an array of bone positions. However, when I set the bones to these new locations, the mesh also moved to compensate for the bones moving. So now, when O add blendshape values, they are now incorrect, because they are assuming the mesh starts from the "average" mesh, not this bone-deformed mesh. So they no longer match the person. The bones match the person but not the mesh anymore.
Is there a way to only move the bones while keeping the mesh constant, and then "resetting" something so that it thinks this is the initial position? and then somehow the blendshapes are correct?
Hopefully my problem is clear.
I've tried cloning the mesh, changinging the bones, then restoring the old mesh, but it still gets deformed by the bone movement.
I've tried resetting the bindposes at different stages using:
public void ResetBindPoses() {
Mesh sharedMesh = skinnedMeshRenderer.sharedMesh;
Matrix4x4[] newBindPoses = new Matrix4x4[bones.Length];
Debug.Log($"binds: {sharedMesh.bindposes.Length}, bones: {bones.Length}");
for (int i = 0; i < bones.Length; i++) {
newBindPoses[i] = bones[i].worldToLocalMatrix * bones[0].parent.parent.localToWorldMatrix;
}
sharedMesh.bindposes = newBindPoses;
skinnedMeshRenderer.sharedMesh = sharedMesh;
}
That didn't seem to do much, but I don't really understand what bindposes are, and the unity help on bindposes is abysmal.
Your answer
Follow this Question
Related Questions
Unbind a skinned mesh in Unity 2 Answers
Importing Blender Object Splits Mesh Into 4 1 Answer
Importing models from streamingassets 0 Answers