This commit is contained in:
2021-06-13 10:28:03 +02:00
parent eb70603c85
commit df2d24cbd3
7487 changed files with 943244 additions and 0 deletions

View File

@@ -0,0 +1,314 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using Random = UnityEngine.Random;
using AnimationImporter.Boomlagoon.JSON;
using UnityEditor;
using System.IO;
namespace AnimationImporter.Aseprite
{
[InitializeOnLoad]
public class AsepriteImporter : IAnimationImporterPlugin
{
// ================================================================================
// const
// --------------------------------------------------------------------------------
const string ASEPRITE_STANDARD_PATH_WINDOWS = @"C:\Program Files (x86)\Aseprite\Aseprite.exe";
const string ASEPRITE_STANDARD_PATH_MACOSX = @"/Applications/Aseprite.app/Contents/MacOS/aseprite";
public static string standardApplicationPath
{
get
{
if (Application.platform == RuntimePlatform.WindowsEditor)
{
return ASEPRITE_STANDARD_PATH_WINDOWS;
}
else
{
return ASEPRITE_STANDARD_PATH_MACOSX;
}
}
}
// ================================================================================
// static constructor, registering plugin
// --------------------------------------------------------------------------------
static AsepriteImporter()
{
AsepriteImporter importer = new AsepriteImporter();
AnimationImporter.RegisterImporter(importer, "ase", "aseprite");
}
// ================================================================================
// public methods
// --------------------------------------------------------------------------------
public ImportedAnimationSheet Import(AnimationImportJob job, AnimationImporterSharedConfig config)
{
if (CreateSpriteAtlasAndMetaFile(job))
{
AssetDatabase.Refresh();
ImportedAnimationSheet animationSheet = CreateAnimationSheetFromMetaData(job, config);
return animationSheet;
}
return null;
}
public bool IsValid()
{
return AnimationImporter.Instance != null && AnimationImporter.Instance.sharedData != null;
}
public bool IsConfigured()
{
return File.Exists(Path.GetFullPath(AnimationImporter.Instance.asepritePath));
}
// ================================================================================
// private methods
// --------------------------------------------------------------------------------
// parses a JSON file and creates the raw data for ImportedAnimationSheet from it
private static ImportedAnimationSheet CreateAnimationSheetFromMetaData(AnimationImportJob job, AnimationImporterSharedConfig config)
{
string textAssetFilename = job.directoryPathForSprites + "/" + job.name + ".json";
TextAsset textAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(textAssetFilename);
if (textAsset != null)
{
JSONObject jsonObject = JSONObject.Parse(textAsset.ToString());
ImportedAnimationSheet animationSheet = GetAnimationInfo(jsonObject);
if (animationSheet == null)
{
return null;
}
if (!animationSheet.hasAnimations)
{
Debug.LogWarning("No Animations found in Aseprite file. Use Aseprite Tags to assign names to Animations.");
}
animationSheet.previousImportSettings = job.previousImportSettings;
animationSheet.SetNonLoopingAnimations(config.animationNamesThatDoNotLoop);
// delete JSON file afterwards
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(textAsset));
return animationSheet;
}
else
{
Debug.LogWarning("Problem with JSON file: " + textAssetFilename);
}
return null;
}
/// <summary>
/// calls the Aseprite application which then should output a png with all sprites and a corresponding JSON
/// </summary>
/// <returns></returns>
private static bool CreateSpriteAtlasAndMetaFile(AnimationImportJob job)
{
char delimiter = '\"';
string parameters = "--data " + delimiter + job.name + ".json" + delimiter + " --sheet " + delimiter + job.name + ".png" + delimiter + " " + job.sheetConfigParameter + " --list-tags --format json-array " + delimiter + job.fileName + delimiter;
if (!string.IsNullOrEmpty(job.additionalCommandLineArguments))
{
parameters = job.additionalCommandLineArguments + " " + parameters;
}
bool success = CallAsepriteCLI(AnimationImporter.Instance.asepritePath, job.assetDirectory, parameters) == 0;
// move png and json file to subfolder
if (success && job.directoryPathForSprites != job.assetDirectory)
{
// create subdirectory
if (!Directory.Exists(job.directoryPathForSprites))
{
Directory.CreateDirectory(job.directoryPathForSprites);
}
// check and copy json file
string jsonSource = job.assetDirectory + "/" + job.name + ".json";
string jsonTarget = job.directoryPathForSprites + "/" + job.name + ".json";
if (File.Exists(jsonSource))
{
if (File.Exists(jsonTarget))
{
File.Delete(jsonTarget);
}
File.Move(jsonSource, jsonTarget);
}
else
{
Debug.LogWarning("Calling Aseprite resulted in no json data file. Wrong Aseprite version?");
return false;
}
// check and copy png file
string pngSource = job.assetDirectory + "/" + job.name + ".png";
string pngTarget = job.directoryPathForSprites + "/" + job.name + ".png";
if (File.Exists(pngSource))
{
if (File.Exists(pngTarget))
{
File.Delete(pngTarget);
}
File.Move(pngSource, pngTarget);
}
else
{
Debug.LogWarning("Calling Aseprite resulted in no png Image file. Wrong Aseprite version?");
return false;
}
}
return success;
}
private static ImportedAnimationSheet GetAnimationInfo(JSONObject root)
{
if (root == null)
{
Debug.LogWarning("Error importing JSON animation info: JSONObject is NULL");
return null;
}
ImportedAnimationSheet animationSheet = new ImportedAnimationSheet();
// import all informations from JSON
if (!root.ContainsKey("meta"))
{
Debug.LogWarning("Error importing JSON animation info: no 'meta' object");
return null;
}
var meta = root["meta"].Obj;
GetMetaInfosFromJSON(animationSheet, meta);
if (GetAnimationsFromJSON(animationSheet, meta) == false)
{
return null;
}
if (GetFramesFromJSON(animationSheet, root) == false)
{
return null;
}
animationSheet.ApplyGlobalFramesToAnimationFrames();
return animationSheet;
}
private static int CallAsepriteCLI(string asepritePath, string path, string buildOptions)
{
string workingDirectory = Application.dataPath.Replace("Assets", "") + path;
System.Diagnostics.ProcessStartInfo start = new System.Diagnostics.ProcessStartInfo();
start.Arguments = "-b " + buildOptions;
start.FileName = Path.GetFullPath(asepritePath);
start.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
start.CreateNoWindow = true;
start.UseShellExecute = false;
start.WorkingDirectory = workingDirectory;
// Run the external process & wait for it to finish
using (System.Diagnostics.Process proc = System.Diagnostics.Process.Start(start))
{
proc.WaitForExit();
// Retrieve the app's exit code
return proc.ExitCode;
}
}
private static void GetMetaInfosFromJSON(ImportedAnimationSheet animationSheet, JSONObject meta)
{
var size = meta["size"].Obj;
animationSheet.width = (int)size["w"].Number;
animationSheet.height = (int)size["h"].Number;
}
private static bool GetAnimationsFromJSON(ImportedAnimationSheet animationSheet, JSONObject meta)
{
if (!meta.ContainsKey("frameTags"))
{
Debug.LogWarning("No 'frameTags' found in JSON created by Aseprite.");
IssueVersionWarning();
return false;
}
var frameTags = meta["frameTags"].Array;
foreach (var item in frameTags)
{
JSONObject frameTag = item.Obj;
ImportedAnimation anim = new ImportedAnimation();
anim.name = frameTag["name"].Str;
anim.firstSpriteIndex = (int)(frameTag["from"].Number);
anim.lastSpriteIndex = (int)(frameTag["to"].Number);
switch (frameTag["direction"].Str)
{
default:
anim.direction = PlaybackDirection.Forward;
break;
case "reverse":
anim.direction = PlaybackDirection.Reverse;
break;
case "pingpong":
anim.direction = PlaybackDirection.PingPong;
break;
}
animationSheet.animations.Add(anim);
}
return true;
}
private static bool GetFramesFromJSON(ImportedAnimationSheet animationSheet, JSONObject root)
{
var list = root["frames"].Array;
if (list == null)
{
Debug.LogWarning("No 'frames' array found in JSON created by Aseprite.");
IssueVersionWarning();
return false;
}
foreach (var item in list)
{
ImportedAnimationFrame frame = new ImportedAnimationFrame();
var frameValues = item.Obj["frame"].Obj;
frame.width = (int)frameValues["w"].Number;
frame.height = (int)frameValues["h"].Number;
frame.x = (int)frameValues["x"].Number;
frame.y = animationSheet.height - (int)frameValues["y"].Number - frame.height; // unity has a different coord system
frame.duration = (int)item.Obj["duration"].Number;
animationSheet.frames.Add(frame);
}
return true;
}
private static void IssueVersionWarning()
{
Debug.LogWarning("Please use official Aseprite 1.1.1 or newer.");
}
}
}