text:
// Author: Daniele Giardini - http://www.demigiant.com
// Created: 2015/03/12 16:03

using System.Collections.Generic;
using DG.DemiEditor;
using DG.DemiLib;
using DG.Tweening;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using Object = UnityEngine.Object;

namespace DG.DOTweenEditor
{
    public static class DOTweenPreviewManager
    {
        static bool _previewOnlyIfSetToAutoPlay = true;
        static readonly Dictionary<DOTweenAnimation,TweenInfo> _AnimationToTween = new Dictionary<DOTweenAnimation,TweenInfo>();
        static readonly List<DOTweenAnimation> _TmpKeys = new List<DOTweenAnimation>();

        #region Public Methods & GUI

        ///
        /// Returns TRUE if its actually previewing animations
        ///
        public static bool PreviewGUI(DOTweenAnimation src)
        {
            if (EditorApplication.isPlaying) return false;

            Styles.Init();

            bool isPreviewing = _AnimationToTween.Count > 0;
            bool isPreviewingThis = isPreviewing && _AnimationToTween.ContainsKey(src);

            // Preview in editor
            GUI.backgroundColor = isPreviewing
                ? new DeSkinColor(new Color(0.49f, 0.8f, 0.86f), new Color(0.15f, 0.26f, 0.35f))
                : new DeSkinColor(Color.white, new Color(0.13f, 0.13f, 0.13f));
            GUILayout.BeginVertical(Styles.previewBox);
            DeGUI.ResetGUIColors();
            GUILayout.BeginHorizontal();
            GUILayout.Label("Preview Mode - Experimental", Styles.previewLabel);
            _previewOnlyIfSetToAutoPlay = DeGUILayout.ToggleButton(
                _previewOnlyIfSetToAutoPlay,
                new GUIContent("AutoPlay only", "If toggled only previews animations that have AutoPlay turned ON"),
                Styles.btOption
            );
            GUILayout.EndHorizontal();
            GUILayout.Space(1);
            // Preview - Play
            GUILayout.BeginHorizontal();
            EditorGUI.BeginDisabledGroup(
                isPreviewingThis || src.animationType == DOTweenAnimation.AnimationType.None
                || !src.isActive || _previewOnlyIfSetToAutoPlay && !src.autoPlay
            );
            if (GUILayout.Button("► Play", Styles.btPreview)) {
                if (!isPreviewing) StartupGlobalPreview();
                AddAnimationToGlobalPreview(src);
            }
            EditorGUI.EndDisabledGroup();
            EditorGUI.BeginDisabledGroup(isPreviewing);
            if (GUILayout.Button("► Play All on GameObject", Styles.btPreview)) {
                if (!isPreviewing) StartupGlobalPreview();
                DOTweenAnimation[] anims = src.gameObject.GetComponents<DOTweenAnimation>();
                foreach (DOTweenAnimation anim in anims) AddAnimationToGlobalPreview(anim);
            }
            if (GUILayout.Button("► Play All in Scene", Styles.btPreview)) {
                if (!isPreviewing) StartupGlobalPreview();
                DOTweenAnimation[] anims = Object.FindObjectsOfType<DOTweenAnimation>();
                foreach (DOTweenAnimation anim in anims) AddAnimationToGlobalPreview(anim);
            }
            EditorGUI.EndDisabledGroup();
            GUILayout.EndHorizontal();
            // Preview - Stop
            GUILayout.BeginHorizontal();
            EditorGUI.BeginDisabledGroup(!isPreviewingThis);
            if (GUILayout.Button("■ Stop", Styles.btPreview)) {
                if (_AnimationToTween.ContainsKey(src)) StopPreview(_AnimationToTween[src].tween);
            }
            EditorGUI.EndDisabledGroup();
            EditorGUI.BeginDisabledGroup(!isPreviewing);
            if (GUILayout.Button("■ Stop All on GameObject", Styles.btPreview)) {
                StopPreview(src.gameObject);
            }
            if (GUILayout.Button("■ Stop All in Scene", Styles.btPreview)) {
                StopAllPreviews();
            }
            EditorGUI.EndDisabledGroup();
            GUILayout.EndHorizontal();
            if (isPreviewing) {
                int playingTweens = 0;
                int completedTweens = 0;
                int pausedTweens = 0;
                foreach (KeyValuePair<DOTweenAnimation, TweenInfo> kvp in _AnimationToTween) {
                    Tween t = kvp.Value.tween;
                    if (t.IsPlaying()) playingTweens++;
                    else if (t.IsComplete()) completedTweens++;
                    else pausedTweens++;
                }
                GUILayout.Label("Playing Tweens: " + playingTweens, Styles.previewStatusLabel);
                GUILayout.Label("Completed Tweens: " + completedTweens, Styles.previewStatusLabel);
//                GUILayout.Label("Paused Tweens: " + playingTweens);
            }
            GUILayout.EndVertical();

            return isPreviewing;
        }

#if !(UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_5)
        public static void StopAllPreviews(PlayModeStateChange state)
        {
            StopAllPreviews();
        }
#endif

        public static void StopAllPreviews()
        {
            _TmpKeys.Clear();
            foreach (KeyValuePair<DOTweenAnimation,TweenInfo> kvp in _AnimationToTween) {
                _TmpKeys.Add(kvp.Key);
            }
            StopPreview(_TmpKeys);
            _TmpKeys.Clear();
            _AnimationToTween.Clear();

            DOTweenEditorPreview.Stop();
#if UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_5
            UnityEditor.EditorApplication.playmodeStateChanged -= StopAllPreviews;
#else
            UnityEditor.EditorApplication.playModeStateChanged -= StopAllPreviews;
#endif
//            EditorApplication.playmodeStateChanged -= StopAllPreviews;

            InternalEditorUtility.RepaintAllViews();
        }

#endregion

#region Methods

        static void StartupGlobalPreview()
        {
            DOTweenEditorPreview.Start();
#if UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_5
            UnityEditor.EditorApplication.playmodeStateChanged += StopAllPreviews;
#else
            UnityEditor.EditorApplication.playModeStateChanged += StopAllPreviews;
#endif
//            EditorApplication.playmodeStateChanged += StopAllPreviews;
        }

