Unity3D - проблема создания костей процедурно (не гуманоидная) - PullRequest
0 голосов
/ 29 июня 2019

Я хотел сделать книгу (только обложку, без страниц) в виде единой сетки, которую можно оснастить, чтобы открывать и закрывать. Однако я хотел добавить кости по коду, используя другие игровые объекты для управления процессом. Благодаря этому позвоночник, передняя и задняя крышки разделены небольшим пространством. План состоит в том, чтобы настроить это по коду, а затем переместить кусочки книги вместе, как это обычно делается перед использованием. Мое текущее решение не дает результатов, поэтому мне интересно, не понимаю ли я, как это делается? Я не мог найти много информации о системе веса кости в Unity.

Сетка для одной книги:

Book mesh

Теперь, чтобы выбрать вершины, на которые должно воздействовать движение открытия / закрытия, я выбираю вершины (в список m_AfferedVertices) внутри этого вспомогательного объекта:

Пересекающиеся вершины должны быть гибкими частями буровой установки:

Vertices selectors

К объекту New Body прикреплен скин-рендеринг сетки.

Hierarchy

Это код, который я использую для добавления весов к вершинам, на которые я хочу воздействовать, и к объектам GameObject, представляющим кости.

private void _AddBones()
{
    if (m_SkinnedRenderer != null && (m_AffectedVertices != null && m_AffectedVertices.Count > 1))
    {
        var mesh            = m_SkinnedRenderer.sharedMesh;
        var parentObject    = m_NewBody;
        bool useBindPoses   = false;

        // Make bone weight for vertices
        BoneWeight[]    weights     = new BoneWeight[mesh.vertexCount];
        Transform[]     bones       = new Transform[2];
        Matrix4x4[]     bindPoses   = new Matrix4x4[2];

        for (int i = 0; i < weights.Length; i++)
        {
            if(m_AffectedVertices.Contains(mesh.vertices[i]))
            {
                weights[i].boneIndex0 = 0;
                weights[i].weight0    = 1;
            } 
            else
            {
                weights[i].boneIndex0 = 0;
                weights[i].weight0    = 0;
            }
        }
        mesh.boneWeights = weights;

        // Root bone
        bones[0]                = new GameObject("Root Bone").transform;
        bones[0].parent         = parentObject.transform;
        bones[0].localRotation  = Quaternion.identity;
        bones[0].localPosition  = Vector3.zero;     
        if(useBindPoses) { bindPoses[0] = bones[0].worldToLocalMatrix * parentObject.transform.localToWorldMatrix; }

        // Page bone
        bones[1]                = new GameObject("Left Bone").transform;
        bones[1].parent         = bones[0].transform;
        bones[1].localRotation  = Quaternion.identity;
        var pos                 = Hint.transform.localPosition;
        pos.y                   = pos.y * 5f;
        bones[1].localPosition  = pos;          
        if(useBindPoses) { bindPoses[1] = bones[1].worldToLocalMatrix * parentObject.transform.localToWorldMatrix; }

        if(useBindPoses) { mesh.bindposes = bindPoses; }
        m_SkinnedRenderer.sharedMesh = mesh;
        m_SkinnedRenderer.bones = bones;
        m_SkinnedRenderer.rootBone = bones[0];
    }
}

Я подтвердил, что список затрагиваемых вершин содержит вершины, выбранные синим пересекающимся прямоугольником. Game Bone Transform GameObjects успешно добавлены, но на ходу ничего не происходит.

...