Страница 1 из 1

Вопросы, касающиеся скрипта для создания мэшей в юнити

СообщениеДобавлено: 19 сен 2015, 06:40
AABB
Надеюсь можно создать такую тему, где буду спрашивать все вопросы, возникающие при его создании, может некоторые и глупые...

Для начала, скрипт вызывается из верхнего меню, создаёт ГО, помещает себя на него и генерирует для начала просто плейн. Как-то так:

Синтаксис:
Используется csharp
    [MenuItem("My Editor Scripts/Carve Land")]
    static void CreateBase()
    {
        GameObject landPiece = new GameObject();
        landPiece.AddComponent<CarveLand>();
        landPiece.name = "Land Piece";
        Selection.activeGameObject = landPiece;
        Undo.RegisterCreatedObjectUndo(landPiece, "Created Land Piece");
        landPiece.GetComponent<CarveLand>().Reset();
    }


И вот с некоторых пор это действие начало выдавать гору ошибок. http://radikal.ru/big/29d48c798a0044dea74c94933fbc660c

При чем в инспекторе есть кнопка ресет, которая делает то же самое landPiece.GetComponent<CarveLand>().Reset();
И она то работает как надо.

Вот какой ресет
Синтаксис:
Используется csharp
    public void Reset()
    {
        MyUtilityScript.ClearLog();
        storedHits.Clear();
        grid = vol.Multiply(res);
        var verts = new List<Vector3>();
        var uv = new List<Vector2>();
        var step = new Vector2(1f / grid.x, 1f / grid.z);
        step *= UVres;
        colors = new Color[(grid.x + 1)*(grid.z + 1)];

        for (int z = 0; z <= grid.z; z++)
        {
            for (int x = 0; x <= grid.x; x++)
            {
                verts.Add(new Vector3(x, 0, z) / res);
                uv.Add(new Vector2(x * step.x, z * step.y));
                colors[x + z * (1 + grid.x)] = Color.red;
            }
        }
        uvs = uv.ToArray();
        vertices = verts.ToArray();
        updateCollider = true;
        AddTris();

    void AddTris()
    {
        List<int> tris = new List<int>();

        for (int A = 0; tris.Count < grid.x * grid.z * 6; A++)
        {
            if (vertices[A].x == vol.x) continue;
            int B = A + grid.x + 1;
            int C = A + 1;
            int D = C + grid.x + 1;
            tris.AddRange(new int[]{ A, B, C, D, C, B});
        }
        triangles = tris.ToArray();
        ApplyMesh();
    }

    void ApplyMesh()
    {
        Undo.RecordObjects(new Object[] { this, GetComponent<MeshFilter>() }, "Carve Land");
        var mesh = new Mesh();
        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.uv = uvs;
        mesh.colors = colors;
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();
        mesh.Optimize();
        GetComponent<MeshFilter>().sharedMesh = mesh;

        if (updateCollider)
        {
            updateCollider = false;
            GetComponent<MeshCollider>().sharedMesh = mesh;
        }
    }
    }

Ошибка указывает на mesh.vertices = vertices;

Re: Вопросы, касающиеся скрипта для создания мэшей в юнити

СообщениеДобавлено: 19 сен 2015, 07:54
AABB
(удалено за ненадобностью)

Re: Вопросы, касающиеся скрипта для создания мэшей в юнити

СообщениеДобавлено: 20 сен 2015, 07:41
AABB
Касаемо первого поста - зря я даже приводил весь этот код. Посмотрел на свежую голову, оказалось просто переменная влияющая на размер меша равна нулю при запуске скрипта. И это потому, что я задавал её через запятую с остальными. Недавно где-то увидел что так делают и перенял, а оказывается нельзя так:
public int res, UVres, d, seed = 1;

Re: Вопросы, касающиеся скрипта для создания мэшей в юнити

СообщениеДобавлено: 20 сен 2015, 12:29
BornFoRdeatH
Синтаксис:
Используется csharp
public int res = 1321, UVres = 345, d = 456, seed = 1;

Re: Вопросы, касающиеся скрипта для создания мэшей в юнити

СообщениеДобавлено: 22 сен 2015, 10:58
AABB
BornFoRdeatH
Я уже понял, но всё равно спасибо за ответ.

А вот есть проблемы с Undo. Например, если скрипт рисует на мэше RGB маску для 3-х текстур. Параметры маски такие:
Синтаксис:
Используется csharp
mask = new Texture2D(1024, 1024, TextureFormat.RGB24, false);

Само по себе рисование происходит без особых тормозов, но нужно же внедрить Undo. Конечно, не каждый кадр:
Синтаксис:
Используется csharp
if(Event.current.mouseDown)
Undo.RecordObject(mask, "Paint Mask");

И тут начинает неприемлемо тормозить.
Пробовал, вместо сохранения текстуры, создать массив цветов и сохранять его вместе с ГО, но не получается. Как-то так:
Синтаксис:
Используется csharp
[SerializeField, HideInInspector]
Color32[] pxl;

void OnEnable()
{
    Undo.undoRedoPerformed = (Undo.UndoRedoCallback)System.Delegate.Combine(Undo.undoRedoPerformed, new Undo.UndoRedoCallback(this.UndoRedoPerformed));
    SceneView.onSceneGUIDelegate += SceneGUI;
}

void SceneGUI(SceneView sceneView)
{
    if (Event.current.mouseDown)
    {
        pxl = mask.GetPixels32();
        Undo.RecordObject(mask, "Paint Mask");
    }
    //прочий код
}

void UndoRedoPerformed()
{
    mask.SetPixels32(pxl);
    mask.Apply();
}
 

Как же быть?

Re: Вопросы, касающиеся скрипта для создания мэшей в юнити