        static void AddAnimationToGlobalPreview(DOTweenAnimation src)
        {
            if (!src.isActive) return; // Ignore sources whose tweens have been set to inactive
            if (_previewOnlyIfSetToAutoPlay && !src.autoPlay) return;

            Tween t = src.CreateEditorPreview();
            _AnimationToTween.Add(src, new TweenInfo(src, t, src.isFrom));
            // Tween setup
            DOTweenEditorPreview.PrepareTweenForPreview(t);
        }

        static void StopPreview(GameObject go)
        {
            _TmpKeys.Clear();
            foreach (KeyValuePair<DOTweenAnimation,TweenInfo> kvp in _AnimationToTween) {
                if (kvp.Key.gameObject != go) continue;
                _TmpKeys.Add(kvp.Key);
            }
            StopPreview(_TmpKeys);
            _TmpKeys.Clear();

            if (_AnimationToTween.Count == 0) StopAllPreviews();
            else InternalEditorUtility.RepaintAllViews();
        }

        static void StopPreview(Tween t)
        {
            TweenInfo tInfo = null;
            foreach (KeyValuePair<DOTweenAnimation,TweenInfo> kvp in _AnimationToTween) {
                if (kvp.Value.tween != t) continue;
                tInfo = kvp.Value;
                _AnimationToTween.Remove(kvp.Key);
                break;
            }
            if (tInfo == null) {
                Debug.LogWarning("DOTween Preview ► Couldn't find tween to stop");
                return;
            }
            if (tInfo.isFrom) {
                int totLoops = tInfo.tween.Loops();
                if (totLoops < 0 || totLoops > 1) {
                    tInfo.tween.Goto(tInfo.tween.Duration(false));
                } else tInfo.tween.Complete();
            } else tInfo.tween.Rewind();
            tInfo.tween.Kill();
            EditorUtility.SetDirty(tInfo.animation); // Init views

            if (_AnimationToTween.Count == 0) StopAllPreviews();
            else InternalEditorUtility.RepaintAllViews();
        }

        // Stops while iterating inversely, which deals better with tweens that overwrite each other
        static void StopPreview(List<DOTweenAnimation> keys)
        {
            for (int i = keys.Count - 1; i > -1; --i) {
                DOTweenAnimation anim = keys[i];
                TweenInfo tInfo = _AnimationToTween[anim];
                if (tInfo.isFrom) {
                    int totLoops = tInfo.tween.Loops();
                    if (totLoops < 0 || totLoops > 1) {
                        tInfo.tween.Goto(tInfo.tween.Duration(false));
                    } else tInfo.tween.Complete();
                } else tInfo.tween.Rewind();
                tInfo.tween.Kill();
                EditorUtility.SetDirty(anim); // Init views
                _AnimationToTween.Remove(anim);
            }
        }

#endregion

        // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
        // ███ INTERNAL CLASSES ████████████████████████████████████████████████████████████████████████████████████████████████
        // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████

        class TweenInfo
        {
            public DOTweenAnimation animation;
            public Tween tween;
            public bool isFrom;
            public TweenInfo(DOTweenAnimation animation, Tween tween, bool isFrom)
            {
                this.animation = animation;
                this.tween = tween;
                this.isFrom = isFrom;
            }
        }

        static class Styles
        {
            static bool _initialized;

            public static GUIStyle previewBox, previewLabel, btOption, btPreview, previewStatusLabel;

            public static void Init()
            {
                if (_initialized) return;

                _initialized = true;

                previewBox = new GUIStyle(GUI.skin.box).Clone().Padding(1, 1, 0, 3)
                    .Background(DeStylePalette.squareBorderCurved_darkBorders).Border(7, 7, 7, 7);
                previewLabel = new GUIStyle(GUI.skin.label).Clone(10, FontStyle.Bold).Padding(1, 0, 3, 0).Margin(3, 6, 0, 0).StretchWidth(false);
                btOption = DeGUI.styles.button.bBlankBorderCompact.MarginBottom(2).MarginRight(4);
                btPreview = EditorStyles.miniButton.Clone(Format.RichText);
                previewStatusLabel = EditorStyles.miniLabel.Clone().Padding(4, 0, 0, 0).Margin(0);
            }
        }
    }
}


text:
fileFormatVersion: 2
guid: ee3a420017f129443896310d9fab256b
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:

mime_type: text/plain


text:
fileFormatVersion: 2
guid: e0203fd81362bab4d842d87ad09ee76e
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
<?xml version="1.0"?>
<doc>
    <assembly>
        <name>DOTweenProEditor</name>
    </assembly>
    <members>
        <member name="T:DG.DOTweenEditor.Core.ColorPalette.Custom">
            <summary>
            Custom colors
            </summary>
        </member>
        <member name="M:DG.DOTweenEditor.Core.StylePalette.Custom.Init">
            <summary>
            Needs to be overridden in order to initialize new styles added from inherited classes
            </summary>
        </member>
    </members>
</doc>


text:
fileFormatVersion: 2
guid: 22292a5f27a9a644ba9e6ad1bf863531
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
// Author: Daniele Giardini - http://www.demigiant.com
// Created: 2015/03/12 16:03

using System;
using System.Collections.Generic;
using DG.DemiEditor;
using DG.DOTweenEditor.Core;
using DG.DOTweenEditor.UI;
using DG.Tweening;
using UnityEditor;
using UnityEngine;
using DOTweenSettings = DG.Tweening.Core.DOTweenSettings;
#if true // UI_MARKER
using UnityEngine.UI;
#endif
#if false // TEXTMESHPRO_MARKER
    using TMPro;
#endif

namespace DG.DOTweenEditor
{
    [CustomEditor(typeof(DOTweenAnimation))]
    public class DOTweenAnimationInspector : ABSAnimationInspector
    {
        enum FadeTargetType
        {
            CanvasGroup,
            Image
        }

        enum ChooseTargetMode
        {
            None,
            BetweenCanvasGroupAndImage
        }

