// ================================================================================ // create sprites and animations // -------------------------------------------------------------------------------- private void CreateAnimations(ImportedAnimationSheet animationSheet, AnimationImportJob job) { if (animationSheet == null) { return; } string imageAssetFilename = job.imageAssetFilename; if (animationSheet.hasAnimations) { string targetPath = _sharedData.animationsTargetLocation.GetAndEnsureTargetDirectory(animationSheet.assetDirectory); CreateAnimationAssets(animationSheet, imageAssetFilename, targetPath); } }
// ================================================================================ // create animator controllers // -------------------------------------------------------------------------------- private void CreateAnimatorController(ImportedAnimationSheet animations, AnimationImportJob job) { AnimatorController controller; string directory = sharedData.animationControllersTargetLocation.GetAndEnsureTargetDirectory(job.assetPath); // check if controller already exists; use this to not loose any references to this in other assets string pathForAnimatorController; if (sharedData.namingScheme == NamingScheme.ItsName) { pathForAnimatorController = $"{directory}/animatorController.controller"; } else { pathForAnimatorController = $"{directory}/{animations.name}.controller"; } controller = AssetDatabase.LoadAssetAtPath <AnimatorController>(pathForAnimatorController); if (controller == null) { // create a new controller and place every animation as a state on the first layer controller = AnimatorController.CreateAnimatorControllerAtPath(pathForAnimatorController); controller.AddLayer("Default"); foreach (var animation in animations.animations) { AnimatorState state = controller.layers[0].stateMachine.AddState(animation.name); state.motion = animation.animationClip; } } else { // look at all states on the first layer and replace clip if state has the same name var childStates = controller.layers[0].stateMachine.states; foreach (var childState in childStates) { AnimationClip clip = animations.GetClip(childState.state.name); if (clip != null) { childState.state.motion = clip; } } } EditorUtility.SetDirty(controller); AssetDatabase.SaveAssets(); }
private void CreateSprites(ImportedAnimationSheet animationSheet) { string imageFile = GetImageAssetFilename(animationSheet.basePath, animationSheet.name); TextureImporter importer = AssetImporter.GetAtPath(imageFile) as TextureImporter; // apply texture import settings if there are no previous ones if (!animationSheet.hasPreviousTextureImportSettings) { importer.textureType = TextureImporterType.Sprite; importer.spritePixelsPerUnit = sharedData.spritePixelsPerUnit; importer.mipmapEnabled = false; importer.filterMode = FilterMode.Point; importer.textureFormat = TextureImporterFormat.AutomaticTruecolor; } // create sub sprites for this file according to the AsepriteAnimationInfo importer.spritesheet = animationSheet.GetSpriteSheet( sharedData.spriteAlignment, sharedData.spriteAlignmentCustomX, sharedData.spriteAlignmentCustomY); // reapply old import settings (pivot settings for sprites) if (animationSheet.hasPreviousTextureImportSettings) { animationSheet.previousImportSettings.ApplyPreviousTextureImportSettings(importer); } // these values will be set in any case, not influenced by previous import settings importer.spriteImportMode = SpriteImportMode.Multiple; importer.maxTextureSize = animationSheet.maxTextureSize; EditorUtility.SetDirty(importer); try { importer.SaveAndReimport(); } catch (Exception e) { Debug.LogWarning("There was a problem with applying settings to the generated sprite file: " + e.ToString()); } AssetDatabase.ImportAsset(imageFile, ImportAssetOptions.ForceUpdate); Sprite[] createdSprites = GetAllSpritesFromAssetFile(imageFile); animationSheet.ApplyCreatedSprites(createdSprites); }
private void CreateAnimatorOverrideController(ImportedAnimationSheet animations, bool useExistingBaseController = false) { AnimatorOverrideController overrideController; string directory = sharedData.animationControllersTargetLocation.GetAndEnsureTargetDirectory(animations.assetDirectory); // check if override controller already exists; use this to not loose any references to this in other assets string pathForOverrideController = directory + "/" + animations.name + ".overrideController"; overrideController = AssetDatabase.LoadAssetAtPath <AnimatorOverrideController>(pathForOverrideController); RuntimeAnimatorController baseController = _baseController; if (useExistingBaseController && overrideController.runtimeAnimatorController != null) { baseController = overrideController.runtimeAnimatorController; } if (baseController != null) { if (overrideController == null) { overrideController = new AnimatorOverrideController(); AssetDatabase.CreateAsset(overrideController, pathForOverrideController); } overrideController.runtimeAnimatorController = baseController; // set override clips var clipPairs = overrideController.clips; for (int i = 0; i < clipPairs.Length; i++) { string animationName = clipPairs[i].originalClip.name; AnimationClip clip = animations.GetClipOrSimilar(animationName); clipPairs[i].overrideClip = clip; } overrideController.clips = clipPairs; EditorUtility.SetDirty(overrideController); } else { Debug.LogWarning("No Animator Controller found as a base for the Override Controller"); } }
private void CreateAnimationAssets(ImportedAnimationSheet animationInfo, string imageAssetFilename, string pathForAnimations) { string masterName; if (sharedData.namingScheme == NamingScheme.ItsName) { masterName = string.Empty; } else { masterName = Path.GetFileNameWithoutExtension(imageAssetFilename); } foreach (var animation in animationInfo.animations) { animationInfo.CreateAnimation(animation, pathForAnimations, masterName, sharedData.targetObjectType); } }
// ================================================================================ // create animator controllers // -------------------------------------------------------------------------------- private void CreateAnimatorController(ImportedAnimationSheet animations) { string directory = SharedData.AnimationControllersTargetLocation.GetAndEnsureTargetDirectory(animations.AssetDirectory); // check if controller already exists; use this to not loose any references to this in other assets string pathForAnimatorController = directory + "/" + animations.Name + ".controller"; var controller = AssetDatabase.LoadAssetAtPath <AnimatorController>(pathForAnimatorController); if (controller == null) { // create a new controller and place every animation as a state on the first layer controller = AnimatorController.CreateAnimatorControllerAtPath(pathForAnimatorController); controller.AddLayer("Default"); foreach (var animation in animations.Animations) { if (animation.IsCategory) { continue; } AnimatorState state = controller.layers[0].stateMachine.AddState(animation.Name); state.motion = animation.AnimationClip; } } else { // look at all states on the first layer and replace clip if state has the same name var childStates = controller.layers[0].stateMachine.states; foreach (var childState in childStates) { AnimationClip clip = animations.GetClip(childState.state.name); if (clip != null) { childState.state.motion = clip; } } } EditorUtility.SetDirty(controller); AssetDatabase.SaveAssets(); }
private ImportedAnimationSheet ImportJob(AnimationImportJob job) { job.SetProgress(0); IAnimationImporterPlugin importer = _importerPlugins[GetExtension(job.fileName)]; ImportedAnimationSheet animationSheet = importer.Import(job, sharedData); job.SetProgress(0.3f); if (animationSheet != null) { animationSheet.assetDirectory = job.assetDirectory; animationSheet.name = job.name; animationSheet.ApplySpriteNamingScheme(sharedData.spriteNamingScheme); CreateSprites(animationSheet, job); job.SetProgress(0.6f); if (job.createUnityAnimations) { CreateAnimations(animationSheet, job); job.SetProgress(0.8f); if (job.importAnimatorController == ImportAnimatorController.AnimatorController) { CreateAnimatorController(animationSheet); } else if (job.importAnimatorController == ImportAnimatorController.AnimatorOverrideController) { CreateAnimatorOverrideController(animationSheet, job.useExistingAnimatorController); } } } return(animationSheet); }
private void CreateAnimations(ImportedAnimationSheet animationSheet) { string imageAssetFilename = GetImageAssetFilename(animationSheet.basePath, animationSheet.name); if (animationSheet.hasAnimations) { if (sharedData.saveAnimationsToSubfolder) { string path = animationSheet.basePath + "/Animations"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } CreateAnimationAssets(animationSheet, imageAssetFilename, path); } else { CreateAnimationAssets(animationSheet, imageAssetFilename, animationSheet.basePath); } } }
public void CreateAnimatorController(ImportedAnimationSheet animations) { AnimatorController controller; // check if controller already exists; use this to not loose any references to this in other assets string pathForAnimatorController = animations.basePath + "/" + animations.name + ".controller"; controller = AssetDatabase.LoadAssetAtPath <AnimatorController>(pathForAnimatorController); if (controller == null) { // create a new controller and place every animation as a state on the first layer controller = AnimatorController.CreateAnimatorControllerAtPath(animations.basePath + "/" + animations.name + ".controller"); controller.AddLayer("Default"); foreach (var animation in animations.animations) { AnimatorState state = controller.layers[0].stateMachine.AddState(animation.name); state.motion = animation.animationClip; } } else { // look at all states on the first layer and replace clip if state has the same name var childStates = controller.layers[0].stateMachine.states; foreach (var childState in childStates) { AnimationClip clip = animations.GetClip(childState.state.name); if (clip != null) { childState.state.motion = clip; } } } EditorUtility.SetDirty(controller); AssetDatabase.SaveAssets(); }
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); animationSheet.animations.Add(anim); } return(true); }
private void CreateAnimatorOverrideController(ImportedAnimationSheet animations, AnimationImportJob job) { AnimatorOverrideController overrideController; string directory = sharedData.animationControllersTargetLocation.GetAndEnsureTargetDirectory(job.assetPath); string pathForOverrideController; // check if override controller already exists; use this to not loose any references to this in other assets if (sharedData.namingScheme == NamingScheme.ItsName) { pathForOverrideController = $"{directory}/animatorController.overrideController"; } else { pathForOverrideController = $"{directory}/{animations.name}.overrideController"; } overrideController = AssetDatabase.LoadAssetAtPath <AnimatorOverrideController>(pathForOverrideController); RuntimeAnimatorController baseController = _baseController; if (job.useExistingAnimatorController && overrideController.runtimeAnimatorController != null) { baseController = overrideController.runtimeAnimatorController; } if (baseController != null) { if (overrideController == null) { overrideController = new AnimatorOverrideController(); AssetDatabase.CreateAsset(overrideController, pathForOverrideController); } overrideController.runtimeAnimatorController = baseController; // set override clips #if UNITY_5_6_OR_NEWER var clipPairs = new List <KeyValuePair <AnimationClip, AnimationClip> >(overrideController.overridesCount); overrideController.GetOverrides(clipPairs); foreach (var pair in clipPairs) { string animationName = pair.Key.name; AnimationClip clip = animations.GetClipOrSimilar(animationName); overrideController[animationName] = clip; } #else var clipPairs = overrideController.clips; for (int i = 0; i < clipPairs.Length; i++) { string animationName = clipPairs[i].originalClip.name; AnimationClip clip = animations.GetClipOrSimilar(animationName); clipPairs[i].overrideClip = clip; } overrideController.clips = clipPairs; #endif EditorUtility.SetDirty(overrideController); } else { Debug.LogWarning("No Animator Controller found as a base for the Override Controller"); } }
private void CreateAnimatorOverrideController(ImportedAnimationSheet animations, bool useExistingBaseController = false) { AnimatorOverrideController overrideController; string directory = sharedData.animationControllersTargetLocation.GetAndEnsureTargetDirectory(animations.assetDirectory); // attempt to ignore characters in master name after _ character string newName = animations.name.Split('_')[0]; ///NOTE - DDobyns experiment to fix animation naming issues ///string fileName = basePath + "/" + masterName + "_" + anim.name + ".anim"; // original behavior is this line //string fileName = directory + "/" + newName + "_" + anim.name + ".anim"; // DDobyns fix is this line // check if override controller already exists; use this to not loose any references to this in other assets //string pathForOverrideController = directory + "/" + animations.name + ".overrideController"; string pathForOverrideController = directory + "/" + newName + ".overrideController"; overrideController = AssetDatabase.LoadAssetAtPath <AnimatorOverrideController>(pathForOverrideController); RuntimeAnimatorController baseController = _baseController; if (useExistingBaseController && overrideController.runtimeAnimatorController != null) { baseController = overrideController.runtimeAnimatorController; } if (baseController != null) { if (overrideController == null) { overrideController = new AnimatorOverrideController(); AssetDatabase.CreateAsset(overrideController, pathForOverrideController); } overrideController.runtimeAnimatorController = baseController; // set override clips #if UNITY_5_6_OR_NEWER var clipPairs = new List <KeyValuePair <AnimationClip, AnimationClip> >(overrideController.overridesCount); overrideController.GetOverrides(clipPairs); foreach (var pair in clipPairs) { string animationName = pair.Key.name; AnimationClip clip = animations.GetClipOrSimilar(animationName); if (clip != null) { overrideController[animationName] = clip; } } #else var clipPairs = overrideController.clips; for (int i = 0; i < clipPairs.Length; i++) { string animationName = clipPairs[i].originalClip.name; AnimationClip clip = animations.GetClipOrSimilar(animationName); clipPairs[i].overrideClip = clip; } overrideController.clips = clipPairs; #endif EditorUtility.SetDirty(overrideController); } else { Debug.LogWarning("No Animator Controller found as a base for the Override Controller"); } }
private void CreateSprites(ImportedAnimationSheet animationSheet, AnimationImportJob job) { if (animationSheet == null) { return; } var spriteInfos = new List <NamedSpriteInfo>(); animationSheet.CreateSpriteInfos( in sharedData.customPivotSettings, spriteInfos ); var siMap = new Dictionary <uint, NamedSpriteInfo>(); var nameMap = new Dictionary <string, string>(); var outputTexs = new Dictionary <Texture2D, SpriteMetaData[]>(); if (sharedData.doTrim) { var srcTex = animationSheet.srcTex; if (srcTex == null) { return; //? } var trimIndexList = new List <uint>(); for (int i = 0; i < spriteInfos.Count; ++i) { job.SetProgress(0.4f + i / (10.0f * spriteInfos.Count), "trimming sprite " + i.ToString()); var trimmed = spriteInfos[i].info.Trim(sharedData.trimColor, sharedData.trimMargin.x, sharedData.trimMargin.y); var trimmedCrc = trimmed.GetCrc32(); if (!siMap.ContainsKey(trimmedCrc)) { siMap[trimmedCrc] = new NamedSpriteInfo { name = spriteInfos[i].name, info = trimmed, }; trimIndexList.Add(trimmedCrc); } nameMap[spriteInfos[i].name] = siMap[trimmedCrc].name; } trimIndexList.Sort((lhsi, rhsi) => { var lhs = siMap[lhsi].info.frame; var rhs = siMap[rhsi].info.frame; if (lhs.width == rhs.width) { return(lhs.height - rhs.height); } return(rhs.width - lhs.width); // return (rhs.width + rhs.height) - (lhs.width + lhs.height); }); var boxs = new Luxko.Geometry.SkylinePacker.Box[trimIndexList.Count]; for (int i = 0; i < trimIndexList.Count; ++i) { var spriteInfo = siMap[trimIndexList[i]].info; boxs[i].w = spriteInfo.frame.width + sharedData.trimSpacing.x; boxs[i].h = spriteInfo.frame.height + sharedData.trimSpacing.y; } job.SetProgress(0.5f, "caculate packing info"); var packOutput = new Luxko.Geometry.SkylinePacker.Output[trimIndexList.Count]; var packBin = new Luxko.Geometry.SkylinePacker.Box { w = sharedData.trimTexSize.x, h = sharedData.trimTexSize.y }; var sky = new Luxko.Geometry.SkylinePacker.Sky(packBin, sharedData.PackSpreadFactor > 0 ? sharedData.PackSpreadFactor : (int)(packBin.h * 0.75f), boxs); for (int i = 0; i < boxs.Length; ++i) { sky.PackNext(out packOutput[i]); } var sheetBuf = new List <KeyValuePair <Texture2D, List <SpriteMetaData> > >(); for (int i = 0; i < packOutput.Length; ++i) { while (sheetBuf.Count <= packOutput[i].binIndex) { var newTex = new Texture2D(sharedData.trimTexSize.x, sharedData.trimTexSize.y, TextureFormat.RGBA32, false); // TODO: proper linear flag ClearTexture(newTex, Color.clear); sheetBuf.Add(new KeyValuePair <Texture2D, List <SpriteMetaData> >( newTex, new List <SpriteMetaData>() )); } var tSheet = sheetBuf[packOutput[i].binIndex]; var ti = new SpritePacker.SpriteInfo { tex = tSheet.Key, frame = new RectInt(packOutput[i].pos.x, packOutput[i].pos.y, 0, 0) }; var tis = siMap[trimIndexList[packOutput[i].boxIndex]]; job.SetProgress(0.55f + i / (20.0f * trimIndexList.Count), string.Format("packing {0} at {1} to {2}", tis.name, tis.info.frame, ti.frame.position)); tis.info.TryCopyTo(ref ti); tSheet.Value.Add(new SpriteMetaData { name = tis.name, rect = new Rect(ti.frame.x, ti.frame.y, ti.frame.width, ti.frame.height), alignment = (int)SpriteAlignment.Custom, pivot = ti.pivotN, }); } foreach (var kv in sheetBuf) { outputTexs.Add(kv.Key, kv.Value.ToArray()); } Texture2D.DestroyImmediate(srcTex, true); } else { var targetTex = animationSheet.srcTex; if (spriteInfos.Count > 0) { var smds = new SpriteMetaData[spriteInfos.Count]; for (int si = 0; si < spriteInfos.Count; ++si) { smds[si] = new SpriteMetaData { name = spriteInfos[si].name, rect = new Rect(spriteInfos[si].info.frame.x, spriteInfos[si].info.frame.y, spriteInfos[si].info.frame.width, spriteInfos[si].info.frame.height), alignment = (int)SpriteAlignment.Custom, pivot = spriteInfos[si].info.pivotN, }; } outputTexs.Add(targetTex, smds); spriteInfos.Clear(); } } int kvi = 0; var spriteDict = new Dictionary <string, Sprite>(); foreach (var kv in outputTexs) { job.SetProgress(0.6f + 0.1f * (kvi / (float)outputTexs.Count), "saving textures " + kvi); string imgPath; if (kvi <= 0) { imgPath = string.Format("{0}/{1}.png", job.directoryPathForSprites, job.name); } else { imgPath = string.Format("{0}/{1}_{2}.png", job.directoryPathForSprites, job.name, kvi); } kvi++; SaveAsPng(kv.Key, imgPath); AssetDatabase.Refresh(); AssetDatabase.ImportAsset(imgPath, ImportAssetOptions.ForceUpdate); var importer = AssetImporter.GetAtPath(imgPath) as TextureImporter; importer.textureType = TextureImporterType.Sprite; importer.spritePixelsPerUnit = sharedData.spritePixelsPerUnit; importer.mipmapEnabled = false; importer.filterMode = FilterMode.Point; importer.textureCompression = TextureImporterCompression.Uncompressed; // TODO: smart update: how to keep old references alive? importer.spritesheet = kv.Value; importer.spriteImportMode = SpriteImportMode.Multiple; importer.maxTextureSize = 2048; importer.textureCompression = TextureImporterCompression.CompressedHQ; EditorUtility.SetDirty(importer); importer.SaveAndReimport(); AssetDatabase.ImportAsset(imgPath, ImportAssetOptions.ForceUpdate); var assets = AssetDatabase.LoadAllAssetsAtPath(imgPath); foreach (var item in assets) { if (item is Sprite) { var sprite = (Sprite)item; spriteDict[sprite.name] = sprite; } } } if (nameMap.Count != 0) { var replaceMap = new Dictionary <string, Sprite>(); foreach (var kv in nameMap) { replaceMap[kv.Key] = spriteDict[kv.Value]; } spriteDict = replaceMap; } foreach (var kv in outputTexs) { Texture2D.DestroyImmediate(kv.Key); } outputTexs.Clear(); animationSheet.ApplyCreatedSprites(spriteDict); }