UNITY создает blendshape из скриптовой задачи - PullRequest
0 голосов
/ 17 февраля 2020

Я создал скрипт, который конвертирует Meshes в SkinnedMeshRenderer и создает для него BlendShape .

В зависимости от всей отладочной информации в редактор, все выглядит правильно!

Но когда я перемещаю ползунок BlendShape, неправильные вершины перемещаются.

здесь:

ЗЕЛЕНЫЙ - текущая позиция вершин.

MAGENTA - путь каждой вершины от начальной позиции к позиции дельты.

СИНИЙ - позиция каждой вершины в это конечная дельта-позиция.

RED - позиция каждой вершины, которая не находится в пределах границ _selection. оставайтесь равными Vector3.zero.

https://forum.unity.com/attachments/blendshapebug-jpg.559830/

НО, когда я пытаюсь увидеть форму смеси в действии, я получаю это: enter image description here

Когда я пробую тот же сценарий, но просто перемещая вершины к их дельтам, это также выглядит хорошо: enter image description here

мой вопрос прост , ЧТО я делаю не так в процессе создания новых данных BlendShape для меня sh ??

вот мой c# код:

private void AddMorph(GameObject _ref, GameObject selection_mesh) {
    Mesh _m = new Mesh();

    // _selection - Bounds for selecting group of vertices within.
    _selection = new Bounds(selection_mesh.transform.position, selection_mesh.transform.localScale);

    // movement delta for future group of vertices.
    Vector3 newDelta = new Vector3(0, -0.4f, 0);

    // name for the future blend shape.
    string MorphName = "Custom[50-250]";

    //
    // Convert Mesh Renderer to Skinned Mesh Renderer, and create and instance of the shared mesh.
    //
    if (_ref.GetComponent < SkinnedMeshRenderer > () == null && _ref.GetComponent < MeshRenderer > () != null) {
        _m = Instantiate(_ref.GetComponent < MeshFilter > ().sharedMesh);
        Destroy(_ref.GetComponent < MeshRenderer > ());
        Destroy(_ref.GetComponent < MeshFilter > ());
        _ref.AddComponent < SkinnedMeshRenderer > ();
        _ref.GetComponent < SkinnedMeshRenderer > ().sharedMesh = _m;
    }
    else if (_ref.GetComponent < SkinnedMeshRenderer > () != null) // Create instance of shared mesh.
    {
        _m = Instantiate(_ref.GetComponent < SkinnedMeshRenderer > ().sharedMesh);
        _ref.GetComponent < SkinnedMeshRenderer > ().sharedMesh = _m;
    }
    else return; // if object has no renderer at all, stop the script execution.

    // Assign the new mesh we instantiated before.
    _ref.GetComponent < SkinnedMeshRenderer > ().sharedMesh = _m;
    // create array with deltas.
    Vector3[] newVertexDeltas = new Vector3[_m.vertices.Length];

    for (int y = 0; y < newVertexDeltas.Length; y++) {
        if (_selection.Contains(_ref.transform.TransformPoint(_m.vertices[y]))) {
            // each vertex found within the _selection bounds, gets the delta.
            newVertexDeltas[y] = newDelta;

            //GREEN draw line - current position of vertices.
            Debug.DrawLine(
            _ref.transform.TransformPoint(_m.vertices[y]), _ref.transform.TransformPoint(_m.vertices[y] + _m.normals[y] * 0.05f), Color.green, 1000000.0f);

            //MAGENTA draw line - path of each vertex from initial position to delta position.
            Debug.DrawLine(
            _ref.transform.TransformPoint(_m.vertices[y]), _ref.transform.TransformPoint(_m.vertices[y] + newDelta), Color.magenta, 1000000.0f);

            //BLUE draw line - position of each vertex in it's delta position.
            Debug.DrawLine(
            _ref.transform.TransformPoint(_m.vertices[y] + newDelta), _ref.transform.TransformPoint((_m.vertices[y] - _m.normals[y] * 0.05f) + newDelta), Color.blue, 1000000.0f);
        }
        else {
            //RED draw line - position of each vertex that are not within the _selection bounds.
            newVertexDeltas[y] = Vector3.zero;
            Debug.DrawLine(
            _ref.transform.TransformPoint(_m.vertices[y]), _ref.transform.TransformPoint(_m.vertices[y] - _m.normals[y] * 0.05f), Color.red, 1000000.0f);
        }
    }

    // Create the new blendshape with vertecies deltas.
    _m.AddBlendShapeFrame(MorphName, 100f, newVertexDeltas, null, null);
}

1 Ответ

1 голос
/ 18 февраля 2020

Исправлено. Только что выполнил пересчет Normals и Tangets сразу после добавления нового BlendShape. теперь все отлично работает.

}

    // Create the new blendshape with vertecies deltas.
    _m.AddBlendShapeFrame(MorphName, 100f, newVertexDeltas, null, null);        
    _m.RecalculateNormals();
    _m.RecalculateTangents();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...