        static readonly Dictionary<DOTweenAnimation.AnimationType, Type[]> _AnimationTypeToComponent = new Dictionary<DOTweenAnimation.AnimationType, Type[]>() {
            { DOTweenAnimation.AnimationType.Move, new[] {
#if true // PHYSICS_MARKER
                typeof(Rigidbody),
#endif
#if true // PHYSICS2D_MARKER
                typeof(Rigidbody2D),
#endif
#if true // UI_MARKER
                typeof(RectTransform),
#endif
                typeof(Transform)
            }},
            { DOTweenAnimation.AnimationType.Rotate, new[] {
#if true // PHYSICS_MARKER
                typeof(Rigidbody),
#endif
#if true // PHYSICS2D_MARKER
                typeof(Rigidbody2D),
#endif
                typeof(Transform)
            }},
            { DOTweenAnimation.AnimationType.LocalMove, new[] { typeof(Transform) } },
            { DOTweenAnimation.AnimationType.LocalRotate, new[] { typeof(Transform) } },
            { DOTweenAnimation.AnimationType.Scale, new[] { typeof(Transform) } },
            { DOTweenAnimation.AnimationType.Color, new[] {
                typeof(Light),
#if true // SPRITE_MARKER
                typeof(SpriteRenderer),
#endif
#if true // UI_MARKER
                typeof(Image), typeof(Text), typeof(RawImage),
#endif
                typeof(Renderer),
            }},
            { DOTweenAnimation.AnimationType.Fade, new[] {
                typeof(Light),
#if true // SPRITE_MARKER
                typeof(SpriteRenderer),
#endif
#if true // UI_MARKER
                typeof(Image), typeof(Text), typeof(CanvasGroup), typeof(RawImage),
#endif
                typeof(Renderer),
            }},
#if true // UI_MARKER
            { DOTweenAnimation.AnimationType.Text, new[] { typeof(Text) } },
#endif
            { DOTweenAnimation.AnimationType.PunchPosition, new[] {
#if true // UI_MARKER
                typeof(RectTransform),
#endif
                typeof(Transform)
            }},
            { DOTweenAnimation.AnimationType.PunchRotation, new[] { typeof(Transform) } },
            { DOTweenAnimation.AnimationType.PunchScale, new[] { typeof(Transform) } },
            { DOTweenAnimation.AnimationType.ShakePosition, new[] {
#if true // UI_MARKER
                typeof(RectTransform),
#endif
                typeof(Transform)
            }},
            { DOTweenAnimation.AnimationType.ShakeRotation, new[] { typeof(Transform) } },
            { DOTweenAnimation.AnimationType.ShakeScale, new[] { typeof(Transform) } },
            { DOTweenAnimation.AnimationType.CameraAspect, new[] { typeof(Camera) } },
            { DOTweenAnimation.AnimationType.CameraBackgroundColor, new[] { typeof(Camera) } },
            { DOTweenAnimation.AnimationType.CameraFieldOfView, new[] { typeof(Camera) } },
            { DOTweenAnimation.AnimationType.CameraOrthoSize, new[] { typeof(Camera) } },
            { DOTweenAnimation.AnimationType.CameraPixelRect, new[] { typeof(Camera) } },
            { DOTweenAnimation.AnimationType.CameraRect, new[] { typeof(Camera) } },
#if true // UI_MARKER
            { DOTweenAnimation.AnimationType.UIWidthHeight, new[] { typeof(RectTransform) } },
#endif
        };

#if false // TK2D_MARKER
        static readonly Dictionary<DOTweenAnimation.AnimationType, Type[]> _Tk2dAnimationTypeToComponent = new Dictionary<DOTweenAnimation.AnimationType, Type[]>() {
            { DOTweenAnimation.AnimationType.Scale, new[] { typeof(tk2dBaseSprite), typeof(tk2dTextMesh) } },
            { DOTweenAnimation.AnimationType.Color, new[] { typeof(tk2dBaseSprite), typeof(tk2dTextMesh) } },
            { DOTweenAnimation.AnimationType.Fade, new[] { typeof(tk2dBaseSprite), typeof(tk2dTextMesh) } },
            { DOTweenAnimation.AnimationType.Text, new[] { typeof(tk2dTextMesh) } }
        };
#endif
#if false // TEXTMESHPRO_MARKER
        static readonly Dictionary<DOTweenAnimation.AnimationType, Type[]> _TMPAnimationTypeToComponent = new Dictionary<DOTweenAnimation.AnimationType, Type[]>() {
            { DOTweenAnimation.AnimationType.Color, new[] { typeof(TextMeshPro), typeof(TextMeshProUGUI) } },
            { DOTweenAnimation.AnimationType.Fade, new[] { typeof(TextMeshPro), typeof(TextMeshProUGUI) } },
            { DOTweenAnimation.AnimationType.Text, new[] { typeof(TextMeshPro), typeof(TextMeshProUGUI) } }
        };
#endif

        static readonly string[] _AnimationType = new[] {
            "None",
            "Move", "LocalMove",
            "Rotate", "LocalRotate",
            "Scale",
            "Color", "Fade",
#if true // UI_MARKER
            "Text",
#endif
#if false // TK2D_MARKER
            "Text",
#endif
#if false // TEXTMESHPRO_MARKER
            "Text",
#endif
#if true // UI_MARKER
            "UIWidthHeight",
#endif
            "Punch/Position", "Punch/Rotation", "Punch/Scale",
            "Shake/Position", "Shake/Rotation", "Shake/Scale",
            "Camera/Aspect", "Camera/BackgroundColor", "Camera/FieldOfView", "Camera/OrthoSize", "Camera/PixelRect", "Camera/Rect"
        };
        static string[] _animationTypeNoSlashes; // _AnimationType list without slashes in values
        static string[] _datString; // String representation of DOTweenAnimation enum (here for caching reasons)

        DOTweenAnimation _src;
        DOTweenSettings _settings;
        bool _runtimeEditMode; // If TRUE allows to change and save stuff at runtime
        bool _refreshRequired; // If TRUE refreshes components data
        int _totComponentsOnSrc; // Used to determine if a Component is added or removed from the source
        bool _isLightSrc; // Used to determine if we're tweening a Light, to set the max Fade value to more than 1
#pragma warning disable 414
        ChooseTargetMode _chooseTargetMode = ChooseTargetMode.None;
#pragma warning restore 414

