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);
}
}