Skip to content

Instantly share code, notes, and snippets.

@Danil0v3s
Created August 11, 2022 22:18
Show Gist options
  • Save Danil0v3s/98db648307ba26d428b4defe627e8a8a to your computer and use it in GitHub Desktop.
Save Danil0v3s/98db648307ba26d428b4defe627e8a8a to your computer and use it in GitHub Desktop.
[MenuItem("UnityRO/Utils/Extract/Sprites")]
static void ExtractSprites() {
try {
var shouldContinue = true;
var config = ConfigurationLoader.Init();
FileManager.LoadGRF(config.root, config.grf);
var descriptors = FilterDescriptors(FileManager.GetFileDescriptors(), "data/sprite/Àΰ£Á·/¸öÅë/").Select(it => {
return it[..it.IndexOf(Path.GetExtension(it))].Replace("/", "\\");
}).Where(it => it.Length > 0).Distinct().ToList();
/**
* First we bulk create all the assets and the atlas textures
* Then we tell Unity to refresh its asset database
* After that we go over each sprite and convert its atlas texture to a proper Sprite format
* and slice every subsprite on the atlas
*/
AssetDatabase.StartAssetEditing();
var spriteDataPaths = new List<string>();
var spritesList = new List<List<Sprite>>();
for (int i = 0; i < descriptors.Count; i++) {
var progress = i * 1f / descriptors.Count;
if (EditorUtility.DisplayCancelableProgressBar("UnityRO", $"Extracting sprites {i} of {descriptors.Count}\t\t{progress * 100}%", progress)) {
shouldContinue = false;
break;
}
var descriptor = descriptors[i];
var sprPath = descriptor + ".spr";
var memoryReader = FileManager.ReadSync(descriptor + ".spr");
if (memoryReader == null) {
Debug.LogError($"Failed to extract {descriptor}");
continue;
}
var spr = memoryReader.ToArray();
var act = FileManager.Load(descriptor + ".act") as ACT;
var sprLoader = new CustomSpriteLoader();
var filename = Path.GetFileName(sprPath);
var filenameWithoutExtension = Path.GetFileNameWithoutExtension(sprPath);
var dir = sprPath.Substring(0, sprPath.IndexOf(filename)).Replace("/", "\\");
string assetPath = Path.Combine(GENERATED_RESOURCES_PATH, "Sprites", dir);
Directory.CreateDirectory(assetPath);
var spriteData = ScriptableObject.CreateInstance<SpriteData>();
sprLoader.Load(spr, filename);
spriteData.act = act;
spritesList.Add(sprLoader.Sprites);
var atlas = sprLoader.Atlas;
atlas.alphaIsTransparency = true;
var bytes = atlas.EncodeToPNG();
var spritePath = Path.Combine(assetPath, filenameWithoutExtension);
var atlasPath = spritePath + ".png";
File.WriteAllBytes(atlasPath, bytes);
var fullAssetPath = spritePath + ".asset";
AssetDatabase.CreateAsset(spriteData, fullAssetPath);
spriteDataPaths.Add(spritePath);
}
if (!shouldContinue) {
return;
}
AssetDatabase.StopAssetEditing();
AssetDatabase.Refresh();
for (var i = 0; i < spriteDataPaths.Count; i++) {
var progress = i * 1f / spriteDataPaths.Count;
if (EditorUtility.DisplayCancelableProgressBar("UnityRO", $"Post processing sprites {i} of {spriteDataPaths.Count}\t\t{progress * 100}%", progress)) {
break;
}
var spritePath = spriteDataPaths[i];
var sprites = spritesList[i];
var spriteData = AssetDatabase.LoadAssetAtPath(spritePath + ".asset", typeof(SpriteData)) as SpriteData;
var texture = AssetDatabase.LoadAssetAtPath(spritePath + ".png", typeof(Texture2D)) as Texture2D;
if (spriteData != null && texture != null) {
TextureImporter importer = AssetImporter.GetAtPath(spritePath + ".png") as TextureImporter;
importer.textureType = TextureImporterType.Sprite;
importer.spriteImportMode = SpriteImportMode.Multiple;
var textureSettings = new TextureImporterSettings();
importer.ReadTextureSettings(textureSettings);
textureSettings.spriteMeshType = SpriteMeshType.FullRect;
var sheetMetaData = sprites.Select(it => {
return new SpriteMetaData {
rect = it.rect,
name = it.name
};
}).ToArray();
importer.spritesheet = sheetMetaData;
importer.SetTextureSettings(textureSettings);
importer.SaveAndReimport();
AssetDatabase.WriteImportSettingsIfDirty(spritePath + ".png");
var savedSprites = AssetDatabase.LoadAllAssetsAtPath(spritePath + ".png")
.Where(it => it is Sprite)
.Select(it => it as Sprite)
.ToArray();
if (savedSprites.Length > 0) {
spriteData.sprites = savedSprites;
} else {
Debug.LogError($"Failed to load sprites of {spritePath}");
}
AssetDatabase.SaveAssets();
}
}
} finally {
EditorUtility.ClearProgressBar();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment