private void CreateAnimatorOverrideController(AsepriteAnimationInfo animations)
        {
            if (_baseController != null)
            {
                AnimatorOverrideController overrideController;

                // check if override controller already exists; use this to not loose any references to this in other assets
                string pathForOverrideController = animations.basePath + "/" + animations.name + ".overrideController";
                overrideController = AssetDatabase.LoadAssetAtPath <AnimatorOverrideController>(pathForOverrideController);

                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.GetClip(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");
            }
        }
        // ================================================================================
        //  public static methods
        // --------------------------------------------------------------------------------

        public static AsepriteAnimationInfo GetAnimationInfo(JSONObject root)
        {
            AsepriteAnimationInfo importedInfos = new AsepriteAnimationInfo();

            // meta animations

            var meta = root["meta"].Obj;

            var size = meta["size"].Obj;

            importedInfos.width  = (int)size["w"].Number;
            importedInfos.height = (int)size["h"].Number;

            var frameTags = meta["frameTags"].Array;

            foreach (var item in frameTags)
            {
                JSONObject        frameTag = item.Obj;
                AsepriteAnimation anim     = new AsepriteAnimation();
                anim.name = frameTag["name"].Str;
                anim.from = (int)(frameTag["from"].Number);
                anim.to   = (int)(frameTag["to"].Number);

                importedInfos.animations.Add(anim);
            }

            // sprites

            var list = root["frames"].Array;

            foreach (var item in list)
            {
                AsepriteFrame frame = new AsepriteFrame();
                frame.filename = item.Obj["filename"].Str;

                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      = importedInfos.height - (int)frameValues["y"].Number - frame.height;            // unity has a different coord system

                frame.duration = (int)item.Obj["duration"].Number;

                importedInfos.frames.Add(frame);
            }

            importedInfos.CalculateTimings();

            return(importedInfos);
        }
        private AsepriteAnimationInfo ImportJSONAndCreateAnimations(string basePath, string name)
        {
            string imagePath = basePath;

            if (_saveSpritesToSubfolder)
            {
                imagePath += "/Sprites";
            }

            string    imageAssetFilename = imagePath + "/" + name + ".png";
            string    textAssetFilename  = imagePath + "/" + name + ".json";
            TextAsset textAsset          = AssetDatabase.LoadAssetAtPath <TextAsset>(textAssetFilename);

            if (textAsset != null)
            {
                // parse the JSON file
                JSONObject            jsonObject = JSONObject.Parse(textAsset.ToString());
                AsepriteAnimationInfo animations = AsepriteAnimationInfo.GetAnimationInfo(jsonObject);
                animations.basePath             = basePath;
                animations.name                 = name;
                animations.nonLoopingAnimations = _animationNamesThatDoNotLoop;
                AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(textAsset)); // delete JSON file afterwards

                CreateSprites(imageAssetFilename, animations);

                if (_saveAnimationsToSubfolder)
                {
                    string path = basePath + "/Animations";
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path);
                    }

                    CreateAnimations(imageAssetFilename, path, animations);
                }
                else
                {
                    CreateAnimations(imageAssetFilename, basePath, animations);
                }

                return(animations);
            }
            else
            {
                Debug.LogWarning("Problem with JSON file: " + textAssetFilename);
            }

            return(null);
        }
		// ================================================================================
		//  public static methods
		// --------------------------------------------------------------------------------

		public static AsepriteAnimationInfo GetAnimationInfo(JSONObject root)
		{
			AsepriteAnimationInfo importedInfos = new AsepriteAnimationInfo();

			// meta animations

			var meta = root["meta"].Obj;

			var size = meta["size"].Obj;
			importedInfos.width = (int)size["w"].Number;
			importedInfos.height = (int)size["h"].Number;

			var frameTags = meta["frameTags"].Array;
			foreach (var item in frameTags)
			{
				JSONObject frameTag = item.Obj;
				AsepriteAnimation anim = new AsepriteAnimation();
				anim.name = frameTag["name"].Str;
				anim.from = (int)(frameTag["from"].Number);
				anim.to = (int)(frameTag["to"].Number);

				importedInfos.animations.Add(anim);
			}

			// sprites

			var list = root["frames"].Array;
			foreach (var item in list)
			{
				AsepriteFrame frame = new AsepriteFrame();
				frame.filename = item.Obj["filename"].Str;

				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 = importedInfos.height - (int)frameValues["y"].Number - frame.height; // unity has a different coord system

				frame.duration = (int)item.Obj["duration"].Number;

				importedInfos.frames.Add(frame);
			}

			importedInfos.CalculateTimings();

			return importedInfos;
		}
        private void CreateSprites(string imageFile, AsepriteAnimationInfo animations)
        {
            TextureImporter importer = AssetImporter.GetAtPath(imageFile) as TextureImporter;

            // adjust values for pixel art
            importer.spriteImportMode    = SpriteImportMode.Multiple;
            importer.spritePixelsPerUnit = _spritePixelsPerUnit;
            importer.mipmapEnabled       = false;
            importer.filterMode          = FilterMode.Point;
            importer.textureFormat       = TextureImporterFormat.AutomaticTruecolor;
            importer.maxTextureSize      = animations.maxTextureSize;

            // create sub sprites for this file
            importer.spritesheet = animations.GetSpriteSheet(_spriteAlignment, _spriteAlignmentCustomX, _spriteAlignmentCustomY);

            EditorUtility.SetDirty(importer);
            importer.SaveAndReimport();

            AssetDatabase.ImportAsset(imageFile, ImportAssetOptions.ForceUpdate);
        }
        private void CreateAnimatorController(AsepriteAnimationInfo animations)
        {
            AnimatorController controller;

            // check if controller already exists; use this to not loose any references to this in other assets
            string pathForOverrideController = animations.basePath + "/" + animations.name + ".controller";

            controller = AssetDatabase.LoadAssetAtPath <AnimatorController>(pathForOverrideController);

            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 void CreateAnimations(string imageAssetFilename, string animationsPath, AsepriteAnimationInfo animationInfo)
        {
            string masterName = Path.GetFileNameWithoutExtension(imageAssetFilename);

            var           assets  = AssetDatabase.LoadAllAssetsAtPath(imageAssetFilename);
            List <Sprite> sprites = new List <Sprite>();

            foreach (var item in assets)
            {
                if (item is Sprite)
                {
                    sprites.Add(item as Sprite);
                }
            }

            foreach (var animation in animationInfo.animations)
            {
                animationInfo.CreateAnimation(animationsPath, masterName, animation, sprites);
            }
        }