Last active
August 2, 2018 13:54
-
-
Save sukedon/e4ca8a21350b6a22cdcd8bae595c7513 to your computer and use it in GitHub Desktop.
SpritePackerとSpriteAtlasを自動変換するスクリプト
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Reflection; | |
using System.Text; | |
using UnityEditor; | |
using UnityEngine; | |
using UnityEngine.U2D; | |
public static class AtlasConverterModel | |
{ | |
public static string DefaultOutputPath = "Resources/SpriteAtlas"; | |
/// <returns>key:SpritePackerのタグ名,value:そのタグがついてる画像パス一覧 のdictを返却</returns> | |
public static Dictionary <string, List <string> > FetchTexturePackerTagGroup() | |
{ | |
var source = Application.dataPath; | |
string projectPath = Application.dataPath.Replace("Assets", ""); | |
List <string> paths = Directory.GetFiles(source, "*.*", SearchOption.AllDirectories) | |
.Where(path => path.EndsWith(".png") || path.EndsWith(".jpg")) | |
.Select(path => path.Replace(projectPath, "")) | |
.Select(path => path.Replace("\\", Path.AltDirectorySeparatorChar.ToString())) | |
.ToList(); | |
var dict = new Dictionary <string, List <string> >(); | |
for (int i = 0; i < paths.Count; i++) | |
{ | |
var path = paths[i]; | |
var importer = AssetImporter.GetAtPath(path); | |
if (importer == null) | |
{ | |
Debug.LogWarning("importerがnullporter:" + path); | |
continue; | |
} | |
var textureImporter = importer as TextureImporter; | |
if (textureImporter == null) | |
{ | |
Debug.LogWarning("textureImporterがnullporter:" + path); | |
continue; | |
} | |
var tag = textureImporter.spritePackingTag; | |
if (string.IsNullOrEmpty(tag)) | |
{ | |
Debug.LogWarning("packingtag is not defined:" + path); | |
continue; | |
} | |
if (dict.ContainsKey(tag)) | |
{ | |
dict[tag].Add(path); | |
} | |
else | |
{ | |
dict.Add(tag, new List <string>()); | |
dict[tag].Add(path); | |
} | |
EditorUtility.DisplayProgressBar("アトラス変換", "テクスチャのタグを取得中 " + (i + 1) + " / " + paths.Count, (float) i / paths.Count); | |
} | |
EditorUtility.ClearProgressBar(); | |
return dict; | |
} | |
public static void GenerateAtlas(string outputDirFromAssets, Dictionary <string, List <string> > dict) | |
{ | |
var atlases = dict.Keys.ToList(); | |
var outputDir = "Assets/" + outputDirFromAssets; | |
if (!Directory.Exists(outputDir)) | |
{ | |
Directory.CreateDirectory(outputDir); | |
AssetDatabase.Refresh(); | |
} | |
for (int i = 0; i < atlases.Count; i++) | |
{ | |
EditorUtility.DisplayProgressBar("アトラス変換", "アトラスを作成中 " + (i + 1) + " / " + atlases.Count, (float) i / atlases.Count); | |
var atlasName = atlases[i] + ".spriteatlas"; | |
var atlas = CreateAtlas(atlasName, outputDir); | |
var sprites = dict[atlases[i]]; | |
AddSpritesToAtlas(sprites.ToArray(), atlas); | |
} | |
EditorUtility.ClearProgressBar(); | |
} | |
private static void AddSpritesToAtlas(string[] spritePaths, SpriteAtlas atlas) | |
{ | |
List <Object> sprites = new List <Object>(); | |
for (int i = 0; i < spritePaths.Length; i++) | |
{ | |
Sprite sprite = AssetDatabase.LoadAssetAtPath <Sprite>(spritePaths[i]); | |
if (IsPackable(sprite)) { | |
sprites.Add(sprite); | |
} | |
} | |
AddPackAtlas(atlas, sprites.ToArray()); | |
} | |
private static bool IsPackable(Object o) | |
{ | |
return o != null && (o.GetType() == typeof(Sprite) || o.GetType() == typeof(Texture2D) || (o.GetType() == typeof(DefaultAsset) && ProjectWindowUtil.IsFolder(o.GetInstanceID()))); | |
} | |
private static void AddPackAtlas(SpriteAtlas atlas, Object[] spt) | |
{ | |
MethodInfo methodInfo = System.Type | |
.GetType("UnityEditor.U2D.SpriteAtlasExtensions, UnityEditor") | |
.GetMethod("Add", BindingFlags.Public | BindingFlags.Static); | |
if (methodInfo != null) { | |
methodInfo.Invoke(null, new object[] { atlas, spt }); | |
} | |
else { | |
Debug.Log("methodInfo is null"); | |
} | |
PackAtlas(atlas); | |
} | |
private static void PackAtlas(SpriteAtlas atlas) | |
{ | |
System.Type | |
.GetType("UnityEditor.U2D.SpriteAtlasUtility, UnityEditor") | |
.GetMethod("PackAtlases", BindingFlags.NonPublic | BindingFlags.Static) | |
.Invoke(null, new object[] { new[] { atlas }, EditorUserBuildSettings.activeBuildTarget }); | |
} | |
/// <summary> | |
/// | |
/// </summary> | |
/// <param name="atlasName"></param> | |
/// <param name="root">Resourceフォルダを含む必要あり</param> | |
/// <param name="dir"></param> | |
/// <returns></returns> | |
private static SpriteAtlas CreateAtlas(string atlasName, string dir) | |
{ | |
string yaml = | |
@"%YAML 1.1 | |
%TAG !u! tag:unity3d.com,2011: | |
--- !u!687078895 &4343727234628468602 | |
SpriteAtlas: | |
m_ObjectHideFlags: 0 | |
m_PrefabParentObject: {fileID: 0} | |
m_PrefabInternal: {fileID: 0} | |
m_Name: New Sprite Atlas | |
m_EditorData: | |
textureSettings: | |
serializedVersion: 2 | |
anisoLevel: 1 | |
compressionQuality: 50 | |
maxTextureSize: 2048 | |
textureCompression: 0 | |
filterMode: 1 | |
generateMipMaps: 0 | |
readable: 0 | |
crunchedCompression: 0 | |
sRGB: 1 | |
platformSettings: [] | |
packingParameters: | |
serializedVersion: 2 | |
padding: 4 | |
blockOffset: 1 | |
allowAlphaSplitting: 0 | |
enableRotation: 1 | |
enableTightPacking: 1 | |
variantMultiplier: 1 | |
packables: [] | |
bindAsDefault: 1 | |
m_MasterAtlas: {fileID: 0} | |
m_PackedSprites: [] | |
m_PackedSpriteNamesToIndex: [] | |
m_Tag: New Sprite Atlas | |
m_IsVariant: 0 | |
"; | |
AssetDatabase.Refresh(); | |
if (!Directory.Exists(dir)) | |
{ | |
Directory.CreateDirectory(dir); | |
AssetDatabase.Refresh(); | |
} | |
string filePath = dir + "/" + atlasName; | |
if (File.Exists(filePath)) | |
{ | |
File.Delete(filePath); | |
AssetDatabase.Refresh(); | |
} | |
FileStream fs = new FileStream(filePath, FileMode.CreateNew); | |
byte[] bytes = new UTF8Encoding().GetBytes(yaml); | |
fs.Write(bytes, 0, bytes.Length); | |
fs.Close(); | |
AssetDatabase.Refresh(); | |
var saPath = dir + "/" + atlasName; | |
SpriteAtlas atlas = AssetDatabase.LoadAssetAtPath <SpriteAtlas>(saPath); | |
return atlas; | |
} | |
public static void AllocateAtlasNameToTextureTag() | |
{ | |
var source = Application.dataPath; | |
string projectPath = Application.dataPath.Replace("Assets", ""); | |
List <string> paths = Directory.GetFiles(source, "*.*", SearchOption.AllDirectories) | |
.Where(path => path.EndsWith(".spriteatlas")) | |
.Select(path => path.Replace(projectPath, "")) | |
.Select(path => path.Replace("\\", Path.AltDirectorySeparatorChar.ToString())) | |
.ToList(); | |
for (int i = 0; i < paths.Count; i++) | |
{ | |
var atlas = AssetDatabase.LoadAssetAtPath <SpriteAtlas>(paths[i]); | |
Debug.Log("============="); | |
Debug.Log("Atlas ==> " + atlas.name); | |
MethodInfo methodInfo = System.Type | |
.GetType("UnityEditor.U2D.SpriteAtlasExtensions, UnityEditor") | |
.GetMethod("GetPackables", BindingFlags.NonPublic | BindingFlags.Static); | |
var packablesObj = methodInfo.Invoke(null, new object[] { atlas }); | |
Object[] packables = (Object[]) packablesObj; | |
for (int j = 0; j < packables.Length; j++) | |
{ | |
EditorUtility.DisplayProgressBar("アトラス->タグ取得", paths[i] + " " + j + "/" + packables.Length, (float) j / packables.Length); | |
var sprite = packables[j] as Sprite; | |
var texture = packables[j] as Texture; | |
if (sprite == null && texture == null) | |
{ | |
continue; | |
} | |
var assetPath = (sprite != null) ? AssetDatabase.GetAssetPath(sprite) : AssetDatabase.GetAssetPath(texture); | |
var textureImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter; | |
if (!textureImporter) | |
{ | |
continue; | |
} | |
textureImporter.spritePackingTag = atlas.name; | |
AssetDatabase.Refresh(); | |
} | |
} | |
EditorUtility.ClearProgressBar(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using UnityEditor; | |
using UnityEngine; | |
public class AtlasConverterWindow : EditorWindow | |
{ | |
private static string AssetPath = ""; | |
private static string OutputPath = ""; | |
private string _inputError = ""; | |
private static Dictionary <string, List <string> > _dict; | |
[MenuItem("Tools/SpriterPacker <-> SpriteAtlas 変換")] | |
public static void Open() | |
{ | |
var window = GetWindow <AtlasConverterWindow>(); | |
} | |
private void OnGUI() | |
{ | |
GUILayout.Label("SpritePackerとSpriteAtlasを変換するツール"); | |
DrawToAtlasTitle(); | |
DrawInput(); | |
GUILayout.Label(""); | |
DrawToPackerTitle(); | |
DrawToPackerButton(); | |
} | |
private void DrawToAtlasTitle() | |
{ | |
DrawLine("[SpriterPacker -> SpriteAtlas 変換]", Color.green); | |
} | |
private void DrawToPackerTitle() | |
{ | |
DrawLine("[SpriteAtlas -> SpritePacker 変換]", Color.green); | |
GUILayout.Label("スプライトアトラスで設定した画像を、各画像のタグに反映させます"); | |
} | |
private void DrawLine(string content, Color color) | |
{ | |
using (new EditorGUILayout.HorizontalScope()) | |
{ | |
var style = new GUIStyle(EditorStyles.label) | |
{ | |
normal = { textColor = color } | |
}; | |
GUILayout.Label(content, style); | |
GUILayout.FlexibleSpace(); | |
} | |
} | |
private void DrawInput() | |
{ | |
using (new EditorGUILayout.HorizontalScope()) | |
{ | |
GUILayout.Label("出力先のフォルダ名(Assets以下)"); | |
OutputPath = GUILayout.TextField(OutputPath, GUILayout.Width(200f)); | |
if (string.IsNullOrEmpty(OutputPath)) | |
{ | |
OutputPath = AtlasConverterModel.DefaultOutputPath; | |
} | |
if (GUILayout.Button("出力")) | |
{ | |
if (string.IsNullOrEmpty(OutputPath)) | |
{ | |
_inputError = "出力先を入力してください(Assets直下は非推奨)"; | |
} | |
else | |
{ | |
_inputError = ""; | |
_dict = AtlasConverterModel.FetchTexturePackerTagGroup(); | |
AtlasConverterModel.GenerateAtlas(OutputPath, _dict); | |
} | |
} | |
GUILayout.FlexibleSpace(); | |
} | |
if (!string.IsNullOrEmpty(_inputError)) | |
{ | |
DrawLine(_inputError, Color.red); | |
} | |
} | |
private void DrawToPackerButton() | |
{ | |
if (GUILayout.Button("出力")) | |
{ | |
AtlasConverterModel.AllocateAtlasNameToTextureTag(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment