Быстрая генерация иконок 3D объектов для Unity UI

Разрабатывали мы игру Speed Traffic, нужно было создать UI иконки доступных дисков для машин. Вручную вырезать и настраивать каждую иконку, долго и нудно, поэтому было найдено необычное решение проблемы.

Как это выглядит в игре

Speed Traffic rims icons

Задача: Быстро создать иконки, а лучше атлас 3D дисков для использования в интерфейсе

Решение: Выстраиваем объекты в сцене, делаем скриншот, разбиваем на спрайты. Автоматизируя всё что можно на своём пути.

К делу:

  • Открываем новую сцену
  • Выставляем настройки камеры так, чтобы получить 2D скриншот, (3D тоже можно :)
  • Убираем скайбокс, ставим цвет заливки на любой выделяющийся цвет, чтобы можно было его вырезать.

Настройки камеры для скриншота

  • Чем больше окно Game тем большее разрешение скриншота мы получим.
  • Делаем настройку окна Game так, чтобы получить текстуру нужным размером (512 x 512)

Unity Resolution settings

  • Расставляем нужные объекты в сцене с одинаковым расстоянием друг от друга...
  • Вручную получалось долго и криво, пришлось написать простой скрипт который выставляет объекты по сетке.
public bool ToDown = true; // Если true скрипт будет расставлять объекты вниз
[Header("Настройки сетки")]
public Vector2 GridSize = new Vector2(10,10); // Количество столбцов и колонн public Vector2 Spacing = new Vector2(10,10); // Отступы

[ContextMenu("Build Grid")] public void BuildGrid() { var hg = 0; var vg = 0; foreach (Transform obj in transform) { if (hg == (int)GridSize.x) { hg = 0; vg++; } obj.position = transform.position + (hg * Vector3.right * Spacing.x) + (vg * (ToDown ? Vector3.down : Vector3.up * Spacing.y)); hg++; } }



  • Делаем сохранение скриншота экрана, в указанную папку с именем объекта, и вырезаем задний фон через скрипт
 [Header("Настройки для скриншота")]
    public bool MakeTransparent = true;
    public Color32 TransparentColor = Color.white;
    public string iconsPath = "Assets/_Data/Icons/icon_{0}.png";



    [ContextMenu("Make Screenshot")]
    public void MakeScreenShot()
    {
        RenderTexture rt = new RenderTexture(Camera.main.pixelWidth, Camera.main.pixelHeight, 24);
        Camera.main.targetTexture = rt;

        Texture2D screenShot = new Texture2D(Camera.main.pixelWidth, Camera.main.pixelHeight, TextureFormat.ARGB32, false);

        Camera.main.Render();
        RenderTexture.active = rt;

        screenShot.ReadPixels(new Rect(0, 0, Camera.main.pixelWidth, Camera.main.pixelHeight), 0, 0);
        
        Camera.main.targetTexture = null;
    
        screenShot.alphaIsTransparency = true;

        if (MakeTransparent)
            MakeTransparentTexture(screenShot); 

        byte[] bytes = screenShot.EncodeToPNG();

        System.IO.File.WriteAllBytes(Application.dataPath.Replace("/Assets", "/") + string.Format(iconsPath, name), bytes);

    }

//Делаем выбранный цвет прозрачным на сохраняемой текстуре
public void MakeTransparentTexture(Texture2D texture)
    {
        
        Color32[] temp = texture.GetPixels32();

        if (temp.Length > 0)
        {
            for (int i = 0; i < temp.Length; ++i)
            {
                if (temp[i].ToString() == TransparentColor.ToString())
                {
                    temp[i] = Color.clear;
                }
            }
            texture.SetPixels32(temp);
            texture.Apply();
        }

    }
  • После сохранения текстуры, делаем автоматическую раскройку на спрайты и получаем готовый атлас.


MISSION SUCCESS :D

Минусы такого метода:

  • Unity не сохраняет настройки автоматической раскройки на спрайты, поэтому нужно куда-то для себя записывать
  • Низкое разрешение, наверно можно рендерить кадр в более высоком разрешение чем экран, но мне это было не нужно, т.к. игра на мобильные устройства.
  • Нельзя менять порядок обьектов в родителе скрипта, если хотите сохранить текущею раскройку на спрайты. Можно добавлять только в конец списка, не боясь за целостность и порядок UI.

Благодаря, Sprite Packer в Unity, можно ренедирить новые атласы с новыми наборами обьектов, а Unity объединит их в один атлас. :)

Документация:

Чтобы воспользоваться скриптом, не нужно запускать сцену в Unity, просто вызываем контекстное меню скрипта.


Как всегда можно скачать исходники

Download the source code: Save to Yandex.Disk

Tags: Speed Traffic, Triks, Icons, Generation, UI

This article is my 4th oldest. It is 486 words long