164 lines
6.3 KiB
C#
164 lines
6.3 KiB
C#
|
|
using System;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
using System.Collections.Generic;
|
|
|
|
|
|
public class DefaultPackerPolicySampleToNormal : UnityEditor.Sprites.IPackerPolicy
|
|
{
|
|
protected class Entry
|
|
{
|
|
public Sprite sprite;
|
|
public UnityEditor.Sprites.AtlasSettings settings;
|
|
public string atlasName;
|
|
public SpritePackingMode packingMode;
|
|
public int anisoLevel;
|
|
}
|
|
|
|
private const uint kDefaultPaddingPower = 3; // Good for base and two mip levels.
|
|
|
|
public virtual int GetVersion() { return 1; }
|
|
protected virtual string TagPrefix { get { return "[TIGHT]"; } }
|
|
protected virtual bool AllowTightWhenTagged { get { return true; } }
|
|
protected virtual bool AllowRotationFlipping { get { return false; } }
|
|
|
|
public virtual bool AllowSequentialPacking { get { return true; } }
|
|
|
|
public static bool IsCompressedFormat(TextureFormat fmt)
|
|
{
|
|
if (fmt >= TextureFormat.DXT1 && fmt <= TextureFormat.DXT5)
|
|
return true;
|
|
if (fmt >= TextureFormat.DXT1Crunched && fmt <= TextureFormat.DXT5Crunched)
|
|
return true;
|
|
if (fmt >= TextureFormat.PVRTC_RGB2 && fmt <= TextureFormat.PVRTC_RGBA4)
|
|
return true;
|
|
if (fmt == TextureFormat.ETC_RGB4)
|
|
return true;
|
|
if (fmt >= TextureFormat.ETC_RGB4 && fmt <= TextureFormat.ETC2_RGBA8)
|
|
return true;
|
|
if (fmt >= TextureFormat.EAC_R && fmt <= TextureFormat.EAC_RG_SIGNED)
|
|
return true;
|
|
if (fmt >= TextureFormat.ETC2_RGB && fmt <= TextureFormat.ETC2_RGBA8)
|
|
return true;
|
|
if (fmt >= TextureFormat.ASTC_RGB_4x4 && fmt <= TextureFormat.ASTC_RGBA_12x12)
|
|
return true;
|
|
if (fmt >= TextureFormat.DXT1Crunched && fmt <= TextureFormat.DXT5Crunched)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
public void OnGroupAtlases(BuildTarget target, UnityEditor.Sprites.PackerJob job, int[] textureImporterInstanceIDs)
|
|
{
|
|
List<Entry> entries = new List<Entry>();
|
|
|
|
foreach (int instanceID in textureImporterInstanceIDs)
|
|
{
|
|
TextureImporter ti = EditorUtility.InstanceIDToObject(instanceID) as TextureImporter;
|
|
|
|
TextureFormat desiredFormat;
|
|
ColorSpace colorSpace;
|
|
int compressionQuality;
|
|
ti.ReadTextureImportInstructions(target, out desiredFormat, out colorSpace, out compressionQuality);
|
|
|
|
TextureImporterSettings tis = new TextureImporterSettings();
|
|
ti.ReadTextureSettings(tis);
|
|
|
|
Sprite[] sprites =
|
|
AssetDatabase.LoadAllAssetRepresentationsAtPath(ti.assetPath)
|
|
.Select(x => x as Sprite)
|
|
.Where(x => x != null)
|
|
.ToArray();
|
|
foreach (Sprite sprite in sprites)
|
|
{
|
|
Entry entry = new Entry();
|
|
entry.sprite = sprite;
|
|
entry.settings.format = desiredFormat;
|
|
entry.settings.colorSpace = colorSpace;
|
|
// Use Compression Quality for Grouping later only for Compressed Formats. Otherwise leave it Empty.
|
|
entry.settings.compressionQuality = IsCompressedFormat(desiredFormat) ? 40 : 0;
|
|
entry.settings.filterMode = Enum.IsDefined(typeof(FilterMode), ti.filterMode)
|
|
? ti.filterMode
|
|
: FilterMode.Bilinear;
|
|
entry.settings.maxWidth = 2048;
|
|
entry.settings.maxHeight = 2048;
|
|
entry.settings.generateMipMaps = ti.mipmapEnabled;
|
|
entry.settings.enableRotation = AllowRotationFlipping;
|
|
if (ti.mipmapEnabled)
|
|
entry.settings.paddingPower = kDefaultPaddingPower;
|
|
else
|
|
entry.settings.paddingPower = (uint)EditorSettings.spritePackerPaddingPower;
|
|
entry.atlasName = ParseAtlasName(ti.spritePackingTag);
|
|
entry.packingMode = GetPackingMode(ti.spritePackingTag, tis.spriteMeshType);
|
|
entry.anisoLevel = ti.anisoLevel;
|
|
entries.Add(entry);
|
|
}
|
|
|
|
Resources.UnloadAsset(ti);
|
|
}
|
|
|
|
// First split sprites into groups based on atlas name
|
|
var atlasGroups =
|
|
from e in entries
|
|
group e by e.atlasName;
|
|
foreach (var atlasGroup in atlasGroups)
|
|
{
|
|
int page = 0;
|
|
// Then split those groups into smaller groups based on texture settings
|
|
var settingsGroups =
|
|
from t in atlasGroup
|
|
group t by t.settings;
|
|
foreach (var settingsGroup in settingsGroups)
|
|
{
|
|
string atlasName = atlasGroup.Key;
|
|
if (settingsGroups.Count() > 1)
|
|
atlasName += string.Format(" (Group {0})", page);
|
|
|
|
UnityEditor.Sprites.AtlasSettings settings = settingsGroup.Key;
|
|
settings.anisoLevel = 1;
|
|
// Use the highest aniso level from all entries in this atlas
|
|
if (settings.generateMipMaps)
|
|
foreach (Entry entry in settingsGroup)
|
|
if (entry.anisoLevel > settings.anisoLevel)
|
|
settings.anisoLevel = entry.anisoLevel;
|
|
|
|
job.AddAtlas(atlasName, settings);
|
|
foreach (Entry entry in settingsGroup)
|
|
{
|
|
job.AssignToAtlas(atlasName, entry.sprite, entry.packingMode, SpritePackingRotation.None);
|
|
}
|
|
|
|
++page;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected bool IsTagPrefixed(string packingTag)
|
|
{
|
|
packingTag = packingTag.Trim();
|
|
if (packingTag.Length < TagPrefix.Length)
|
|
return false;
|
|
return (packingTag.Substring(0, TagPrefix.Length) == TagPrefix);
|
|
}
|
|
|
|
private string ParseAtlasName(string packingTag)
|
|
{
|
|
string name = packingTag.Trim();
|
|
if (IsTagPrefixed(name))
|
|
name = name.Substring(TagPrefix.Length).Trim();
|
|
return (name.Length == 0) ? "(unnamed)" : name;
|
|
}
|
|
|
|
private SpritePackingMode GetPackingMode(string packingTag, SpriteMeshType meshType)
|
|
{
|
|
if (meshType == SpriteMeshType.Tight)
|
|
if (IsTagPrefixed(packingTag) == AllowTightWhenTagged)
|
|
return SpritePackingMode.Tight;
|
|
return SpritePackingMode.Rectangle;
|
|
}
|
|
|
|
|
|
|
|
}
|