Unity2D объединяет спрайты

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

Я еще не нашел этот ресурс: объединить массив объектов Sprite в один Sprite - Unity

Но я не думаю, что это работает для моих целей.

1 ответ

Если у вас уже есть эти спрайты в вашем проекте, вы можете просто отредактировать их настройки импорта в Advanced и установить переключатель Read/Write Enable.

Тогда вы сможете прочитать содержимое ваших спрайтов и объединить их следующим образом:

public Sprite CombineSpriteArray(Sprite[][] spritesArray)
{
    // Set those two or get them from one the the sprites you want to combine
    int spritesWidth = (int)spritesArray[0][0].rect.width;
    int spritesHeight = (int)spritesArray[0][0].rect.height;

    Texture2D combinedTexture = new Texture2D(spritesWidth * spritesArray.Length, spritesHeight * spritesArray[0].Length);

    for(int x = 0; x < spritesArray.Length; x++)
    {
        for(int y = 0; y < spritesArray[0].Length; y++)
        {
            combinedTexture.SetPixels(x * spritesArray.Length, y * spritesArray[0].Length, spritesWidth, spritesHeight, spritesArray[x][y].texture.GetPixels((int)spritesArray[x][y].textureRect.x, (int)spritesArray[x][y].textureRect.y, (int)spritesArray[x][y].textureRect.width, (int)spritesArray[x][y].textureRect.height));
            // For a working script, use:
            // combinedTexture.SetPixels32(x * spritesWidth, y * spritesHeight, spritesWidth, spritesHeight, spritesArray[x][y].texture.GetPixels32());
        }
    }
    combinedTexture.Apply();

    return Sprite.Create(combinedTexture, new Rect(0.0f, 0.0f, combinedTexture.width, combinedTexture.height), new Vector2(0.5f, 0.5f), 100.0f);
}

Предупреждение: код не проверен

Имейте в виду, что такая операция тяжелая и что асинхронное выполнение ее в сопрограмме может быть хорошей идеей, чтобы избежать замораживания.


РЕДАКТИРОВАТЬ:

Поскольку вам кажется, что вы новичок в Stack Overflow, имейте в виду, что это не скрипт, предоставляющий сервис, люди здесь, чтобы помогать друг другу: это означает, что предоставленный код не всегда будет идеальным, но может просто направить вас на правильный путь (это также почему я добавил "Предупреждение: код не проверен" после моего кода).

Вы утверждали, что код "полностью сломан" и "повсеместно выдает ошибки". Я написал небольшой фрагмент сценария для проверки сценария, и единственная ошибка, которую я получил, заключалась в том, что он (был принят несколько раз):

Поэтому после поиска в Google (что вы должны были сделать самостоятельно), я заметил, что GetPixels32() / SetPixels32() методы, которые также могут быть использованы вместо GetPixels() / SetPixels() (вот 3-й и 5-й результаты, которые показали этот метод). Просто изменив это, код теперь работал без нареканий.

Единственные проблемы, которые я получил, заключались в том, что спрайты были упакованы вместе в левом нижнем углу текстуры: из-за этого я допустил небольшую ошибку. Не сложно найти где: просто поменяй
x * spritesArray.Length, y * spritesArray[0].Length, ...
в
x * spritesWidth, y * spritesHeight, ...
внутри SetPixels метод.

Поэтому, пожалуйста, найдите весь тестовый скрипт, который я написал, и не стесняйтесь его использовать:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class TestScript : MonoBehaviour
{
    public Image m_DisplayImage;
    public Sprite m_Sprite1, m_Sprite2;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(CombineSpritesCoroutine());
        }
    }

    private IEnumerator CombineSpritesCoroutine()
    {
        Sprite[][] spritesToCombine = new Sprite[4][];
        for (int i = 0; i < spritesToCombine.Length; i++)
        {
            spritesToCombine[i] = new Sprite[4];
        }

        for (int x = 0; x < spritesToCombine.Length; x++)
        {
            for (int y = 0; y < spritesToCombine[x].Length; y++)
            {
                spritesToCombine[x][y] = ((x + y) % 2 == 0 ? m_Sprite1 : m_Sprite2);
            }
        }

        Sprite finalSprite = null;
        yield return finalSprite = CombineSpriteArray(spritesToCombine);

        m_DisplayImage.sprite = finalSprite;
    }

    public Sprite CombineSpriteArray(Sprite[][] spritesArray)
    {
        // Set those two or get them from one the the sprites you want to combine
        int spritesWidth = (int)spritesArray[0][0].rect.width;
        int spritesHeight = (int)spritesArray[0][0].rect.height;

        Texture2D combinedTexture = new Texture2D(spritesWidth * spritesArray.Length, spritesHeight * spritesArray[0].Length);

        for (int x = 0; x < spritesArray.Length; x++)
        {
            for (int y = 0; y < spritesArray[0].Length; y++)
            {
                combinedTexture.SetPixels32(x * spritesWidth, y * spritesHeight, spritesWidth, spritesHeight, spritesArray[x][y].texture.GetPixels32());
            }
        }
        combinedTexture.Apply();

        return Sprite.Create(combinedTexture, new Rect(0.0f, 0.0f, combinedTexture.width, combinedTexture.height), new Vector2(0.5f, 0.5f), 100.0f);
    }
}
Другие вопросы по тегам