        static readonly GUIContent _GuiC_selfTarget_true = new GUIContent(
            "SELF", "Will animate components on this gameObject"
        );
        static readonly GUIContent _GuiC_selfTarget_false = new GUIContent(
            "OTHER", "Will animate components on the given gameObject instead than on this one"
        );
        static readonly GUIContent _GuiC_tweenTargetIsTargetGO_true = new GUIContent(
            "Use As Tween Target", "Will set the tween inTarget (via SetTarget, used to control a tween directly from a inTarget) to the \"OTHER\" gameObject"
        );
        static readonly GUIContent _GuiC_tweenTargetIsTargetGO_false = new GUIContent(
            "Use As Tween Target", "Will set the tween inTarget (via SetTarget, used to control a tween directly from a inTarget) to the gameObject containing this animation, not the \"OTHER\" one"
        );

        #region MonoBehaviour Methods

        void OnEnable()
        {
            _src = target as DOTweenAnimation;
            _settings = DOTweenUtilityWindow.GetDOTweenSettings();

            onStartProperty = base.serializedObject.FindProperty("onStart");
            onPlayProperty = base.serializedObject.FindProperty("onPlay");
            onUpdateProperty = base.serializedObject.FindProperty("onUpdate");
            onStepCompleteProperty = base.serializedObject.FindProperty("onStepComplete");
            onCompleteProperty = base.serializedObject.FindProperty("onComplete");
            onRewindProperty = base.serializedObject.FindProperty("onRewind");
            onTweenCreatedProperty = base.serializedObject.FindProperty("onTweenCreated");

            // Convert _AnimationType to _animationTypeNoSlashes
            int len = _AnimationType.Length;
            _animationTypeNoSlashes = new string[len];
            for (int i = 0; i < len; ++i) {
                string a = _AnimationType[i];
                a = a.Replace("/", "");
                _animationTypeNoSlashes[i] = a;
            }
        }

        void OnDisable()
        {
            DOTweenPreviewManager.StopAllPreviews();
        }

        override public void OnInspectorGUI()
        {
        	base.OnInspectorGUI();

            GUILayout.Space(3);
            EditorGUIUtils.SetGUIStyles();

            bool playMode = Application.isPlaying;
            _runtimeEditMode = _runtimeEditMode && playMode;

            GUILayout.BeginHorizontal();
            EditorGUIUtils.InspectorLogo();
            GUILayout.Label(_src.animationType.ToString() + (string.IsNullOrEmpty(_src.id) ? "" : " [" + _src.id + "]"), EditorGUIUtils.sideLogoIconBoldLabelStyle);
            // Up-down buttons
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("▲", DeGUI.styles.button.toolIco)) UnityEditorInternal.ComponentUtility.MoveComponentUp(_src);
            if (GUILayout.Button("▼", DeGUI.styles.button.toolIco)) UnityEditorInternal.ComponentUtility.MoveComponentDown(_src);
            GUILayout.EndHorizontal();

            if (playMode) {
                if (_runtimeEditMode) {

                } else {
                    GUILayout.Space(8);
                    GUILayout.Label("Animation Editor disabled while in play mode", EditorGUIUtils.wordWrapLabelStyle);
                    if (!_src.isActive) {
                        GUILayout.Label("This animation has been toggled as inactive and won't be generated", EditorGUIUtils.wordWrapLabelStyle);
                        GUI.enabled = false;
                    }
                    if (GUILayout.Button(new GUIContent("Activate Edit Mode", "Switches to Runtime Edit Mode, where you can change animations values and restart them"))) {
                        _runtimeEditMode = true;
                    }
                    GUILayout.Label("NOTE: when using DOPlayNext, the sequence is determined by the DOTweenAnimation Components order in the inTarget GameObject's Inspector", EditorGUIUtils.wordWrapLabelStyle);
                    GUILayout.Space(10);
                    if (!_runtimeEditMode) return;
                }
            }

            Undo.RecordObject(_src, "DOTween Animation");
            Undo.RecordObject(_settings, "DOTween Animation");

//            _src.isValid = Validate(); // Moved down

            EditorGUIUtility.labelWidth = 110;

            if (playMode) {
                GUILayout.Space(4);
                DeGUILayout.Toolbar("Edit Mode Commands");
                DeGUILayout.BeginVBox(DeGUI.styles.box.stickyTop);
                    GUILayout.BeginHorizontal();
                    if (GUILayout.Button("TogglePause")) _src.tween.TogglePause();
                    if (GUILayout.Button("Rewind")) _src.tween.Rewind();
                    if (GUILayout.Button("Restart")) _src.tween.Restart();
                    GUILayout.EndHorizontal();
                    if (GUILayout.Button("Commit changes and restart")) {
                        _src.tween.Rewind();
                        _src.tween.Kill();
                        if (_src.isValid) {
                            _src.CreateTween();
                            _src.tween.Play();
                        }
                    }
                    GUILayout.Label("To apply your changes when exiting Play mode, use the Component's upper right menu and choose \"Copy Component\", then \"Paste Component Values\" after exiting Play mode", DeGUI.styles.label.wordwrap);
                DeGUILayout.EndVBox();
            } else {
                GUILayout.BeginHorizontal();
                bool hasManager = _src.GetComponent<DOTweenVisualManager>() != null;
                EditorGUI.BeginChangeCheck();
                _settings.showPreviewPanel = hasManager
                    ? DeGUILayout.ToggleButton(_settings.showPreviewPanel, "Preview Controls", styles.custom.inlineToggle)
                    : DeGUILayout.ToggleButton(_settings.showPreviewPanel, "Preview Controls", styles.custom.inlineToggle, GUILayout.Width(120));
                if (EditorGUI.EndChangeCheck()) {
                    EditorUtility.SetDirty(_settings);
                    DOTweenPreviewManager.StopAllPreviews();
                }
                if (!hasManager) {
                    if (GUILayout.Button(new GUIContent("Add Manager", "Adds a manager component which allows you to choose additional options for this gameObject"))) {
                        _src.gameObject.AddComponent<DOTweenVisualManager>();
                    }
                }
                GUILayout.EndHorizontal();
            }

