/// <summary>
/// Rebuilds the atlas texture.
/// </summary>
public void RebuildAtlas()
{
if (this.m_Instance == null)
{
Debug.LogError(
"SPAtlasBuilder failed to rebuild the atlas, reason: Sprite Packer Instance reference is null.");
return;
}
if (this.m_Instance.texture == null)
{
Debug.LogWarning(
"Sprite Packer failed to rebuild the atlas, please make sure the atlas texture reference is set.");
return;
}
// Make the atlas texture readable
if (SPTools.TextureSetReadWriteEnabled(this.m_Instance.texture, true, false))
{
// Get a list with the current sprites and applied actions
List <SPSpriteInfo> spriteInfoList = this.m_Instance.GetSpriteListWithAppliedActions();
// Get the source textures asset paths
string[] sourceTexturePaths = this.CollectSourceTextureAssetPaths(spriteInfoList);
// Make the source textures readable
if (!this.SetAssetsReadWriteEnabled(sourceTexturePaths, true))
{
Debug.LogError(
"Sprite Packer failed to make one or more of the source texture readable, please do it manually.");
return;
}
// Make sure all the textures have the correct texture format
this.CorrectTexturesFormat(spriteInfoList);
// If we are using max rects packing, sort the sprite info list by size
if (this.m_Instance.packingMethod == SPInstance.PackingMethod.MaxRects)
{
spriteInfoList.Sort(CompareBySize);
}
// Temporary textures array
Texture2D[] textures = new Texture2D[spriteInfoList.Count];
// Create an array to contain the sprite import data
SPSpriteImportData[] spritesImportData = new SPSpriteImportData[spriteInfoList.Count];
// Populate the textures and names arrays
int ia = 0;
foreach (SPSpriteInfo si in spriteInfoList)
{
// Temporary texture
Texture2D texture = null;
// Prepare the sprite import data
SPSpriteImportData importData = new SPSpriteImportData();
// Prepare the sprite name
importData.name = "Sprite_" + ia.ToString();
if (si.targetSprite != null)
{
importData.name = si.targetSprite.name;
}
else if (si.source != null && (si.source is Texture2D || si.source is Sprite))
{
if (si.source is Texture2D)
{
importData.name = (si.source as Texture2D).name;
}
else
{
importData.name = (si.source as Sprite).name;
}
}
// Prepare texture
// In case the source texture is missing, rebuild from the already existing sprite
if (si.source == null && si.targetSprite != null)
{
// Copy the sprite into the temporary texture
texture = new Texture2D((int)si.targetSprite.rect.width, (int)si.targetSprite.rect.height,
TextureFormat.ARGB32, false);
Color[] pixels = si.targetSprite.texture.GetPixels((int)si.targetSprite.rect.x,
(int)si.targetSprite.rect.y,
(int)si.targetSprite.rect.width,
(int)si.targetSprite.rect.height);
texture.SetPixels(pixels);
texture.Apply();
}
// Handle texture source
else if (si.source is Texture2D)
{
// Get as texture
Texture2D sourceTex = si.source as Texture2D;
// Check if we have as source texture
if (sourceTex != null)
{
// Copy the source texture into the temp one
texture = new Texture2D(sourceTex.width, sourceTex.height, TextureFormat.ARGB32, false);
Color[] pixels = sourceTex.GetPixels(0, 0, sourceTex.width, sourceTex.height);
texture.SetPixels(pixels);
texture.Apply();
// Transfer the sprite data
importData.border = Vector4.zero;
importData.alignment = this.m_Instance.defaultPivot;
importData.pivot = this.m_Instance.defaultCustomPivot;
}
}
// Handle sprite source
else if (si.source is Sprite)
{
// Get as sprite
Sprite sourceSprite = si.source as Sprite;
// Make sure we have the sprite
if (sourceSprite != null)
{
// Copy the sprite into the temporary texture
texture = new Texture2D((int)sourceSprite.rect.width, (int)sourceSprite.rect.height,
TextureFormat.ARGB32, false);
Color[] pixels = sourceSprite.texture.GetPixels((int)sourceSprite.rect.x,
(int)sourceSprite.rect.y,
(int)sourceSprite.rect.width,
(int)sourceSprite.rect.height);
texture.SetPixels(pixels);
texture.Apply();
// Transfer the sprite data
importData.border = sourceSprite.border;
importData.alignment = SpriteAlignment.Custom;
importData.pivot = new Vector2(
(0f - sourceSprite.bounds.center.x / sourceSprite.bounds.extents.x / 2 + 0.5f),
(0f - sourceSprite.bounds.center.y / sourceSprite.bounds.extents.y / 2 + 0.5f));
}
}
// Save the new texture into our array
textures[ia] = (texture != null) ? texture : new Texture2D(1, 1);
// Set the sprite import data
spritesImportData[ia] = importData;
// Increase the indexer
ia++;
}
// Make the source textures assets non readable
if (SPTools.GetEditorPrefBool(SPTools.Settings_DisableReadWriteEnabled))
{
this.SetAssetsReadWriteEnabled(sourceTexturePaths, false);
}
// Clear the source textures asset paths
System.Array.Clear(sourceTexturePaths, 0, sourceTexturePaths.Length);
// Create a temporary texture for the packing
Texture2D tempTexture = new Texture2D(1, 1, TextureFormat.ARGB32, false);
// UV coords array
Rect[] uvs;
// Pack the textures into the temporary
if (this.m_Instance.packingMethod == SPInstance.PackingMethod.Unity)
{
uvs = tempTexture.PackTextures(textures, this.m_Instance.padding, this.m_Instance.maxSize);
}
else
{
uvs = UITexturePacker.PackTextures(tempTexture, textures, this.m_Instance.padding,
this.m_Instance.maxSize);
// Check if packing failed
if (uvs == null)
{
Debug.LogError(
"Sprite Packer texture packing failed, the textures might be exceeding the specified maximum size.");
return;
}
}
// Import and Configure the texture atlas (also disables Read/Write)
SPTools.ImportAndConfigureAtlasTexture(this.m_Instance.texture, tempTexture, uvs, spritesImportData);
// Clear the current sprite info list
this.m_Instance.ClearSprites();
// Clear the actions list
this.m_Instance.ClearActions();
// Destroy the textures from the temporary textures array
for (int ib = 0; ib < textures.Length; ib++)
{
UnityEngine.Object.DestroyImmediate(textures[ib]);
}
// Destroy the temporary texture
UnityEngine.Object.DestroyImmediate(tempTexture);
// Convert the temporary sprite info into array
SPSpriteInfo[] spriteInfoArray = spriteInfoList.ToArray();
// Clear the temporary sprite info list
spriteInfoList.Clear();
// Apply the new sprite reff to the sprite info and add the sprite info to the sprites list
for (int i = 0; i < spriteInfoArray.Length; i++)
{
SPSpriteInfo info = spriteInfoArray[i];
if (info.targetSprite == null)
{
info.targetSprite = SPTools.LoadSprite(this.m_Instance.texture, spritesImportData[i].name);
}
// Add to the instance sprite info list
this.m_Instance.AddSprite(info);
}
// Clear the sprites import data array
System.Array.Clear(spritesImportData, 0, spritesImportData.Length);
// Set dirty
EditorUtility.SetDirty(this.m_Instance);
}
else
{
Debug.LogError("Sprite Packer failed to make the atlas texture readable, please do it manually.");
}
}