// ================================================================================
        //  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);
            }
        }
Beispiel #2
0
        // ================================================================================
        //  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();
        }
Beispiel #3
0
        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");
            }
        }
Beispiel #5
0
        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);
            }
        }
Beispiel #6
0
        // ================================================================================
        //  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);
        }
Beispiel #8
0
        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);
                }
            }
        }
Beispiel #9
0
        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();
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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");
            }
        }
Beispiel #12
0
        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);
        }