            // Preview in editor
            bool isPreviewing = _settings.showPreviewPanel ? DOTweenPreviewManager.PreviewGUI(_src) : false;

            EditorGUI.BeginDisabledGroup(isPreviewing);
            // Choose inTarget
            GUILayout.BeginHorizontal();
                _src.isActive = EditorGUILayout.Toggle(new GUIContent("", "If unchecked, this animation will not be created"), _src.isActive, GUILayout.Width(14));
                EditorGUI.BeginChangeCheck();
                    EditorGUI.BeginChangeCheck();
                        _src.targetIsSelf = DeGUILayout.ToggleButton(
                            _src.targetIsSelf, _src.targetIsSelf ? _GuiC_selfTarget_true : _GuiC_selfTarget_false,
                            new Color(1f, 0.78f, 0f), DeGUI.colors.bg.toggleOn, new Color(0.33f, 0.14f, 0.02f), DeGUI.colors.content.toggleOn,
                            null, GUILayout.Width(47)
                        );
                    bool innerChanged = EditorGUI.EndChangeCheck();
                    if (innerChanged) {
                        _src.targetGO = null;
                        GUI.changed = true;
                    }
                    if (_src.targetIsSelf) GUILayout.Label(_GuiC_selfTarget_true.tooltip);
                    else {
                        using (new DeGUI.ColorScope(null, null, _src.targetGO == null ? Color.red : Color.white)) {
                            _src.targetGO = (GameObject)EditorGUILayout.ObjectField(_src.targetGO, typeof(GameObject), true);
                        }
                        _src.tweenTargetIsTargetGO = DeGUILayout.ToggleButton(
                            _src.tweenTargetIsTargetGO, _src.tweenTargetIsTargetGO ? _GuiC_tweenTargetIsTargetGO_true : _GuiC_tweenTargetIsTargetGO_false,
                            GUILayout.Width(131)
                        );
                    }
                bool check = EditorGUI.EndChangeCheck();
                if (check) _refreshRequired = true;
            GUILayout.EndHorizontal();

            GameObject targetGO = _src.targetIsSelf ? _src.gameObject : _src.targetGO;

