/// <summary> /// Creates spritesheet on aTexture using the json aAtlas generated by aseprite /// </summary> /// <param name="aTexture">Spritesheet texture</param> /// <param name="aObj">Aseprite object</param> public static void ImportSheet(TextureImporter aTexture, CAsepriteObject aObj) { // Change metadata CAtlasData tData = JsonConvert.DeserializeObject <CAtlasData>(aObj.targetAtlas.text); List <SpriteMetaData> tMetaData = new List <SpriteMetaData>(); aTexture.textureType = TextureImporterType.Sprite; aTexture.spriteImportMode = SpriteImportMode.Multiple; aTexture.filterMode = FilterMode.Point; #if UNITY_5_6_OR_NEWER aTexture.textureCompression = TextureImporterCompression.Uncompressed; #else aTexture.textureFormat = TextureImporterFormat.AutomaticTruecolor; #endif List <string> tKeys = new List <string>(); tKeys.AddRange(tData.frames.Keys); tKeys.Sort(); Dictionary <string, int> tAnimations = new Dictionary <string, int>(); Vector2 tPivot = aObj.pivot; SpriteAlignment tAlignment = aObj.alignment; for (int i = 0; i < tKeys.Count; i++) { string tKey = tKeys[i]; CAtlasData.Frame tFrame = tData.frames[tKey]; SpriteMetaData tThisData = new SpriteMetaData(); string tTag = GetTag(tKey); if (tTag != "") { if (tAnimations.ContainsKey(tTag)) { tAnimations[tTag] += 1; } else { tAnimations.Add(tTag, 0); } string tName = tTag + "_" + tAnimations[tTag]; tThisData.name = tName; tThisData.rect = new Rect( tFrame.frame.x, tFrame.frame.y, tFrame.frame.w, tFrame.frame.h ); tThisData.rect.y = tData.meta.size.h - tThisData.rect.y - tThisData.rect.height; tThisData.alignment = (int)tAlignment; tThisData.pivot = tPivot; tMetaData.Add(tThisData); } } aTexture.spritesheet = tMetaData.ToArray(); AssetDatabase.ImportAsset(aTexture.assetPath, ImportAssetOptions.ForceUpdate); }
/// <summary> /// Creates AnimationClips using the information in the json atlas created /// by aseprite. /// If CAsepriteWindow.UseTags is true, it separates the animations, /// otherwise it creates only one animation. /// </summary> /// <param name="aTexture">Spritesheet texture</param> /// <param name="aObj">Aseprite object</param> /// <returns>AnimationClips created</returns> public static AnimationClip[] ImportAnimation(TextureImporter aTexture, CAsepriteObject aObj) { CAtlasData tData = JsonConvert.DeserializeObject <CAtlasData>(aObj.targetAtlas.text); aTexture.textureType = TextureImporterType.Sprite; aTexture.spriteImportMode = SpriteImportMode.Multiple; aTexture.filterMode = FilterMode.Point; List <string> tKeys = new List <string>(); tKeys.AddRange(tData.frames.Keys); Dictionary <string, int> tAnimationsIndices = new Dictionary <string, int>(); Dictionary <string, List <Frame> > tAnimations = new Dictionary <string, List <Frame> >(); Sprite[] tSprites = AssetDatabase.LoadAllAssetsAtPath(aTexture.assetPath) .OfType <Sprite>().ToArray(); ResetOptions(); foreach (string tKey in tKeys) { string tTag = GetTag(tKey); if (tTag != "") { List <Frame> tFrameList; if (tAnimations.ContainsKey(tTag)) { tFrameList = tAnimations[tTag]; } else { tAnimationsIndices.Add(tTag, 0); tFrameList = new List <Frame>(); tAnimations.Add(tTag, tFrameList); } ObjectReferenceKeyframe kf = new ObjectReferenceKeyframe(); if (tFrameList.Count > 0) { float tTime = 0; for (int i = 0; i < tFrameList.Count; i++) { tTime += tFrameList[i].length; } kf.time = tTime; } else { kf.time = 0; } kf.value = GetSprite(tSprites, tTag + "_" + tAnimationsIndices[tTag].ToString()); Frame tFrame = new Frame(); tFrame.frame = kf; tFrame.length = tData.frames[tKey].duration / 1000f; tAnimations[tTag].Add(tFrame); tAnimationsIndices[tTag] += 1; } } foreach (KeyValuePair <string, KeyValuePair <int, string[]> > tPair in _frameOptions) { KeyValuePair <int, string[]> tEvent = tPair.Value; for (int i = 0; i < tEvent.Value.Length; i++) { Debug.Log(tEvent.Key + ", " + tEvent.Value[i]); } } EditorCurveBinding tBinding = GetBinding(aObj); AnimationClip[] tClips = new AnimationClip[tAnimations.Keys.Count]; int j = 0; foreach (string tKey in tAnimations.Keys) { int tInd = ClipInList(aObj.clips, tKey); AnimationClip tClip; if (tInd >= 0) { tClip = aObj.clips[tInd]; } else { tClip = new AnimationClip(); } List <Frame> tAnimation = tAnimations[tKey]; int tFramecount = tAnimation.Count; tClip.frameRate = 60; tClip.wrapMode = WrapMode.Loop; ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[tFramecount + 1]; for (int i = 0; i < tFramecount; i++) { keyFrames[i] = tAnimation[i].frame; } ObjectReferenceKeyframe kf = new ObjectReferenceKeyframe(); kf.time = keyFrames[tFramecount - 1].time + tAnimation[0].length; if ((!aObj.useConfig && aObj.loopAnim) || (aObj.useConfig && !HasOption(tKey, NO_LOOP))) { // Make last frame the same as first kf.value = tAnimation[0].frame.value; // Make animation loop AnimationClipSettings tSettings = AnimationUtility.GetAnimationClipSettings(tClip); tSettings.loopTime = true; AnimationUtility.SetAnimationClipSettings(tClip, tSettings); } else { kf.value = tAnimation[tAnimation.Count - 1].frame.value; } keyFrames[tFramecount] = kf; AnimationUtility.SetObjectReferenceCurve(tClip, tBinding, keyFrames); tClip.name = tKey; tClips[j] = tClip; j++; /* * string tAnimPath; * if (aEnv.targetAnimator != null) * { * string tPath = AssetDatabase.GetAssetPath(aEnv.targetAnimator); * tAnimPath = Path.GetDirectoryName(tPath) + "/" + aEnv.name + "_" + tKey + ".anim"; * } * else * { * if (CAsepriteWindow.UseConfiguredTargets) * tAnimPath = CAsepriteWindow.TargetAnimDir; * else * tAnimPath = Path.GetDirectoryName( * AssetDatabase.GetAssetPath(aEnv.targetTexture)); * if (string.IsNullOrEmpty(tAnimPath)) * tAnimPath = Path.GetDirectoryName( * AssetDatabase.GetAssetPath(aEnv.targetTexture)); * tAnimPath += "/" + aEnv.name + "_" + tKey + ".anim"; * } */ if (tInd < 0) { //if (tAnimPath.StartsWith(Application.dataPath)) // tAnimPath = "Assets/" + tAnimPath.Substring(Application.dataPath.Length); //AssetDatabase.CreateAsset(tClip, tAnimPath); AssetDatabase.AddObjectToAsset(tClip, aObj); } } AssetDatabase.SaveAssets(); // Frame options foreach (KeyValuePair <string, KeyValuePair <int, string[]> > tOption in _frameOptions) { AnimationClip tClip = GetClip(tClips, tOption.Key); List <AnimationEvent> tEvents = new List <AnimationEvent>(); if (tClip != null) { ObjectReferenceKeyframe[] tFrameList = AnimationUtility.GetObjectReferenceCurve(tClip, tBinding); int tFrameNum = tOption.Value.Key; if (tFrameNum >= 0 && tFrameNum < tFrameList.Length) { ObjectReferenceKeyframe tFrame = tFrameList[tFrameNum]; for (int i = 0; i < tOption.Value.Value.Length; i++) { string tOptionName = tOption.Value.Value[i]; if (tOptionName.StartsWith(EVENT_PLUS) && tFrameNum < tFrameList.Length - 1) { tFrame = tFrameList[tFrameNum + 1]; AnimationEvent tEvent = new AnimationEvent(); tEvent.time = tFrame.time; string[] tValues = tOptionName.Split(EVENT_SEPARATOR); if (tValues.Length > 1) { tValues = tValues[1].Split(SEPARATOR); if (tValues.Length > 1) { tEvent.functionName = tValues[0]; tEvent.stringParameter = tValues[1]; tEvents.Add(tEvent); } } } else if (tOptionName.StartsWith(EVENT)) { AnimationEvent tEvent = new AnimationEvent(); tEvent.time = tFrame.time; string[] tValues = tOptionName.Split(EVENT_SEPARATOR); if (tValues.Length > 1) { tValues = tValues[1].Split(SEPARATOR); if (tValues.Length > 1) { tEvent.functionName = tValues[0]; tEvent.stringParameter = tValues[1]; tEvents.Add(tEvent); } } } } } AnimationUtility.SetAnimationEvents(tClip, tEvents.ToArray()); } } aObj.clips = tClips; return(tClips); }
/// <summary> /// Exports a .ase file to a .json and .png file using Aseprite CLI /// </summary> /// <param name="aFile">.ase file path</param> /// <param name="aObj">Aseprite object</param> /// <returns></returns> public static bool Export(string aFile, CAsepriteObject aObj) { string tExePath = CAsepriteWindow.AsepriteExePath; if (!File.Exists(tExePath)) { UnityEngine.Debug.Log("File " + tExePath + " not found"); return(false); } // Create arguments string tName = Path.GetFileNameWithoutExtension(aFile); string tOutPath; if (aObj.targetTexture == null) { if (!CAsepriteWindow.UseConfiguredTargets || CAsepriteWindow.TargetDir == "") { tOutPath = Path.GetDirectoryName(aFile); } else { tOutPath = CAsepriteWindow.TargetDir; } if (!Directory.Exists(tOutPath)) { Directory.CreateDirectory(tOutPath); } tOutPath += "/" + tName + ".png"; } else { tOutPath = AssetDatabase.GetAssetPath(aObj.targetTexture); } int tBorder = aObj.border; string tFramename = ""; if (aObj.useTags) { tFramename = "{frame000}_{tag}"; } else { tFramename = "{frame000}_{title}"; } string args = "-b \"" + aFile + "\" --filename-format " + tFramename + " --sheet-pack "; if (tBorder > 0) { args += "--inner-padding " + tBorder.ToString() + " "; } args += "--sheet \"" + tOutPath + "\""; // Create process Process tProcess = new Process(); tProcess.StartInfo.FileName = tExePath; tProcess.StartInfo.UseShellExecute = false; tProcess.StartInfo.Arguments = args; tProcess.StartInfo.CreateNoWindow = true; tProcess.StartInfo.RedirectStandardOutput = true; tProcess.StartInfo.RedirectStandardError = true; tProcess.EnableRaisingEvents = true; tProcess.Start(); string tOutput = tProcess.StandardOutput.ReadToEnd(); using (StreamReader s = tProcess.StandardError) { //string error = s.ReadToEnd(); tProcess.WaitForExit(20000); } if (string.IsNullOrEmpty(tOutput)) { return(false); } // Apply border to atlas if (tBorder > 0) { CAtlasData tData = JsonConvert.DeserializeObject <CAtlasData>(tOutput); foreach (CAtlasData.Frame tFrame in tData.frames.Values) { tFrame.frame.x += tBorder; tFrame.frame.w -= tBorder * 2; tFrame.frame.y += tBorder; tFrame.frame.h -= tBorder * 2; } tOutput = JsonConvert.SerializeObject(tData, Formatting.Indented); } string tOutJsonFilePath; if (aObj.targetAtlas == null) { if (!CAsepriteWindow.UseConfiguredTargets || CAsepriteWindow.TargetDir == "") { tOutJsonFilePath = Path.GetDirectoryName(aFile); } else { tOutJsonFilePath = CAsepriteWindow.TargetDir; } if (!Directory.Exists(tOutJsonFilePath)) { Directory.CreateDirectory(tOutJsonFilePath); } tOutJsonFilePath += "/" + tName + ".json"; } else { tOutJsonFilePath = AssetDatabase.GetAssetPath(aObj.targetAtlas); } File.WriteAllText(tOutJsonFilePath, tOutput); if (tOutJsonFilePath.StartsWith(Application.dataPath)) { tOutJsonFilePath = "Assets" + tOutJsonFilePath.Substring(Application.dataPath.Length); } if (tOutPath.StartsWith(Application.dataPath)) { tOutPath = "Assets" + tOutPath.Substring(Application.dataPath.Length); } AssetDatabase.ImportAsset(tOutPath, ImportAssetOptions.ForceSynchronousImport); AssetDatabase.ImportAsset(tOutJsonFilePath, ImportAssetOptions.ForceSynchronousImport); aObj.targetAtlas = AssetDatabase.LoadAssetAtPath <TextAsset>(tOutJsonFilePath); aObj.targetTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(tOutPath); aObj.LastExport = DateTime.Now; return(true); }