You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
745 lines
38 KiB
745 lines
38 KiB
// Author: Daniele Giardini - http://www.demigiant.com |
|
// Created: 2015/03/12 16:03 |
|
|
|
using System; |
|
using System.Collections.Generic; |
|
using System.IO; |
|
using DG.DemiEditor; |
|
using DG.DOTweenEditor.Core; |
|
using DG.DOTweenEditor.UI; |
|
using DG.Tweening; |
|
using DG.Tweening.Core; |
|
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), typeof(Graphic), |
|
#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), typeof(Graphic), |
|
#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 target (via SetTarget, used to control a tween directly from a target) to the \"OTHER\" gameObject" |
|
); |
|
static readonly GUIContent _GuiC_tweenTargetIsTargetGO_false = new GUIContent( |
|
"Use As Tween Target", "Will set the tween target (via SetTarget, used to control a tween directly from a target) 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 target 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 target |
|
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 target 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 target 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 target 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 target |
|
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("Ease", _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.target = 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.target = 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 target 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 target 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 ? "target" : "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 target, 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); |
|
} |
|
} |
|
}
|
|
|