            if (targetGO == null) {
                // Uses external inTarget gameObject but it's not set
                if (_src.targetGO != null || _src.target != null) {
                    _src.targetGO = null;
                    _src.target = null;
                    GUI.changed = true;
                }
            } else {
                GUILayout.BeginHorizontal();
                DOTweenAnimation.AnimationType prevAnimType = _src.animationType;
//                _src.animationType = (DOTweenAnimation.AnimationType)EditorGUILayout.EnumPopup(_src.animationType, EditorGUIUtils.popupButton);
                GUI.enabled = GUI.enabled && _src.isActive;
                _src.animationType = AnimationToDOTweenAnimationType(_AnimationType[EditorGUILayout.Popup(DOTweenAnimationTypeToPopupId(_src.animationType), _AnimationType)]);
                _src.autoPlay = DeGUILayout.ToggleButton(_src.autoPlay, new GUIContent("AutoPlay", "If selected, the tween will play automatically"));
                _src.autoKill = DeGUILayout.ToggleButton(_src.autoKill, new GUIContent("AutoKill", "If selected, the tween will be killed when it completes, and won't be reusable"));
                GUILayout.EndHorizontal();
                if (prevAnimType != _src.animationType) {
                    // Set default optional values based on animation type
                    _src.endValueTransform = null;
                    _src.useTargetAsV3 = false;
                    switch (_src.animationType) {
                    case DOTweenAnimation.AnimationType.Move:
                    case DOTweenAnimation.AnimationType.LocalMove:
                    case DOTweenAnimation.AnimationType.Rotate:
                    case DOTweenAnimation.AnimationType.LocalRotate:
                    case DOTweenAnimation.AnimationType.Scale:
                        _src.endValueV3 = Vector3.zero;
                        _src.endValueFloat = 0;
                        _src.optionalBool0 = _src.animationType == DOTweenAnimation.AnimationType.Scale;
                        break;
                    case DOTweenAnimation.AnimationType.UIWidthHeight:
                        _src.endValueV3 = Vector3.zero;
                        _src.endValueFloat = 0;
                        _src.optionalBool0 = _src.animationType == DOTweenAnimation.AnimationType.UIWidthHeight;
                        break;
                    case DOTweenAnimation.AnimationType.Color:
                    case DOTweenAnimation.AnimationType.Fade:
                        _isLightSrc = targetGO.GetComponent<Light>() != null;
                        _src.endValueFloat = 0;
                        break;
                    case DOTweenAnimation.AnimationType.Text:
                        _src.optionalBool0 = true;
                        break;
                    case DOTweenAnimation.AnimationType.PunchPosition:
                    case DOTweenAnimation.AnimationType.PunchRotation:
                    case DOTweenAnimation.AnimationType.PunchScale:
                        _src.endValueV3 = _src.animationType == DOTweenAnimation.AnimationType.PunchRotation ? new Vector3(0, 180, 0) : Vector3.one;
                        _src.optionalFloat0 = 1;
                        _src.optionalInt0 = 10;
                        _src.optionalBool0 = false;
                        break;
                    case DOTweenAnimation.AnimationType.ShakePosition:
                    case DOTweenAnimation.AnimationType.ShakeRotation:
                    case DOTweenAnimation.AnimationType.ShakeScale:
                        _src.endValueV3 = _src.animationType == DOTweenAnimation.AnimationType.ShakeRotation ? new Vector3(90, 90, 90) : Vector3.one;
                        _src.optionalInt0 = 10;
                        _src.optionalFloat0 = 90;
                        _src.optionalBool0 = false;
                        break;
                    case DOTweenAnimation.AnimationType.CameraAspect:
                    case DOTweenAnimation.AnimationType.CameraFieldOfView:
                    case DOTweenAnimation.AnimationType.CameraOrthoSize:
                        _src.endValueFloat = 0;
                        break;
                    case DOTweenAnimation.AnimationType.CameraPixelRect:
                    case DOTweenAnimation.AnimationType.CameraRect:
                        _src.endValueRect = new Rect(0, 0, 0, 0);
                        break;
                    }
                }
                if (_src.animationType == DOTweenAnimation.AnimationType.None) {
                    _src.isValid = false;
                    if (GUI.changed) EditorUtility.SetDirty(_src);
                    return;
                }

                if (_refreshRequired || prevAnimType != _src.animationType || ComponentsChanged()) {
                    _refreshRequired = false;
                    _src.isValid = Validate(targetGO);
                    // See if we need to choose between multiple targets
#if true // UI_MARKER
                    if (_src.animationType == DOTweenAnimation.AnimationType.Fade && targetGO.GetComponent<CanvasGroup>() != null && targetGO.GetComponent<Image>() != null) {
                        _chooseTargetMode = ChooseTargetMode.BetweenCanvasGroupAndImage;
                        // Reassign inTarget and forcedTargetType if lost
                        if (_src.forcedTargetType == DOTweenAnimation.TargetType.Unset) _src.forcedTargetType = _src.targetType;
                        switch (_src.forcedTargetType) {
                        case DOTweenAnimation.TargetType.CanvasGroup:
                            _src.target = targetGO.GetComponent<CanvasGroup>();
                            break;
                        case DOTweenAnimation.TargetType.Image:
                            _src.target = targetGO.GetComponent<Image>();
                            break;
                        }
                    } else {
#endif
                        _chooseTargetMode = ChooseTargetMode.None;
                        _src.forcedTargetType = DOTweenAnimation.TargetType.Unset;
#if true // UI_MARKER
                    }
#endif
                }

                if (!_src.isValid) {
                    GUI.color = Color.red;
                    GUILayout.BeginVertical(GUI.skin.box);
                    GUILayout.Label("No valid Component was found for the selected animation", EditorGUIUtils.wordWrapLabelStyle);
                    GUILayout.EndVertical();
                    GUI.color = Color.white;
                    if (GUI.changed) EditorUtility.SetDirty(_src);
                    return;
                }

#if true // UI_MARKER
                // Special cases in which multiple inTarget types could be used (set after validation)
                if (_chooseTargetMode == ChooseTargetMode.BetweenCanvasGroupAndImage && _src.forcedTargetType != DOTweenAnimation.TargetType.Unset) {
                    FadeTargetType fadeTargetType = (FadeTargetType)Enum.Parse(typeof(FadeTargetType), _src.forcedTargetType.ToString());
                    DOTweenAnimation.TargetType prevTargetType = _src.forcedTargetType;
                    _src.forcedTargetType = (DOTweenAnimation.TargetType)Enum.Parse(typeof(DOTweenAnimation.TargetType), EditorGUILayout.EnumPopup(_src.animationType + " Target", fadeTargetType).ToString());
                    if (_src.forcedTargetType != prevTargetType) {
                        // Target type change > assign correct inTarget
                        switch (_src.forcedTargetType) {
                        case DOTweenAnimation.TargetType.CanvasGroup:
                            _src.target = targetGO.GetComponent<CanvasGroup>();
                            break;
                        case DOTweenAnimation.TargetType.Image:
                            _src.target = targetGO.GetComponent<Image>();
                            break;
                        }
                    }
                }
#endif

                GUILayout.BeginHorizontal();
                _src.duration = EditorGUILayout.FloatField("Duration", _src.duration);
                if (_src.duration < 0) _src.duration = 0;
                _src.isSpeedBased = DeGUILayout.ToggleButton(_src.isSpeedBased, new GUIContent("SpeedBased", "If selected, the duration will count as units/degree x second"), DeGUI.styles.button.tool, GUILayout.Width(75));
                GUILayout.EndHorizontal();
                _src.delay = EditorGUILayout.FloatField("Delay", _src.delay);
                if (_src.delay < 0) _src.delay = 0;
                _src.isIndependentUpdate = EditorGUILayout.Toggle("Ignore TimeScale", _src.isIndependentUpdate);
                _src.easeType = EditorGUIUtils.FilteredEasePopup(_src.easeType);
                if (_src.easeType == Ease.INTERNAL_Custom) {
                    _src.easeCurve = EditorGUILayout.CurveField("   Ease Curve", _src.easeCurve);
                }
                _src.loops = EditorGUILayout.IntField(new GUIContent("Loops", "Set to -1 for infinite loops"), _src.loops);
                if (_src.loops < -1) _src.loops = -1;
                if (_src.loops > 1 || _src.loops == -1)
                    _src.loopType = (LoopType)EditorGUILayout.EnumPopup("   Loop Type", _src.loopType);
                _src.id = EditorGUILayout.TextField("ID", _src.id);

                bool canBeRelative = true;
                // End value and eventual specific options
                switch (_src.animationType) {
                case DOTweenAnimation.AnimationType.Move:
                case DOTweenAnimation.AnimationType.LocalMove:
                    GUIEndValueV3(targetGO, _src.animationType == DOTweenAnimation.AnimationType.Move);
                    _src.optionalBool0 = EditorGUILayout.Toggle("    Snapping", _src.optionalBool0);
                    canBeRelative = !_src.useTargetAsV3;
                    break;
                case DOTweenAnimation.AnimationType.Rotate:
                case DOTweenAnimation.AnimationType.LocalRotate:
                    bool isRigidbody2D = DOTweenModuleUtils.Physics.HasRigidbody2D(_src);
                    if (isRigidbody2D) GUIEndValueFloat();
                    else {
                        GUIEndValueV3(targetGO);
                        _src.optionalRotationMode = (RotateMode)EditorGUILayout.EnumPopup("    Rotation Mode", _src.optionalRotationMode);
                    }
                    break;
                case DOTweenAnimation.AnimationType.Scale:
                    if (_src.optionalBool0) GUIEndValueFloat();
                    else GUIEndValueV3(targetGO);
                    _src.optionalBool0 = EditorGUILayout.Toggle("Uniform Scale", _src.optionalBool0);
                    break;
                case DOTweenAnimation.AnimationType.UIWidthHeight:
                    if (_src.optionalBool0) GUIEndValueFloat();
                    else GUIEndValueV2();
                    _src.optionalBool0 = EditorGUILayout.Toggle("Uniform Scale", _src.optionalBool0);
                    break;
                case DOTweenAnimation.AnimationType.Color:
                    GUIEndValueColor();
                    canBeRelative = false;
                    break;
                case DOTweenAnimation.AnimationType.Fade:
                    GUIEndValueFloat();
                    if (_src.endValueFloat < 0) _src.endValueFloat = 0;
                    if (!_isLightSrc && _src.endValueFloat > 1) _src.endValueFloat = 1;
                    canBeRelative = false;
                    break;
                case DOTweenAnimation.AnimationType.Text:
                    GUIEndValueString();
                    _src.optionalBool0 = EditorGUILayout.Toggle("Rich Text Enabled", _src.optionalBool0);
                    _src.optionalScrambleMode = (ScrambleMode)EditorGUILayout.EnumPopup("Scramble Mode", _src.optionalScrambleMode);
                    _src.optionalString = EditorGUILayout.TextField(new GUIContent("Custom Scramble", "Custom characters to use in case of ScrambleMode.Custom"), _src.optionalString);
                    break;
                case DOTweenAnimation.AnimationType.PunchPosition:
                case DOTweenAnimation.AnimationType.PunchRotation:
                case DOTweenAnimation.AnimationType.PunchScale:
                    GUIEndValueV3(targetGO);
                    canBeRelative = false;
                    _src.optionalInt0 = EditorGUILayout.IntSlider(new GUIContent("    Vibrato", "How much will the punch vibrate"), _src.optionalInt0, 1, 50);
                    _src.optionalFloat0 = EditorGUILayout.Slider(new GUIContent("    Elasticity", "How much the vector will go beyond the starting position when bouncing backwards"), _src.optionalFloat0, 0, 1);
                    if (_src.animationType == DOTweenAnimation.AnimationType.PunchPosition) _src.optionalBool0 = EditorGUILayout.Toggle("    Snapping", _src.optionalBool0);
                    break;
                case DOTweenAnimation.AnimationType.ShakePosition:
                case DOTweenAnimation.AnimationType.ShakeRotation:
                case DOTweenAnimation.AnimationType.ShakeScale:
                    GUIEndValueV3(targetGO);
                    canBeRelative = false;
                    _src.optionalInt0 = EditorGUILayout.IntSlider(new GUIContent("    Vibrato", "How much will the shake vibrate"), _src.optionalInt0, 1, 50);
                    _src.optionalFloat0 = EditorGUILayout.Slider(new GUIContent("    Randomness", "The shake randomness"), _src.optionalFloat0, 0, 90);
                    if (_src.animationType == DOTweenAnimation.AnimationType.ShakePosition) _src.optionalBool0 = EditorGUILayout.Toggle("    Snapping", _src.optionalBool0);
                    break;
                case DOTweenAnimation.AnimationType.CameraAspect:
                case DOTweenAnimation.AnimationType.CameraFieldOfView:
                case DOTweenAnimation.AnimationType.CameraOrthoSize:
                    GUIEndValueFloat();
                    canBeRelative = false;
                    break;
                case DOTweenAnimation.AnimationType.CameraBackgroundColor:
                    GUIEndValueColor();
                    canBeRelative = false;
                    break;
                case DOTweenAnimation.AnimationType.CameraPixelRect:
                case DOTweenAnimation.AnimationType.CameraRect:
                    GUIEndValueRect();
                    canBeRelative = false;
                    break;
                }

                // Final settings
                if (canBeRelative) _src.isRelative = EditorGUILayout.Toggle("    Relative", _src.isRelative);

                // Events
                AnimationInspectorGUI.AnimationEvents(this, _src);
            }
            EditorGUI.EndDisabledGroup();