СообщениеДобавлено: 23 сен 2015, 05:28
AABB
И тут начинает неприемлемо тормозить.

Поправка - не просто тормозит, а вообще не работает. Изменяет только какой-то маленький кусочек. Так что проблемы две: как сделать чтобы Undo.RecordObject текстуры не тормозило, и как сделать чтобы Undo работало. Нашёл какой-то "Editor Thread Dispatcher" в юнисторе за бесплатно, но он не уменьшил лаг.

А ещё, я только сейчас наконец чётко понял в каком случае Undo сохраняет меш. Столько мучений было! Значит, так не работает:
Синтаксис:
Используется csharp
Mesh mesh = GetComponent<MeshFilter>().sharedMesh;
mesh.colors = newСolors;
//и так далее
Undo.RecordObject(GetComponent<MeshFilter>(), "Edit mesh");
GetComponent<MeshFilter>().sharedMesh = mesh;

Так работает:
Синтаксис:
Используется csharp
Mesh mesh = Instantiate(GetComponent<MeshFilter>().sharedMesh);
mesh.colors = newСolors;
//и так далее
Undo.RecordObject(GetComponent<MeshFilter>(), "Edit mesh");
GetComponent<MeshFilter>().sharedMesh = mesh;

Re: Вопросы, касающиеся скрипта для создания мэшей в юнити

СообщениеДобавлено: 23 сен 2015, 17:05
AABB
Неужели никто не знает? Это же важно. Смысла в скрипте вообще нет, если нельзя сделать undo. Кстати, если я выбираю радиус кисти больше самой текстуры, то всё равно она заливается мгновенно. Ну так и должно быть, так во всех графических редакторах. Но почему же она не может с такой же скоростью сохраняться в undo?

Re: Вопросы, касающиеся скрипта для создания мэшей в юнити

СообщениеДобавлено: 23 сен 2015, 17:54
Tolking
Нет смысла в скрипте создания мешей, текстур и т.п. в юнити при наличии специализированных решений для этого... Среда Юнити это не графический редактор, он создан для работы на уровне игровых объектов.

Re: Вопросы, касающиеся скрипта для создания мэшей в юнити

СообщениеДобавлено: 23 сен 2015, 18:16
AABB
Многочисленные платные ассеты в сторе с вами не согласны. В разделе scripting/modelling 86 ассетов.

Re: Вопросы, касающиеся скрипта для создания мэшей в юнити

СообщениеДобавлено: 25 сен 2015, 08:04
AABB
Конкретно этот скрипт призван заменить террайн юнити, чтобы можно было:
1. делать пещеры
2. удалять на ровных поверхностях лишние полигоны
3. масштабировать uv, чтобы не изменять тайлинг текстур
4. разбивать на части, чтобы подгружались отдельно

Разве это глупая затея?

Re: Вопросы, касающиеся скрипта для создания мэшей в юнити

СообщениеДобавлено: 25 сен 2015, 10:29
Tolking
:) Не глупая.

1. кто будет делать пещеры?
2. кто будет удалять на ровных поверхностях лишние полигоны?
3. кто будет масштабировать uv, чтобы не изменять тайлинг текстур?
4. кто будет разбивать на части, чтобы подгружались отдельно?

Зачем ему изучать твой инструмент если он уже владеет другим и там это делать ему удобнее?

Но дело нужное. Из которого можно многому научиться...

Re: Вопросы, касающиеся скрипта для создания мэшей в юнити

СообщениеДобавлено: 25 сен 2015, 11:25
Dewa1s
ну, не факт, что другой инструмент выйдет удобнее.
Хотя ля полноценной замены террейна нужно пилить полноценный редактор для этого самого террейна, чтобы и погнуть его в нужных местах была возможность, и текстурками подкрасить если надо... Ну и шейдеры, кудаж без них.
Имхо, основной недостаток террейна юнити - отсутствие дырок. Иногда лютый баттхерт вызывает.
Хотя у меня свой велосипед на этот случай :D прозрачный меш генерируется поверх террейна, пользователю надо только букву Н тыкать.
cry.JPG

Гора в ужасе от происходящего

Re: Вопросы, касающиеся скрипта для создания мэшей в юнити

СообщениеДобавлено: 25 сен 2015, 13:18
AABB
2. кто будет удалять на ровных поверхностях лишние полигоны?
Скрипт, нажатием одной кнопки. В целом я понимаю, что преимущество 3д редакторов в том, что моделлеры умеют в них работать, а не в юнити. Но я под себя делаю. Ибо нанимать отдельно художника, чтобы он тебе нарисовалал горы и реки - как-то слишком, если самому можно сделать. Для этого худ. образование не требуется.

Но ещё преимущество редакторов в возможности продвинутой развертки. Стандартный Unwrapping юнити практически нерабочий. А сам я понимаю только как по виду сверху сделать, или кругами ствол дерева. Правда сейчас есть шейдеры, которые сами неплохо справляются с разверткой, но они дорогие, для мобильных не вариант, если я не ошибаюсь.

Хотя ля полноценной замены террейна нужно пилить полноценный редактор для этого самого террейна
Может быть, но мне нравится когда компактно в инспекторе.
И у меня не полноценная замена. Нет ветра и для деревьев отдельный инструмент.

Гора в ужасе от происходящегоМило. А почему через пасть не видно террайн?

Re: Вопросы, касающиеся скрипта для создания мэшей в юнити

СообщениеДобавлено: 25 сен 2015, 14:02
Dewa1s
Ну, потому-что его и не должно быть видно)
Внутренности пещеры в любом случае надо делать отдельным мешем.
Единственная проблема с таким подходом - нельзя сделать проход через узкую гору, но опять же, решается на стадии планирования контента небольшим искривлением коридорчика так, чтобы игрок не мог стоя перед входом в пещеру видеть ее выход.