how to code a skinnedMesh ?
enter code here
Hi everyone, i'm having problems coding bindposes for a simple skinnedMeshRenderer. I'm trying to create a rigidBody GameObject for each of my vertex and binding it to the vertex as a bone. this system is quite simple but no matter how i am coding this my mesh ends up totally messed up and the console is logging "Bones do not match BindPose". I really dont know what i am doing wrong and i came to simplify my code so far that it looks more like a Learning exemple but even now it doesn't work !!
Could someone please help me with that ?
//this mesh is assigned in the editor, right now i'm using a simple quad
public Mesh mesh;
void Start () {
//i will store the bones in this array
Transform[] bones = new Transform[4];
//the bindposes will come in this one, it has the same size as the bones one
Matrix4x4[] bindPoses = new Matrix4x4[4];
//one boneWeight foreach vertex
BoneWeight[] boneWeights = new BoneWeight[4];
for(int i = 0; i < mesh.vertexCount; i++)
{
bones[i] = new GameObject("bone").transform;
bones[i].position = transform.TransformPoint(mesh.vertices[i]);
bindPoses[i] = bones[i].worldToLocalMatrix * transform.localToWorldMatrix;
boneWeights[i].boneIndex0 = i;
boneWeights[i].weight0 = 1;
}
mesh.bindposes = bindPoses;
mesh.boneWeights = boneWeights;
gameObject.AddComponent<SkinnedMeshRenderer>().sharedMesh = mesh;
GetComponent<SkinnedMeshRenderer>().bones = bones;
}
Answer by rcalabrezi · Apr 21, 2017 at 07:13 AM
The code looks right and works with a few changes, even though I'm answering this too late.
I've just changed it a bit for future references, placing a few things to avoid messing up with the wrong mesh. Just attach the following script to a GO and select any mesh. Note that this way we will get a bone for every vertex in the mesh, so have in mind that the script is intended for learning purposes only.
using UnityEngine;
[RequireComponent(typeof(SkinnedMeshRenderer))]
public class Mine : MonoBehaviour
{
void Start()
{
SkinnedMeshRenderer skinned = this.GetComponent<SkinnedMeshRenderer>();
if (skinned.sharedMesh == null || skinned.sharedMesh.vertexCount == 0)
return;
Mesh mesh = (Mesh)Object.Instantiate(skinned.sharedMesh);
mesh.RecalculateBounds();
mesh.RecalculateNormals();
mesh.RecalculateTangents();
Transform[] bones = new Transform[mesh.vertexCount];
Matrix4x4[] bindPoses = new Matrix4x4[mesh.vertexCount];
BoneWeight[] boneWeights = new BoneWeight[mesh.vertexCount];
for (int index = 0; index < mesh.vertexCount; index++)
{
bones[index] = new GameObject(string.Format("Bone [{0}]", index)).transform;
bones[index].SetParent(this.transform);
bones[index].position = this.transform.TransformPoint(mesh.vertices[index]);
bindPoses[index] = bones[index].worldToLocalMatrix * this.transform.localToWorldMatrix;
boneWeights[index].boneIndex0 = index;
boneWeights[index].weight0 = 1;
}
mesh.bindposes = bindPoses;
mesh.boneWeights = boneWeights;
skinned.sharedMesh = mesh;
skinned.bones = bones;
}
}
The above code was tested in Unity 5.6.
-Rod
Answer by look001 · Oct 10, 2018 at 07:05 PM
The question is a bit old but i probably had the same problem recently. After setting the boneWeights of the mesh you need to set the vertices again.
example:
Vector3[] vertices = mesh.vertices;
BoneWeight[] weights = new BoneWeight[mesh.vertices.length];
// Some code...
mesh.boneWeights = weights; // after this the mesh is "messed up"
mesh.vertices = vertices; // this will reset the vertices
Hopefully this solves the problem for you aswell. Good Luck!
HI. $$anonymous$$aybe you got solution. After restart Unity my vertex aren't bind to mesh any longer. void Start() { CreateLoadBone(); }
private void CreateLoadBone()
{
meshCreated = gameObject.GetComponent<Skinned$$anonymous$$eshRenderer>().shared$$anonymous$$esh;
meshCollider = gameObject.GetComponent<$$anonymous$$eshCollider>();
count += 1;
if (count > 1) { count = 2; }
if (this.gameObject.GetComponent<BoneEditor>().count == 1)
{
Skinned$$anonymous$$eshRenderer skinned = this.GetComponent<Skinned$$anonymous$$eshRenderer>();
if (skinned.shared$$anonymous$$esh == null || skinned.shared$$anonymous$$esh.vertexCount == 0)
return;
//$$anonymous$$esh mesh = ($$anonymous$$esh)UnityEngine.Object.Instantiate(skinned.shared$$anonymous$$esh);
meshCreated.RecalculateBounds();
meshCreated.RecalculateNormals();
meshCreated.RecalculateTangents();
Transform[] bones = new Transform[meshCreated.vertexCount];
$$anonymous$$atrix4x4[] bindPoses = new $$anonymous$$atrix4x4[meshCreated.vertexCount];
BoneWeight[] boneWeights = new BoneWeight[meshCreated.vertexCount];
// AssetDatabase.CreateAsset(meshCreated, "Assets/body.mesh");
// AssetDatabase.SaveAssets();
for (int index = 0; index < meshCreated.vertexCount; index++)
{
bones[index] = new GameObject(string.Format("Bone [{0}]", index)).AddComponent<Verticales$$anonymous$$idifierGizmo>().transform;
bones[index].SetParent(this.transform);
bones[index].position = this.transform.TransformPoint(meshCreated.vertices[index]);
bindPoses[index] = bones[index].worldToLocal$$anonymous$$atrix * this.transform.localToWorld$$anonymous$$atrix;
boneWeights[index].boneIndex0 = index;
boneWeights[index].weight0 = 1;
}
meshCreated.bindposes = bindPoses;
meshCreated.boneWeights = boneWeights;
skinned.shared$$anonymous$$esh = meshCreated;
skinned.bones = bones;
meshCollider.shared$$anonymous$$esh = meshCreated;
}
else
{
gameObject.GetComponentInChildren<Verticales$$anonymous$$idifierGizmo>();
Skinned$$anonymous$$eshRenderer skinned = this.GetComponent<Skinned$$anonymous$$eshRenderer>();
Vector3[] vertices = meshCreated.vertices;
BoneWeight[] weights = new BoneWeight[meshCreated.vertices.Length];
//Verticales$$anonymous$$idifierGizmo[] bones = meshCreated.;
meshCreated.RecalculateBounds();
meshCreated.RecalculateNormals();
meshCreated.RecalculateTangents();
skinned.shared$$anonymous$$esh = meshCreated;
meshCollider.shared$$anonymous$$esh = meshCreated;
meshCreated.vertices = vertices; // this will reset the vertices
}
}
}
Answer by raqbiel · Jun 11, 2019 at 08:45 PM
Hi!, Theres an way to keep changes on mesh after unity reset? My mesh back to original form..
Your answer
![](https://koobas.hobune.stream/wayback/20220612081310im_/https://answers.unity.com/themes/thub/images/avi.jpg)