            if (GUI.changed) EditorUtility.SetDirty(_src);
        }

        #endregion

        #region Methods

        // Returns TRUE if the Component layout on the src gameObject changed (a Component was added or removed)
        bool ComponentsChanged()
        {
            int prevTotComponentsOnSrc = _totComponentsOnSrc;
            _totComponentsOnSrc = _src.gameObject.GetComponents<Component>().Length;
            return prevTotComponentsOnSrc != _totComponentsOnSrc;
        }

        // Checks if a Component that can be animated with the given animationType is attached to the src
        bool Validate(GameObject targetGO)
        {
            if (_src.animationType == DOTweenAnimation.AnimationType.None) return false;

            Component srcTarget;
            // First check for external plugins
#if false // TK2D_MARKER
            if (_Tk2dAnimationTypeToComponent.ContainsKey(_src.animationType)) {
                foreach (Type t in _Tk2dAnimationTypeToComponent[_src.animationType]) {
                    srcTarget = targetGO.GetComponent(t);
                    if (srcTarget != null) {
                        _src.inTarget = srcTarget;
                        _src.targetType = DOTweenAnimation.TypeToDOTargetType(t);
                        return true;
                    }
                }
            }
#endif
#if false // TEXTMESHPRO_MARKER
            if (_TMPAnimationTypeToComponent.ContainsKey(_src.animationType)) {
                foreach (Type t in _TMPAnimationTypeToComponent[_src.animationType]) {
                    srcTarget = targetGO.GetComponent(t);
                    if (srcTarget != null) {
                        _src.inTarget = srcTarget;
                        _src.targetType = DOTweenAnimation.TypeToDOTargetType(t);
                        return true;
                    }
                }
            }
#endif
            // Then check for regular stuff
            if (_AnimationTypeToComponent.ContainsKey(_src.animationType)) {
                foreach (Type t in _AnimationTypeToComponent[_src.animationType]) {
                    srcTarget = targetGO.GetComponent(t);
                    if (srcTarget != null) {
                        _src.target = srcTarget;
                        _src.targetType = DOTweenAnimation.TypeToDOTargetType(t);
                        return true;
                    }
                }
            }
            return false;
        }

