0
\$\begingroup\$

Basically this is the set up: An N amount of prefabs are bundled together into a new GameObject. This is then merged into a single main mesh composited of M amount of material submeshes. The shape is standing upwards on the Y axis and is a bunch of arms. The goal is to move these by adding bones.

I wasn't able to find many examples on how to properly assign bones to a procedural mesh which isn't a simple cube.

The problem is assignment of vertices to the boneweights. I'd like for the transform Y=0 vertices to have no weight and the Y=furthest vertices have full weight. I am not sure how the assignment should be done.. Any pointers? :)

So far the Lower and Upper bone transforms are in the right place, but when moving them the mesh isn't bending as I hoped it would in a nice curve, half of the vertices are simply moved uniformly with a thin mesh line connecting the two halves.

private void _AddBones()
{
    if(m_SkinnedRenderer != null)
    {
        // Make bone weight for vertices
        BoneWeight[] weights = new BoneWeight[m_MainMesh.vertexCount];
        int halfway = (weights.Length / 2);
        for (int i = 0; i < weights.Length; i++)
        {
            if(i < halfway)
            {
                weights[i].boneIndex0 = 0;
                weights[i].weight0 = 1;
            }
            else
            {
                weights[i].boneIndex0 = 1;
                weights[i].weight0 = 1;
            }
        }

        m_MainMesh.boneWeights = weights;

        // Make bones and bind poses
        Transform[] bones = new Transform[2];
        Matrix4x4[] bindPoses = new Matrix4x4[2];
        bones[0] = new GameObject("Lower Bone").transform;
        bones[0].parent = m_MergedRoot.transform;
        bones[0].localRotation = Quaternion.identity;
        bones[0].localPosition = Vector3.zero;
        bindPoses[0] = bones[0].worldToLocalMatrix * m_MergedRoot.transform.localToWorldMatrix;

        bones[1] = new GameObject("Upper Bone").transform;
        bones[1].parent = m_MergedRoot.transform;
        bones[1].localRotation = Quaternion.identity;
        bones[1].localPosition = new Vector3(0, 1.5f, 0);
        bindPoses[1] = bones[1].worldToLocalMatrix * m_MergedRoot.transform.localToWorldMatrix;

        m_MainMesh.bindposes = bindPoses;
        m_SkinnedRenderer.bones = bones;
        m_SkinnedRenderer.sharedMesh = m_MainMesh;
        m_SkinnedRenderer.rootBone = bones[0];
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.