public AseFileAnimationSettings[] GetAnimationImportSettings()
        {
            List <AseFileAnimationSettings> animationSettings = new List <AseFileAnimationSettings>();

            FrameTag[] frameTags = aseFile.GetAnimations();

            foreach (var frameTag in frameTags)
            {
                int frames = frameTag.FrameTo - frameTag.FrameFrom + 1;

                AseFileAnimationSettings setting = new AseFileAnimationSettings(frameTag.TagName)
                {
                    about        = GetAnimationAbout(frameTag),
                    loopTime     = true,
                    sprites      = new Sprite[frames],
                    frameNumbers = new int[frames]
                };

                int frameFrom = frameTag.FrameFrom;
                int frameTo   = frameTag.FrameTo;
                int step      = (frameTag.Animation != LoopAnimation.Reverse) ? 1 : -1;

                int frameIndex = frameFrom;
                int i          = 0;
                while (frameIndex != frameTo)
                {
                    setting.frameNumbers[i] = frameIndex;
                    frameIndex += step;
                    ++i;
                }

                setting.frameNumbers[i] = frameTo;

                animationSettings.Add(setting);
            }

            return(animationSettings.ToArray());
        }
        private void DrawAnimationSetting(SerializedProperty animationSettingProperty,
                                          AseFileAnimationSettings animationSetting)
        {
            string animationName = animationSettingProperty.FindPropertyRelative("animationName").stringValue;

            if (animationName == null)
            {
                return;
            }



            if (!foldoutStates.ContainsKey(animationName))
            {
                foldoutStates.Add(animationName, false);
            }

            EditorGUILayout.BeginVertical(GUI.skin.box);
            EditorGUI.indentLevel++;

            GUIStyle  foldoutStyle      = EditorStyles.foldout;
            FontStyle prevoiusFontStyle = foldoutStyle.fontStyle;

            foldoutStyle.fontStyle = FontStyle.Bold;

            var content = new GUIContent();

            content.text = animationName;

            if (animationSetting.HasInvalidSprites)
            {
                content.image = EditorGUIUtility.IconContent("console.warnicon.sml").image;
            }


            if (foldoutStates[animationName] = EditorGUILayout.Foldout(foldoutStates[animationName],
                                                                       content, true, foldoutStyle))
            {
                if (animationSetting.HasInvalidSprites)
                {
                    EditorGUILayout.HelpBox(
                        $"The animation '{animationName}' will not be imported.\nSome sprites are missing.",
                        MessageType.Warning);
                }


                EditorGUILayout.PropertyField(animationSettingProperty.FindPropertyRelative("loopTime"));
                EditorGUILayout.HelpBox(animationSettingProperty.FindPropertyRelative("about").stringValue,
                                        MessageType.None);

                SerializedProperty sprites      = animationSettingProperty.FindPropertyRelative("sprites");
                SerializedProperty frameNumbers = animationSettingProperty.FindPropertyRelative("frameNumbers");

                for (int i = 0; i < sprites.arraySize; i++)
                {
                    EditorGUILayout.PropertyField(sprites.GetArrayElementAtIndex(i),
                                                  new GUIContent("Frame #" + frameNumbers.GetArrayElementAtIndex(i).intValue));
                }
            }

            foldoutStyle.fontStyle = prevoiusFontStyle;

            EditorGUI.indentLevel--;
            EditorGUILayout.EndVertical();
        }
        public AnimationClip[] GenerateAnimations(string parentName, AseFileAnimationSettings[] animationSettings)
        {
            var animations = aseFile.GetAnimations();

            if (animations.Length <= 0)
            {
                return(new AnimationClip[0]);
            }

            AnimationClip[] animationClips = new AnimationClip[animations.Length];

            int index = 0;

            foreach (var animation in animations)
            {
                AseFileAnimationSettings importSettings = GetAnimationSettingFor(animationSettings, animation);
                if (importSettings == null)
                {
                    continue;
                }

                if (importSettings.HasInvalidSprites)
                {
                    continue;
                }

                AnimationClip animationClip = new AnimationClip
                {
                    name      = parentName + "_" + animation.TagName,
                    frameRate = 25
                };

                EditorCurveBinding spriteBinding = new EditorCurveBinding
                {
                    type         = typeof(SpriteRenderer),
                    path         = "",
                    propertyName = "m_Sprite"
                };


                int length = animation.FrameTo - animation.FrameFrom + 1;
                ObjectReferenceKeyframe[]
                spriteKeyFrames = new ObjectReferenceKeyframe[length + 1];     // plus last frame to keep the duration

                float time = 0;

                int from = (animation.Animation != LoopAnimation.Reverse) ? animation.FrameFrom : animation.FrameTo;
                int step = (animation.Animation != LoopAnimation.Reverse) ? 1 : -1;

                int keyIndex = from;

                for (int i = 0; i < length; i++)
                {
                    if (i >= length)
                    {
                        keyIndex = from;
                    }

                    ObjectReferenceKeyframe frame = new ObjectReferenceKeyframe
                    {
                        time  = time,
                        value = importSettings.sprites[i]
                    };

                    time += aseFile.Frames[keyIndex].FrameDuration / 1000f;

                    keyIndex          += step;
                    spriteKeyFrames[i] = frame;
                }

                float frameTime = 1f / animationClip.frameRate;

                ObjectReferenceKeyframe lastFrame = new ObjectReferenceKeyframe
                {
                    time  = time - frameTime,
                    value = importSettings.sprites[length - 1]
                };

                spriteKeyFrames[spriteKeyFrames.Length - 1] = lastFrame;


                AnimationUtility.SetObjectReferenceCurve(animationClip, spriteBinding, spriteKeyFrames);
                AnimationClipSettings settings = AnimationUtility.GetAnimationClipSettings(animationClip);

                switch (animation.Animation)
                {
                case LoopAnimation.Forward:
                    animationClip.wrapMode = WrapMode.Loop;
                    settings.loopTime      = true;
                    break;

                case LoopAnimation.Reverse:
                    animationClip.wrapMode = WrapMode.Loop;
                    settings.loopTime      = true;
                    break;

                case LoopAnimation.PingPong:
                    animationClip.wrapMode = WrapMode.PingPong;
                    settings.loopTime      = true;
                    break;
                }

                if (!importSettings.loopTime)
                {
                    animationClip.wrapMode = WrapMode.Once;
                    settings.loopTime      = false;
                }

                AnimationUtility.SetAnimationClipSettings(animationClip, settings);
                animationClips[index] = animationClip;

                index++;
            }

            return(animationClips);
        }