        DOTweenAnimation.AnimationType AnimationToDOTweenAnimationType(string animation)
        {
            if (_datString == null) _datString = Enum.GetNames(typeof(DOTweenAnimation.AnimationType));
            animation = animation.Replace("/", "");
            return (DOTweenAnimation.AnimationType)(Array.IndexOf(_datString, animation));
        }
        int DOTweenAnimationTypeToPopupId(DOTweenAnimation.AnimationType animation)
        {
            return Array.IndexOf(_animationTypeNoSlashes, animation.ToString());
        }

        #endregion

        #region GUI Draw Methods

        void GUIEndValueFloat()
        {
            GUILayout.BeginHorizontal();
            GUIToFromButton();
            _src.endValueFloat = EditorGUILayout.FloatField(_src.endValueFloat);
            GUILayout.EndHorizontal();
        }

        void GUIEndValueColor()
        {
            GUILayout.BeginHorizontal();
            GUIToFromButton();
            _src.endValueColor = EditorGUILayout.ColorField(_src.endValueColor);
            GUILayout.EndHorizontal();
        }

        void GUIEndValueV3(GameObject targetGO, bool optionalTransform = false)
        {
            GUILayout.BeginHorizontal();
            GUIToFromButton();
            if (_src.useTargetAsV3) {
                Transform prevT = _src.endValueTransform;
                _src.endValueTransform = EditorGUILayout.ObjectField(_src.endValueTransform, typeof(Transform), true) as Transform;
                if (_src.endValueTransform != prevT && _src.endValueTransform != null) {
#if true // UI_MARKER
                    // Check that it's a Transform for a Transform or a RectTransform for a RectTransform
                    if (targetGO.GetComponent<RectTransform>() != null) {
                        if (_src.endValueTransform.GetComponent<RectTransform>() == null) {
                            EditorUtility.DisplayDialog("DOTween Pro", "For Unity UI elements, the inTarget must also be a UI element", "Ok");
                            _src.endValueTransform = null;
                        }
                    } else if (_src.endValueTransform.GetComponent<RectTransform>() != null) {
                        EditorUtility.DisplayDialog("DOTween Pro", "You can't use a UI inTarget for a non UI object", "Ok");
                        _src.endValueTransform = null;
                    }
#endif
                }
            } else {
                _src.endValueV3 = EditorGUILayout.Vector3Field("", _src.endValueV3, GUILayout.Height(16));
            }
            if (optionalTransform) {
                if (GUILayout.Button(_src.useTargetAsV3 ? "inTarget" : "value", EditorGUIUtils.sideBtStyle, GUILayout.Width(44))) _src.useTargetAsV3 = !_src.useTargetAsV3;
            }
            GUILayout.EndHorizontal();
#if true // UI_MARKER
            if (_src.useTargetAsV3 && _src.endValueTransform != null && _src.target is RectTransform) {
                EditorGUILayout.HelpBox("NOTE: when using a UI inTarget, the tween will be created during Start instead of Awake", MessageType.Info);
            }
#endif
        }

        void GUIEndValueV2()
        {
            GUILayout.BeginHorizontal();
            GUIToFromButton();
            _src.endValueV2 = EditorGUILayout.Vector2Field("", _src.endValueV2, GUILayout.Height(16));
            GUILayout.EndHorizontal();
        }

        void GUIEndValueString()
        {
            GUILayout.BeginHorizontal();
            GUIToFromButton();
            _src.endValueString = EditorGUILayout.TextArea(_src.endValueString, EditorGUIUtils.wordWrapTextArea);
            GUILayout.EndHorizontal();
        }

        void GUIEndValueRect()
        {
            GUILayout.BeginHorizontal();
            GUIToFromButton();
            _src.endValueRect = EditorGUILayout.RectField(_src.endValueRect);
            GUILayout.EndHorizontal();
        }

        void GUIToFromButton()
        {
            if (GUILayout.Button(_src.isFrom ? "FROM" : "TO", EditorGUIUtils.sideBtStyle, GUILayout.Width(90))) _src.isFrom = !_src.isFrom;
            GUILayout.Space(16);
        }

        #endregion
    }

    // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
    // ███ INTERNAL CLASSES ████████████████████████████████████████████████████████████████████████████████████████████████
    // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████

    [InitializeOnLoad]
    static class Initializer
    {
        static Initializer()
        {
            DOTweenAnimation.OnReset += OnReset;
        }

        static void OnReset(DOTweenAnimation src)
        {
            DOTweenSettings settings = DOTweenUtilityWindow.GetDOTweenSettings();
            if (settings == null) return;

            Undo.RecordObject(src, "DOTweenAnimation");
            src.autoPlay = settings.defaultAutoPlay == AutoPlay.All || settings.defaultAutoPlay == AutoPlay.AutoPlayTweeners;
            src.autoKill = settings.defaultAutoKill;
            EditorUtility.SetDirty(src);
        }
    }
}


text:
fileFormatVersion: 2
guid: 34192c5e0d14aee43a0e86cc4823268a
TextScriptImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
fileFormatVersion: 2
guid: 4f007001a22b3d24dae350342c4d19c8
DefaultImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
fileFormatVersion: 2
guid: fccfc62abf2eb0a4db614853430894fd
TextScriptImporter:
  externalObjects: {}
  userData:
  assetBundleName:
  assetBundleVariant:


text:
fileFormatVersion: 2
guid: a811bde74b26b53498b4f6d872b09b6d
PluginImporter:
  externalObjects: {}
  serializedVersion: 2
  iconMap: {}
  executionOrder: {}
  defineConstraints: []
  isPreloaded: 0
  isOverridable: 0
  isExplicitlyReferenced: 0
  validateReferences: 1
  platformData:
  - first:
      Any:
    second:
      enabled: 1
      settings: {}
  - first:
      Editor: Editor
    second:
      enabled: 0
      settings:
        DefaultValueInitialized: true
  - first:
      Windows Store Apps: WindowsStoreApps
    second:
      enabled: 0
      settings:
        CPU: AnyCPU
  userData:
  assetBundleName:
  assetBundleVariant: