using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.U2D;
using UnityEngine;
using UnityEngine.U2D;
using Object = UnityEngine.Object;
///
/// 图集导入管线。
///
public class SpritePostprocessor : AssetPostprocessor
{
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{
foreach (var s in importedAssets)
{
EditorSpriteSaveInfo.OnImportSprite(s);
}
foreach (var s in deletedAssets)
{
EditorSpriteSaveInfo.OnDeleteSprite(s);
}
foreach (var s in movedFromAssetPaths)
{
EditorSpriteSaveInfo.OnDeleteSprite(s);
}
foreach (var s in movedAssets)
{
EditorSpriteSaveInfo.OnImportSprite(s);
}
}
}
public static class EditorSpriteSaveInfo
{
private const string NormalAtlasDir = "Assets/Atlas";
private const string UISpritePath = "Assets/AssetRaw/UIRaw";
private const string UIAtlasPath = "Assets/AssetRaw/UIRaw/Atlas";
private const string UIRawPath = "Assets/AssetRaw/UIRaw/UIRaw";
private static List m_dirtyAtlasList = new List();
private static Dictionary> m_allASprites = new Dictionary>();
private static Dictionary m_uiAtlasMap = new Dictionary();
private static bool m_inited = false;
private static bool m_dirty = false;
public static void Init()
{
if (m_inited)
{
return;
}
EditorApplication.update += CheckDirty;
}
public static void CheckDirty()
{
if (m_dirty)
{
m_dirty = false;
AssetDatabase.Refresh();
float lastProgress = -1;
for (int i = 0; i < m_dirtyAtlasList.Count; i++)
{
string atlasName = m_dirtyAtlasList[i];
Debug.Log("更新图集 : " + atlasName);
var curProgress = (float)i / m_dirtyAtlasList.Count;
if (curProgress > lastProgress + 0.01f)
{
lastProgress = curProgress;
var progressText = $"当前进度:{i}/{m_dirtyAtlasList.Count} {atlasName}";
bool cancel = EditorUtility.DisplayCancelableProgressBar("刷新图集" + atlasName, progressText, curProgress);
if (cancel)
{
break;
}
}
bool isUI = atlasName.StartsWith("UIRaw");
SaveAtlas(atlasName, isUI);
}
EditorUtility.ClearProgressBar();
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
m_dirtyAtlasList.Clear();
}
}
public static void OnImportSprite(string assetPath)
{
if (!assetPath.StartsWith(UISpritePath))
{
return;
}
TextureImporter ti = AssetImporter.GetAtPath(assetPath) as TextureImporter;
if (ti != null)
{
var modify = false;
if (assetPath.StartsWith(UISpritePath))
{
if (ti.textureType != TextureImporterType.Sprite)
{
ti.textureType = TextureImporterType.Sprite;
modify = true;
}
if (!string.IsNullOrEmpty(ti.spritePackingTag))
{
ti.spritePackingTag = string.Empty;
modify = true;
}
var setting = new TextureImporterSettings();
ti.ReadTextureSettings(setting);
if (setting.spriteGenerateFallbackPhysicsShape)
{
setting.spriteGenerateFallbackPhysicsShape = false;
ti.SetTextureSettings(setting);
modify = true;
}
if (IsKeepRawImage(assetPath))
{
//调整android格式
var andPlatformSettings = ti.GetPlatformTextureSettings("Android");
if (!andPlatformSettings.overridden)
{
andPlatformSettings.overridden = true;
modify = true;
}
if (andPlatformSettings.format != TextureImporterFormat.ASTC_6x6)
{
andPlatformSettings.format = TextureImporterFormat.ASTC_6x6;
ti.SetPlatformTextureSettings(andPlatformSettings);
modify = true;
}
//调整ios格式
var iosPlatformSettings = ti.GetPlatformTextureSettings("iPhone");
if (!iosPlatformSettings.overridden)
{
iosPlatformSettings.overridden = true;
modify = true;
}
if (iosPlatformSettings.format != TextureImporterFormat.ASTC_5x5)
{
iosPlatformSettings.format = TextureImporterFormat.ASTC_5x5;
iosPlatformSettings.compressionQuality = 50;
ti.SetPlatformTextureSettings(iosPlatformSettings);
modify = true;
}
}
}
if (modify)
{
ti.SaveAndReimport();
}
if (ti.textureType == TextureImporterType.Sprite)
{
OnProcessSprite(assetPath);
}
}
}
///
/// 是否保持散图(不打图集)
///
///
///
public static bool IsKeepRawImage(string dirPath)
{
return dirPath.Contains("UIRaw/Raw/") || dirPath.Contains("UIRaw_Raw_");
}
public static string GetSpritePath(string assetPath)
{
string path = assetPath.Substring(0, assetPath.LastIndexOf("."));
path = path.Replace("Assets/AssetRaw/", "");
return path;
}
///
/// 根据文件路径,返回图集名称
///
///
///
public static string GetPackageTag(string fullName)
{
fullName = fullName.Replace("\\", "/");
int idx = fullName.LastIndexOf("UIRaw", StringComparison.Ordinal);
if (idx == -1)
{
return "";
}
if (IsKeepRawImage(fullName))
{
return "";
}
var atlasPath = fullName.Substring(idx);
string str = atlasPath;
str = str.Substring(0, str.LastIndexOf("/", StringComparison.Ordinal)).Replace("/", "_");
return str;
}
public static void OnProcessSprite(string assetPath)
{
if (!assetPath.StartsWith("Assets"))
{
return;
}
if (assetPath.StartsWith("Assets/UIRaw_Delete"))
{
return;
}
Init();
var spriteName = Path.GetFileNameWithoutExtension(assetPath);
var spritePath = GetSpritePath(assetPath);
if (!m_uiAtlasMap.TryGetValue(spriteName, out string oldAssetPath) || spritePath == oldAssetPath)
{
m_uiAtlasMap[spriteName] = spritePath;
m_dirty = true;
}
else
{
Debug.LogError($"有重名的图片:{spriteName}\n旧图集:{oldAssetPath}\n新图集:{spritePath} ");
m_uiAtlasMap[spriteName] = spritePath;
m_dirty = true;
}
string atlasName = GetPackageTag(assetPath);
if (string.IsNullOrEmpty(atlasName))
{
bool keepRaw = IsKeepRawImage(assetPath);
if (!keepRaw)
{
Debug.LogError($"empty packingTag of asset :{assetPath} !!!");
}
return;
}
else
{
List ret;
if (!m_allASprites.TryGetValue(atlasName, out ret))
{
ret = new List();
m_allASprites.Add(atlasName, ret);
}
if (!ret.Contains(assetPath))
{
ret.Add(assetPath);
m_dirty = true;
if (!m_dirtyAtlasList.Contains(atlasName))
{
m_dirtyAtlasList.Add(atlasName);
}
}
}
}
public static void OnDeleteSprite(string assetPath)
{
if (assetPath.StartsWith("Assets/UIRaw_Delete"))
{
return;
}
if (!assetPath.StartsWith(UISpritePath))
{
return;
}
Init();
string atlasName = GetPackageTag(assetPath);
if (!m_allASprites.TryGetValue(atlasName, out var ret))
{
return;
}
//改成文件名的匹配
if (!ret.Exists(s => Path.GetFileName(s) == Path.GetFileName(assetPath)))
{
return;
}
if (assetPath.StartsWith(UISpritePath))
{
var spriteName = Path.GetFileNameWithoutExtension(assetPath);
if (m_uiAtlasMap.ContainsKey(spriteName))
{
m_uiAtlasMap.Remove(spriteName);
m_dirty = true;
}
}
ret.Remove(assetPath);
m_dirty = true;
if (!m_dirtyAtlasList.Contains(atlasName))
{
m_dirtyAtlasList.Add(atlasName);
}
}
#region 更新图集
public static void SaveAtlas(string atlasName, bool isUI)
{
List