Reupload to new git vps.
This commit is contained in:
commit
8ad72ae00b
57 changed files with 2290 additions and 0 deletions
16
DC.Animator.asmdef
Normal file
16
DC.Animator.asmdef
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"name": "DC.Animator",
|
||||||
|
"rootNamespace": "",
|
||||||
|
"references": [
|
||||||
|
"GUID:6055be8ebefd69e48b49212b09b47b2f"
|
||||||
|
],
|
||||||
|
"includePlatforms": [],
|
||||||
|
"excludePlatforms": [],
|
||||||
|
"allowUnsafeCode": false,
|
||||||
|
"overrideReferences": false,
|
||||||
|
"precompiledReferences": [],
|
||||||
|
"autoReferenced": true,
|
||||||
|
"defineConstraints": [],
|
||||||
|
"versionDefines": [],
|
||||||
|
"noEngineReferences": false
|
||||||
|
}
|
7
DC.Animator.asmdef.meta
Normal file
7
DC.Animator.asmdef.meta
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fd7612f2de54f1e46a60c1460f826a43
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Editor.meta
Normal file
8
Editor.meta
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a60c3d1cd509697419e16c967dfffc14
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
145
Editor/AnimationCollectionEditor.cs
Normal file
145
Editor/AnimationCollectionEditor.cs
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
using System;
|
||||||
|
using DC.Animator.Data;
|
||||||
|
using DC.Animator.Utils;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DC.Animator.Editor
|
||||||
|
{
|
||||||
|
[CustomEditor(typeof(AnimationCollection))]
|
||||||
|
public class AnimationCollectionEditor : UnityEditor.Editor
|
||||||
|
{
|
||||||
|
private SerializedProperty _animationsProperty;
|
||||||
|
private AnimationCollection _collection;
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
_animationsProperty = serializedObject.FindProperty("animations");
|
||||||
|
_collection = (AnimationCollection)target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnInspectorGUI()
|
||||||
|
{
|
||||||
|
serializedObject.Update();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
EditorGUILayout.LabelField("Animation Presets", EditorStyles.boldLabel);
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
if (GUILayout.Button("Add Animation", GUILayout.Height(30))) AddNewAnimation();
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
for (var i = 0; i < _animationsProperty.arraySize; i++)
|
||||||
|
{
|
||||||
|
var animationProperty = _animationsProperty.GetArrayElementAtIndex(i);
|
||||||
|
var nameProperty = animationProperty.FindPropertyRelative("name");
|
||||||
|
var typeProperty = animationProperty.FindPropertyRelative("type");
|
||||||
|
|
||||||
|
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
||||||
|
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUILayout.PropertyField(nameProperty, GUIContent.none);
|
||||||
|
EditorGUILayout.PropertyField(typeProperty, GUIContent.none, GUILayout.Width(100));
|
||||||
|
|
||||||
|
if (GUILayout.Button("X", GUILayout.Width(25)))
|
||||||
|
{
|
||||||
|
_animationsProperty.DeleteArrayElementAtIndex(i);
|
||||||
|
serializedObject.ApplyModifiedProperties();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
var foldoutName = nameProperty.stringValue;
|
||||||
|
if (string.IsNullOrEmpty(foldoutName))
|
||||||
|
foldoutName = "Animation " + i;
|
||||||
|
|
||||||
|
animationProperty.isExpanded = EditorGUILayout.Foldout(animationProperty.isExpanded, foldoutName, true);
|
||||||
|
|
||||||
|
if (animationProperty.isExpanded)
|
||||||
|
{
|
||||||
|
EditorGUI.indentLevel++;
|
||||||
|
|
||||||
|
EditorGUILayout.PropertyField(animationProperty.FindPropertyRelative("duration"));
|
||||||
|
EditorGUILayout.PropertyField(animationProperty.FindPropertyRelative("delay"));
|
||||||
|
EditorGUILayout.PropertyField(animationProperty.FindPropertyRelative("easingType"));
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
var type = (AnimationCollection.AnimationType)typeProperty.enumValueIndex;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case AnimationCollection.AnimationType.Fade:
|
||||||
|
EditorGUILayout.PropertyField(animationProperty.FindPropertyRelative("fromAlpha"));
|
||||||
|
EditorGUILayout.PropertyField(animationProperty.FindPropertyRelative("toAlpha"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnimationCollection.AnimationType.Move:
|
||||||
|
EditorGUILayout.PropertyField(animationProperty.FindPropertyRelative("fromPosition"));
|
||||||
|
EditorGUILayout.PropertyField(animationProperty.FindPropertyRelative("toPosition"));
|
||||||
|
EditorGUILayout.PropertyField(animationProperty.FindPropertyRelative("useLocalPosition"));
|
||||||
|
EditorGUILayout.PropertyField(
|
||||||
|
animationProperty.FindPropertyRelative("useAnchoredPosition"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnimationCollection.AnimationType.Scale:
|
||||||
|
EditorGUILayout.PropertyField(animationProperty.FindPropertyRelative("fromScale"));
|
||||||
|
EditorGUILayout.PropertyField(animationProperty.FindPropertyRelative("toScale"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnimationCollection.AnimationType.Rotate:
|
||||||
|
EditorGUILayout.PropertyField(animationProperty.FindPropertyRelative("fromEulerAngles"));
|
||||||
|
EditorGUILayout.PropertyField(animationProperty.FindPropertyRelative("toEulerAngles"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnimationCollection.AnimationType.Color:
|
||||||
|
EditorGUILayout.PropertyField(animationProperty.FindPropertyRelative("fromColor"));
|
||||||
|
EditorGUILayout.PropertyField(animationProperty.FindPropertyRelative("toColor"));
|
||||||
|
EditorGUILayout.PropertyField(animationProperty.FindPropertyRelative("isTextColor"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUI.indentLevel--;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndVertical();
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
}
|
||||||
|
|
||||||
|
serializedObject.ApplyModifiedProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddNewAnimation()
|
||||||
|
{
|
||||||
|
var index = _animationsProperty.arraySize;
|
||||||
|
_animationsProperty.InsertArrayElementAtIndex(index);
|
||||||
|
|
||||||
|
var element = _animationsProperty.GetArrayElementAtIndex(index);
|
||||||
|
|
||||||
|
element.FindPropertyRelative("name").stringValue = "New Animation";
|
||||||
|
element.FindPropertyRelative("type").enumValueIndex = 0;
|
||||||
|
element.FindPropertyRelative("duration").floatValue = 0.5f;
|
||||||
|
element.FindPropertyRelative("delay").floatValue = 0f;
|
||||||
|
element.FindPropertyRelative("easingType").enumValueIndex = (int)Easing.Type.EaseOutQuad;
|
||||||
|
|
||||||
|
element.FindPropertyRelative("fromAlpha").floatValue = 0f;
|
||||||
|
element.FindPropertyRelative("toAlpha").floatValue = 1f;
|
||||||
|
|
||||||
|
element.FindPropertyRelative("fromScale").vector3Value = Vector3.zero;
|
||||||
|
element.FindPropertyRelative("toScale").vector3Value = Vector3.one;
|
||||||
|
|
||||||
|
element.FindPropertyRelative("fromColor").colorValue = Color.white;
|
||||||
|
element.FindPropertyRelative("toColor").colorValue = Color.white;
|
||||||
|
|
||||||
|
element.isExpanded = true;
|
||||||
|
|
||||||
|
serializedObject.ApplyModifiedProperties();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
3
Editor/AnimationCollectionEditor.cs.meta
Normal file
3
Editor/AnimationCollectionEditor.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e980dad5c4f248808f571603257f2611
|
||||||
|
timeCreated: 1747861571
|
401
Editor/AnimationEditorWindow.cs
Normal file
401
Editor/AnimationEditorWindow.cs
Normal file
|
@ -0,0 +1,401 @@
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
using System;
|
||||||
|
using DC.Animator.Adapters;
|
||||||
|
using DC.Animator.Core;
|
||||||
|
using DC.Animator.Data;
|
||||||
|
using DC.Animator.Utils;
|
||||||
|
using DCAnimator.Data;
|
||||||
|
using TMPro;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace DC.Animator.Editor
|
||||||
|
{
|
||||||
|
public class AnimationEditorWindow : EditorWindow
|
||||||
|
{
|
||||||
|
private readonly string[] _animationTypes = { "Fade", "Move", "Scale", "Rotate", "Color" };
|
||||||
|
|
||||||
|
private readonly string[] _tabNames = { "Create", "Test", "Manage Presets" };
|
||||||
|
private AnimationCollection _animationCollection;
|
||||||
|
|
||||||
|
private AnimationData _currentAnimation = new();
|
||||||
|
private bool _isAnimating;
|
||||||
|
private float _lastUpdateTime;
|
||||||
|
private string _presetName = "New Preset";
|
||||||
|
private IAnimation _previewAnimation;
|
||||||
|
private Vector2 _scrollPosition;
|
||||||
|
private int _selectedAnimationType;
|
||||||
|
|
||||||
|
private int _selectedTabIndex;
|
||||||
|
|
||||||
|
private GameObject _targetObject;
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
ResetCurrentAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGUI()
|
||||||
|
{
|
||||||
|
_selectedTabIndex = GUILayout.Toolbar(_selectedTabIndex, _tabNames);
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
switch (_selectedTabIndex)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
DrawCreateAnimationTab();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
DrawTestAnimationTab();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
DrawManagePresetsTab();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_isAnimating || _previewAnimation == null) return;
|
||||||
|
|
||||||
|
var deltaTime = (float)(EditorApplication.timeSinceStartup - _lastUpdateTime);
|
||||||
|
_lastUpdateTime = (float)EditorApplication.timeSinceStartup;
|
||||||
|
|
||||||
|
_previewAnimation.Update(deltaTime);
|
||||||
|
|
||||||
|
if (_previewAnimation.IsComplete) _isAnimating = false;
|
||||||
|
|
||||||
|
Repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("Window/DC Animator/Editor")]
|
||||||
|
public static void ShowWindow()
|
||||||
|
{
|
||||||
|
GetWindow<AnimationEditorWindow>("DC Animator Editor");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetCurrentAnimation()
|
||||||
|
{
|
||||||
|
_currentAnimation = new AnimationData
|
||||||
|
{
|
||||||
|
name = "New Animation",
|
||||||
|
type = AnimationCollection.AnimationType.Fade,
|
||||||
|
duration = 0.5f,
|
||||||
|
delay = 0f,
|
||||||
|
easingType = Easing.Type.EaseOutQuad,
|
||||||
|
fromAlpha = 0f,
|
||||||
|
toAlpha = 1f,
|
||||||
|
fromScale = Vector3.zero,
|
||||||
|
toScale = Vector3.one,
|
||||||
|
fromColor = Color.white,
|
||||||
|
toColor = Color.white
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawCreateAnimationTab()
|
||||||
|
{
|
||||||
|
_scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);
|
||||||
|
|
||||||
|
EditorGUILayout.LabelField("Create New Animation", EditorStyles.boldLabel);
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
_currentAnimation.name = EditorGUILayout.TextField("Animation Name", _currentAnimation.name);
|
||||||
|
|
||||||
|
_selectedAnimationType = EditorGUILayout.Popup("Animation Type", _selectedAnimationType, _animationTypes);
|
||||||
|
_currentAnimation.type = (AnimationCollection.AnimationType)_selectedAnimationType;
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
EditorGUILayout.LabelField("Common Properties", EditorStyles.boldLabel);
|
||||||
|
_currentAnimation.duration = EditorGUILayout.FloatField("Duration", _currentAnimation.duration);
|
||||||
|
_currentAnimation.delay = EditorGUILayout.FloatField("Delay", _currentAnimation.delay);
|
||||||
|
|
||||||
|
var easingNames = Enum.GetNames(typeof(Easing.Type));
|
||||||
|
var easingIndex = (int)_currentAnimation.easingType;
|
||||||
|
easingIndex = EditorGUILayout.Popup("Easing Type", easingIndex, easingNames);
|
||||||
|
_currentAnimation.easingType = (Easing.Type)easingIndex;
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
// Specific Properties
|
||||||
|
EditorGUILayout.LabelField("Animation Properties", EditorStyles.boldLabel);
|
||||||
|
|
||||||
|
switch (_currentAnimation.type)
|
||||||
|
{
|
||||||
|
case AnimationCollection.AnimationType.Fade:
|
||||||
|
_currentAnimation.fromAlpha =
|
||||||
|
EditorGUILayout.Slider("From Alpha", _currentAnimation.fromAlpha, 0f, 1f);
|
||||||
|
_currentAnimation.toAlpha = EditorGUILayout.Slider("To Alpha", _currentAnimation.toAlpha, 0f, 1f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnimationCollection.AnimationType.Move:
|
||||||
|
_currentAnimation.fromPosition =
|
||||||
|
EditorGUILayout.Vector3Field("From Position", _currentAnimation.fromPosition);
|
||||||
|
_currentAnimation.toPosition =
|
||||||
|
EditorGUILayout.Vector3Field("To Position", _currentAnimation.toPosition);
|
||||||
|
_currentAnimation.useLocalPosition =
|
||||||
|
EditorGUILayout.Toggle("Use Local Position", _currentAnimation.useLocalPosition);
|
||||||
|
_currentAnimation.useAnchoredPosition = EditorGUILayout.Toggle("Use Anchored Position",
|
||||||
|
_currentAnimation.useAnchoredPosition);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnimationCollection.AnimationType.Scale:
|
||||||
|
_currentAnimation.fromScale =
|
||||||
|
EditorGUILayout.Vector3Field("From Scale", _currentAnimation.fromScale);
|
||||||
|
_currentAnimation.toScale = EditorGUILayout.Vector3Field("To Scale", _currentAnimation.toScale);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnimationCollection.AnimationType.Rotate:
|
||||||
|
_currentAnimation.fromEulerAngles =
|
||||||
|
EditorGUILayout.Vector3Field("From Rotation", _currentAnimation.fromEulerAngles);
|
||||||
|
_currentAnimation.toEulerAngles =
|
||||||
|
EditorGUILayout.Vector3Field("To Rotation", _currentAnimation.toEulerAngles);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnimationCollection.AnimationType.Color:
|
||||||
|
_currentAnimation.fromColor = EditorGUILayout.ColorField("From Color", _currentAnimation.fromColor);
|
||||||
|
_currentAnimation.toColor = EditorGUILayout.ColorField("To Color", _currentAnimation.toColor);
|
||||||
|
_currentAnimation.isTextColor =
|
||||||
|
EditorGUILayout.Toggle("Is Text Color", _currentAnimation.isTextColor);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
|
||||||
|
_animationCollection = (AnimationCollection)EditorGUILayout.ObjectField("Save To Preset", _animationCollection,
|
||||||
|
typeof(AnimationCollection), false);
|
||||||
|
|
||||||
|
if (_animationCollection && GUILayout.Button("Save")) SaveAnimationToPreset();
|
||||||
|
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
|
||||||
|
if (!_animationCollection)
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
_presetName = EditorGUILayout.TextField("New Preset Name", _presetName);
|
||||||
|
|
||||||
|
if (GUILayout.Button("Create")) CreateNewPreset();
|
||||||
|
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndScrollView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawTestAnimationTab()
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("Test Animation", EditorStyles.boldLabel);
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
_targetObject =
|
||||||
|
(GameObject)EditorGUILayout.ObjectField("Target Object", _targetObject, typeof(GameObject), true);
|
||||||
|
_animationCollection = (AnimationCollection)EditorGUILayout.ObjectField("Animation Preset", _animationCollection,
|
||||||
|
typeof(AnimationCollection), false);
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
if (_targetObject && _animationCollection)
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("Available Animations:", EditorStyles.boldLabel);
|
||||||
|
|
||||||
|
if (_animationCollection.animations.Count == 0)
|
||||||
|
EditorGUILayout.HelpBox("No animations in preset", MessageType.Info);
|
||||||
|
else
|
||||||
|
foreach (var anim in _animationCollection.animations)
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUILayout.LabelField(anim.name, EditorStyles.label);
|
||||||
|
|
||||||
|
if (GUILayout.Button("Play", GUILayout.Width(60))) PlayAnimation(anim.name);
|
||||||
|
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorGUILayout.HelpBox("Select a target object and an animation preset to test animations",
|
||||||
|
MessageType.Info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawManagePresetsTab()
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("Manage Animation Presets", EditorStyles.boldLabel);
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
_animationCollection = (AnimationCollection)EditorGUILayout.ObjectField("Animation Preset", _animationCollection,
|
||||||
|
typeof(AnimationCollection), false);
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
if (_animationCollection)
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("Animations in Preset:", EditorStyles.boldLabel);
|
||||||
|
|
||||||
|
if (_animationCollection.animations.Count == 0)
|
||||||
|
EditorGUILayout.HelpBox("No animations in preset", MessageType.Info);
|
||||||
|
else
|
||||||
|
for (var i = 0; i < _animationCollection.animations.Count; i++)
|
||||||
|
{
|
||||||
|
var anim = _animationCollection.animations[i];
|
||||||
|
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
EditorGUILayout.LabelField($"{anim.name} ({anim.type})", EditorStyles.label);
|
||||||
|
|
||||||
|
if (GUILayout.Button("Edit", GUILayout.Width(60)))
|
||||||
|
{
|
||||||
|
_currentAnimation = anim;
|
||||||
|
_selectedAnimationType = (int)anim.type;
|
||||||
|
_selectedTabIndex = 0; // Switch to Create tab
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GUILayout.Button("Delete", GUILayout.Width(60)))
|
||||||
|
if (EditorUtility.DisplayDialog("Delete Animation",
|
||||||
|
$"Are you sure you want to delete animation '{anim.name}'?",
|
||||||
|
"Delete", "Cancel"))
|
||||||
|
{
|
||||||
|
_animationCollection.animations.RemoveAt(i);
|
||||||
|
EditorUtility.SetDirty(_animationCollection);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
if (GUILayout.Button("Create New Animation", GUILayout.Height(30)))
|
||||||
|
{
|
||||||
|
ResetCurrentAnimation();
|
||||||
|
_selectedTabIndex = 0; // Switch to Create tab
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EditorGUILayout.BeginHorizontal();
|
||||||
|
_presetName = EditorGUILayout.TextField("New Preset Name", _presetName);
|
||||||
|
|
||||||
|
if (GUILayout.Button("Create")) CreateNewPreset();
|
||||||
|
|
||||||
|
EditorGUILayout.EndHorizontal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateNewPreset()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(_presetName))
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("Error", "Please enter a name for the preset", "OK");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var path = EditorUtility.SaveFilePanelInProject(
|
||||||
|
"Save Animation Preset",
|
||||||
|
_presetName,
|
||||||
|
"asset",
|
||||||
|
"Save animation preset"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(path))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_animationCollection = CreateInstance<AnimationCollection>();
|
||||||
|
AssetDatabase.CreateAsset(_animationCollection, path);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
|
||||||
|
SaveAnimationToPreset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveAnimationToPreset()
|
||||||
|
{
|
||||||
|
if (!_animationCollection)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (var i = 0; i < _animationCollection.animations.Count; i++)
|
||||||
|
if (_animationCollection.animations[i].name == _currentAnimation.name)
|
||||||
|
{
|
||||||
|
if (!EditorUtility.DisplayDialog("Overwrite Animation",
|
||||||
|
$"Animation '{_currentAnimation.name}' already exists. Overwrite?",
|
||||||
|
"Overwrite", "Cancel")) return;
|
||||||
|
|
||||||
|
_animationCollection.animations[i] = _currentAnimation;
|
||||||
|
EditorUtility.SetDirty(_animationCollection);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_animationCollection.animations.Add(_currentAnimation);
|
||||||
|
EditorUtility.SetDirty(_animationCollection);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PlayAnimation(string animationName)
|
||||||
|
{
|
||||||
|
if (!_targetObject || !_animationCollection)
|
||||||
|
return;
|
||||||
|
|
||||||
|
IAnimatable adapter;
|
||||||
|
|
||||||
|
var image = _targetObject.GetComponent<Image>();
|
||||||
|
if (image)
|
||||||
|
adapter = new ImageAdapter(image);
|
||||||
|
|
||||||
|
var text = _targetObject.GetComponent<TextMeshProUGUI>();
|
||||||
|
if (text)
|
||||||
|
adapter = new TMPTextAdapter(text);
|
||||||
|
|
||||||
|
var tmpro = _targetObject.GetComponent<TextMeshPro>();
|
||||||
|
if (tmpro)
|
||||||
|
adapter = new TMPTextAdapter(tmpro);
|
||||||
|
|
||||||
|
var spriteRenderer = _targetObject.GetComponent<SpriteRenderer>();
|
||||||
|
if (spriteRenderer)
|
||||||
|
adapter = new SpriteAdapter(spriteRenderer);
|
||||||
|
|
||||||
|
var rectTransform = _targetObject.GetComponent<RectTransform>();
|
||||||
|
if (rectTransform)
|
||||||
|
{
|
||||||
|
adapter = new RectTransformAdapter(rectTransform);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var transform = _targetObject.transform;
|
||||||
|
adapter = new TransformAdapter(transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
_previewAnimation = _animationCollection.CreateAnimation(adapter, animationName);
|
||||||
|
|
||||||
|
if (_previewAnimation == null)
|
||||||
|
{
|
||||||
|
EditorUtility.DisplayDialog("Error", $"Animation '{animationName}' not found in preset", "OK");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_previewAnimation.Start();
|
||||||
|
_isAnimating = true;
|
||||||
|
_lastUpdateTime = (float)EditorApplication.timeSinceStartup;
|
||||||
|
|
||||||
|
EditorApplication.update += EditorUpdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EditorUpdate()
|
||||||
|
{
|
||||||
|
if (_isAnimating && _previewAnimation != null)
|
||||||
|
{
|
||||||
|
Repaint();
|
||||||
|
|
||||||
|
if (!_previewAnimation.IsComplete) return;
|
||||||
|
|
||||||
|
_isAnimating = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorApplication.update -= EditorUpdate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
3
Editor/AnimationEditorWindow.cs.meta
Normal file
3
Editor/AnimationEditorWindow.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f24aeb6fb1654955ac87e118100d8b1d
|
||||||
|
timeCreated: 1747861633
|
8
Runtime.meta
Normal file
8
Runtime.meta
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e657351d63ffca146a291a3fe1b517b0
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
3
Runtime/Adapters.meta
Normal file
3
Runtime/Adapters.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 56735d71953b4e5385da5122c22cd6e1
|
||||||
|
timeCreated: 1747861237
|
60
Runtime/Adapters/ImageAdapter.cs
Normal file
60
Runtime/Adapters/ImageAdapter.cs
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
using System;
|
||||||
|
using DC.Animator.Core;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace DC.Animator.Adapters
|
||||||
|
{
|
||||||
|
public class ImageAdapter : IAnimatable
|
||||||
|
{
|
||||||
|
private readonly Image _image;
|
||||||
|
|
||||||
|
public ImageAdapter(Image image) => _image = image;
|
||||||
|
|
||||||
|
public bool SupportsProperty(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
return property switch
|
||||||
|
{
|
||||||
|
AnimatableProperty.Alpha or AnimatableProperty.Color => true,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public object GetValue(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
return property switch
|
||||||
|
{
|
||||||
|
AnimatableProperty.Alpha => _image.color.a,
|
||||||
|
AnimatableProperty.Color => _image.color,
|
||||||
|
_ => throw new ArgumentException($"ImageAdapter does not support property {property}")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue(AnimatableProperty property, object value)
|
||||||
|
{
|
||||||
|
switch (property)
|
||||||
|
{
|
||||||
|
case AnimatableProperty.Alpha:
|
||||||
|
var colorAlpha = _image.color;
|
||||||
|
colorAlpha.a = (float)value;
|
||||||
|
_image.color = colorAlpha;
|
||||||
|
break;
|
||||||
|
case AnimatableProperty.Color:
|
||||||
|
_image.color = (Color)value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"ImageAdapter does not support property {property}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type GetPropertyType(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
return property switch
|
||||||
|
{
|
||||||
|
AnimatableProperty.Alpha => typeof(float),
|
||||||
|
AnimatableProperty.Color => typeof(Color),
|
||||||
|
_ => throw new ArgumentException($"ImageAdapter does not support property {property}")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
Runtime/Adapters/ImageAdapter.cs.meta
Normal file
3
Runtime/Adapters/ImageAdapter.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6c004264ae534a60b0acc1e9b0a1fabf
|
||||||
|
timeCreated: 1747861252
|
77
Runtime/Adapters/RectTransformAdapter.cs
Normal file
77
Runtime/Adapters/RectTransformAdapter.cs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
using System;
|
||||||
|
using DC.Animator.Core;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DC.Animator.Adapters
|
||||||
|
{
|
||||||
|
public class RectTransformAdapter : IAnimatable
|
||||||
|
{
|
||||||
|
private readonly RectTransform _rectTransform;
|
||||||
|
|
||||||
|
public RectTransformAdapter(RectTransform rectTransform) => _rectTransform = rectTransform;
|
||||||
|
|
||||||
|
public bool SupportsProperty(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
return property switch
|
||||||
|
{
|
||||||
|
AnimatableProperty.Position or AnimatableProperty.LocalPosition or AnimatableProperty.AnchoredPosition
|
||||||
|
or AnimatableProperty.Scale or AnimatableProperty.Rotation
|
||||||
|
or AnimatableProperty.EulerAngles => true,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public object GetValue(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
return property switch
|
||||||
|
{
|
||||||
|
AnimatableProperty.Position => _rectTransform.position,
|
||||||
|
AnimatableProperty.LocalPosition => _rectTransform.localPosition,
|
||||||
|
AnimatableProperty.AnchoredPosition => _rectTransform.anchoredPosition,
|
||||||
|
AnimatableProperty.Scale => _rectTransform.localScale,
|
||||||
|
AnimatableProperty.Rotation => _rectTransform.rotation,
|
||||||
|
AnimatableProperty.EulerAngles => _rectTransform.eulerAngles,
|
||||||
|
_ => throw new ArgumentException($"RectTransformAdapter does not support property {property}")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue(AnimatableProperty property, object value)
|
||||||
|
{
|
||||||
|
switch (property)
|
||||||
|
{
|
||||||
|
case AnimatableProperty.Position:
|
||||||
|
_rectTransform.position = (Vector3)value;
|
||||||
|
break;
|
||||||
|
case AnimatableProperty.LocalPosition:
|
||||||
|
_rectTransform.localPosition = (Vector3)value;
|
||||||
|
break;
|
||||||
|
case AnimatableProperty.AnchoredPosition:
|
||||||
|
_rectTransform.anchoredPosition = (Vector2)value;
|
||||||
|
break;
|
||||||
|
case AnimatableProperty.Scale:
|
||||||
|
_rectTransform.localScale = (Vector3)value;
|
||||||
|
break;
|
||||||
|
case AnimatableProperty.Rotation:
|
||||||
|
_rectTransform.rotation = (Quaternion)value;
|
||||||
|
break;
|
||||||
|
case AnimatableProperty.EulerAngles:
|
||||||
|
_rectTransform.eulerAngles = (Vector3)value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"RectTransformAdapter does not support property {property}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type GetPropertyType(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
return property switch
|
||||||
|
{
|
||||||
|
AnimatableProperty.Position or AnimatableProperty.LocalPosition or AnimatableProperty.Scale
|
||||||
|
or AnimatableProperty.EulerAngles => typeof(Vector3),
|
||||||
|
AnimatableProperty.AnchoredPosition => typeof(Vector2),
|
||||||
|
AnimatableProperty.Rotation => typeof(Quaternion),
|
||||||
|
_ => throw new ArgumentException($"RectTransformAdapter does not support property {property}")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
Runtime/Adapters/RectTransformAdapter.cs.meta
Normal file
3
Runtime/Adapters/RectTransformAdapter.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3445d296a0bb42dc8cfe1d0f4ab762a1
|
||||||
|
timeCreated: 1747861417
|
59
Runtime/Adapters/SpriteAdapter.cs
Normal file
59
Runtime/Adapters/SpriteAdapter.cs
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
using System;
|
||||||
|
using DC.Animator.Core;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DC.Animator.Adapters
|
||||||
|
{
|
||||||
|
public class SpriteAdapter : IAnimatable
|
||||||
|
{
|
||||||
|
private readonly SpriteRenderer _spriteRenderer;
|
||||||
|
|
||||||
|
public SpriteAdapter(SpriteRenderer spriteRenderer) => _spriteRenderer = spriteRenderer;
|
||||||
|
|
||||||
|
public bool SupportsProperty(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
return property switch
|
||||||
|
{
|
||||||
|
AnimatableProperty.Alpha or AnimatableProperty.Color => true,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public object GetValue(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
return property switch
|
||||||
|
{
|
||||||
|
AnimatableProperty.Alpha => _spriteRenderer.color.a,
|
||||||
|
AnimatableProperty.Color => _spriteRenderer.color,
|
||||||
|
_ => throw new ArgumentException($"SpriteRendererAdapter does not support property {property}")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue(AnimatableProperty property, object value)
|
||||||
|
{
|
||||||
|
switch (property)
|
||||||
|
{
|
||||||
|
case AnimatableProperty.Alpha:
|
||||||
|
var colorAlpha = _spriteRenderer.color;
|
||||||
|
colorAlpha.a = (float)value;
|
||||||
|
_spriteRenderer.color = colorAlpha;
|
||||||
|
break;
|
||||||
|
case AnimatableProperty.Color:
|
||||||
|
_spriteRenderer.color = (Color)value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"SpriteRendererAdapter does not support property {property}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type GetPropertyType(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
return property switch
|
||||||
|
{
|
||||||
|
AnimatableProperty.Alpha => typeof(float),
|
||||||
|
AnimatableProperty.Color => typeof(Color),
|
||||||
|
_ => throw new ArgumentException($"SpriteRendererAdapter does not support property {property}")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
Runtime/Adapters/SpriteAdapter.cs.meta
Normal file
3
Runtime/Adapters/SpriteAdapter.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 81eaeba71eb74408976c0dbc72a8a454
|
||||||
|
timeCreated: 1747861361
|
63
Runtime/Adapters/TMPTextAdapter.cs
Normal file
63
Runtime/Adapters/TMPTextAdapter.cs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
using System;
|
||||||
|
using DC.Animator.Core;
|
||||||
|
using TMPro;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DC.Animator.Adapters
|
||||||
|
{
|
||||||
|
public class TMPTextAdapter : IAnimatable
|
||||||
|
{
|
||||||
|
private readonly TMP_Text _text;
|
||||||
|
|
||||||
|
public TMPTextAdapter(TMP_Text text) => _text = text;
|
||||||
|
|
||||||
|
public bool SupportsProperty(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
return property switch
|
||||||
|
{
|
||||||
|
AnimatableProperty.Alpha or AnimatableProperty.Color or AnimatableProperty.TextColor => true,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public object GetValue(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
return property switch
|
||||||
|
{
|
||||||
|
AnimatableProperty.Alpha => _text.alpha,
|
||||||
|
AnimatableProperty.Color or AnimatableProperty.TextColor => _text.color,
|
||||||
|
_ => throw new ArgumentException($"TextMeshProAdapter does not support property {property}")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue(AnimatableProperty property, object value)
|
||||||
|
{
|
||||||
|
switch (property)
|
||||||
|
{
|
||||||
|
case AnimatableProperty.Alpha:
|
||||||
|
_text.alpha = (float)value;
|
||||||
|
break;
|
||||||
|
case AnimatableProperty.Color:
|
||||||
|
case AnimatableProperty.TextColor:
|
||||||
|
_text.color = (Color)value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"TextMeshProAdapter does not support property {property}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type GetPropertyType(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
switch (property)
|
||||||
|
{
|
||||||
|
case AnimatableProperty.Alpha:
|
||||||
|
return typeof(float);
|
||||||
|
case AnimatableProperty.Color:
|
||||||
|
case AnimatableProperty.TextColor:
|
||||||
|
return typeof(Color);
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"TextMeshProAdapter does not support property {property}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
Runtime/Adapters/TMPTextAdapter.cs.meta
Normal file
3
Runtime/Adapters/TMPTextAdapter.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d707c0a42bba4df2bde5731ebda18905
|
||||||
|
timeCreated: 1747861307
|
71
Runtime/Adapters/TransformAdapter.cs
Normal file
71
Runtime/Adapters/TransformAdapter.cs
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
using System;
|
||||||
|
using DC.Animator.Core;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DC.Animator.Adapters
|
||||||
|
{
|
||||||
|
public class TransformAdapter : IAnimatable
|
||||||
|
{
|
||||||
|
private readonly Transform _transform;
|
||||||
|
|
||||||
|
public TransformAdapter(Transform transform) => _transform = transform;
|
||||||
|
|
||||||
|
public bool SupportsProperty(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
return property switch
|
||||||
|
{
|
||||||
|
AnimatableProperty.Position or AnimatableProperty.LocalPosition or AnimatableProperty.Scale
|
||||||
|
or AnimatableProperty.Rotation or AnimatableProperty.EulerAngles => true,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public object GetValue(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
return property switch
|
||||||
|
{
|
||||||
|
AnimatableProperty.Position => _transform.position,
|
||||||
|
AnimatableProperty.LocalPosition => _transform.localPosition,
|
||||||
|
AnimatableProperty.Scale => _transform.localScale,
|
||||||
|
AnimatableProperty.Rotation => _transform.rotation,
|
||||||
|
AnimatableProperty.EulerAngles => _transform.eulerAngles,
|
||||||
|
_ => throw new ArgumentException($"TransformAdapter does not support property {property}")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue(AnimatableProperty property, object value)
|
||||||
|
{
|
||||||
|
switch (property)
|
||||||
|
{
|
||||||
|
case AnimatableProperty.Position:
|
||||||
|
_transform.position = (Vector3)value;
|
||||||
|
break;
|
||||||
|
case AnimatableProperty.LocalPosition:
|
||||||
|
_transform.localPosition = (Vector3)value;
|
||||||
|
break;
|
||||||
|
case AnimatableProperty.Scale:
|
||||||
|
_transform.localScale = (Vector3)value;
|
||||||
|
break;
|
||||||
|
case AnimatableProperty.Rotation:
|
||||||
|
_transform.rotation = (Quaternion)value;
|
||||||
|
break;
|
||||||
|
case AnimatableProperty.EulerAngles:
|
||||||
|
_transform.eulerAngles = (Vector3)value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"TransformAdapter does not support property {property}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type GetPropertyType(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
return property switch
|
||||||
|
{
|
||||||
|
AnimatableProperty.Position or AnimatableProperty.LocalPosition or AnimatableProperty.Scale
|
||||||
|
or AnimatableProperty.EulerAngles => typeof(Vector3),
|
||||||
|
AnimatableProperty.Rotation => typeof(Quaternion),
|
||||||
|
_ => throw new ArgumentException($"TransformAdapter does not support property {property}")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
Runtime/Adapters/TransformAdapter.cs.meta
Normal file
3
Runtime/Adapters/TransformAdapter.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 12a9475c333d43d0ade1f05f8bfd1283
|
||||||
|
timeCreated: 1747861386
|
3
Runtime/AnimationTypeBuilders.meta
Normal file
3
Runtime/AnimationTypeBuilders.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8c757291c27645019681e3bb8f24ef0f
|
||||||
|
timeCreated: 1747861055
|
53
Runtime/AnimationTypeBuilders/ColorAnimationBuilder.cs
Normal file
53
Runtime/AnimationTypeBuilders/ColorAnimationBuilder.cs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
using DC.Animator.Core;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DC.Animator.AnimationTypeBuilders
|
||||||
|
{
|
||||||
|
public class ColorAnimationBuilder : AnimationTypeBuilderBase
|
||||||
|
{
|
||||||
|
private Color _fromColor = Color.white;
|
||||||
|
private bool _hasFromColor;
|
||||||
|
private bool _isTextColor;
|
||||||
|
private Color _toColor = Color.white;
|
||||||
|
|
||||||
|
public ColorAnimationBuilder(AnimationBuilder baseBuilder) : base(baseBuilder) { }
|
||||||
|
|
||||||
|
public ColorAnimationBuilder From(Color color)
|
||||||
|
{
|
||||||
|
_fromColor = color;
|
||||||
|
_hasFromColor = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColorAnimationBuilder To(Color color)
|
||||||
|
{
|
||||||
|
_toColor = color;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColorAnimationBuilder FromCurrent()
|
||||||
|
{
|
||||||
|
_hasFromColor = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColorAnimationBuilder AsTextColor()
|
||||||
|
{
|
||||||
|
_isTextColor = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IAnimation Build()
|
||||||
|
{
|
||||||
|
var animation = BaseBuilder.Build();
|
||||||
|
|
||||||
|
var property = _isTextColor ? AnimatableProperty.TextColor : AnimatableProperty.Color;
|
||||||
|
|
||||||
|
if (!_hasFromColor) _fromColor = (Color)animation.GetValue(property);
|
||||||
|
|
||||||
|
animation.SetProperty(property, _fromColor, _toColor);
|
||||||
|
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 906d0b3b5c8a480cbca966bd4f505e12
|
||||||
|
timeCreated: 1747861219
|
32
Runtime/AnimationTypeBuilders/FadeAnimationBuilder.cs
Normal file
32
Runtime/AnimationTypeBuilders/FadeAnimationBuilder.cs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
using DC.Animator.Core;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DC.Animator.AnimationTypeBuilders
|
||||||
|
{
|
||||||
|
public class FadeAnimationBuilder : AnimationTypeBuilderBase
|
||||||
|
{
|
||||||
|
private float _fromAlpha;
|
||||||
|
private float _toAlpha = 1f;
|
||||||
|
|
||||||
|
public FadeAnimationBuilder(AnimationBuilder baseBuilder) : base(baseBuilder) { }
|
||||||
|
|
||||||
|
public FadeAnimationBuilder From(float alpha)
|
||||||
|
{
|
||||||
|
_fromAlpha = Mathf.Clamp01(alpha);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FadeAnimationBuilder To(float alpha)
|
||||||
|
{
|
||||||
|
_toAlpha = Mathf.Clamp01(alpha);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IAnimation Build()
|
||||||
|
{
|
||||||
|
var animation = BaseBuilder.Build();
|
||||||
|
animation.SetProperty(AnimatableProperty.Alpha, _fromAlpha, _toAlpha);
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 87ca0a0406324a70a8a5f7e8bd289a99
|
||||||
|
timeCreated: 1747861075
|
76
Runtime/AnimationTypeBuilders/MoveAnimationBuilder.cs
Normal file
76
Runtime/AnimationTypeBuilders/MoveAnimationBuilder.cs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
using DC.Animator.Core;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DC.Animator.AnimationTypeBuilders
|
||||||
|
{
|
||||||
|
public class MoveAnimationBuilder : AnimationTypeBuilderBase
|
||||||
|
{
|
||||||
|
private Vector3 _fromPosition;
|
||||||
|
private bool _hasFromPosition;
|
||||||
|
private bool _hasToPosition;
|
||||||
|
private bool _isAnchored;
|
||||||
|
private bool _isLocal;
|
||||||
|
private Vector3 _toPosition;
|
||||||
|
|
||||||
|
public MoveAnimationBuilder(AnimationBuilder baseBuilder) : base(baseBuilder) { }
|
||||||
|
|
||||||
|
public MoveAnimationBuilder From(Vector3 position)
|
||||||
|
{
|
||||||
|
_fromPosition = position;
|
||||||
|
_hasFromPosition = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MoveAnimationBuilder To(Vector3 position)
|
||||||
|
{
|
||||||
|
_toPosition = position;
|
||||||
|
_hasToPosition = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MoveAnimationBuilder FromCurrent()
|
||||||
|
{
|
||||||
|
_hasFromPosition = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MoveAnimationBuilder Local()
|
||||||
|
{
|
||||||
|
_isLocal = true;
|
||||||
|
_isAnchored = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MoveAnimationBuilder Anchored()
|
||||||
|
{
|
||||||
|
_isAnchored = true;
|
||||||
|
_isLocal = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IAnimation Build()
|
||||||
|
{
|
||||||
|
var animation = BaseBuilder.Build();
|
||||||
|
AnimatableProperty property;
|
||||||
|
|
||||||
|
if (_isLocal)
|
||||||
|
property = AnimatableProperty.LocalPosition;
|
||||||
|
else if (_isAnchored)
|
||||||
|
property = AnimatableProperty.AnchoredPosition;
|
||||||
|
else
|
||||||
|
property = AnimatableProperty.Position;
|
||||||
|
|
||||||
|
if (!_hasFromPosition) _fromPosition = (Vector3)animation.GetValue(property);
|
||||||
|
|
||||||
|
if (!_hasToPosition)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("No target position specified for move animation");
|
||||||
|
_toPosition = _fromPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
animation.SetProperty(property, _fromPosition, _toPosition);
|
||||||
|
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 800d1b5a42e24886b87d95dab0e1df99
|
||||||
|
timeCreated: 1747861100
|
87
Runtime/AnimationTypeBuilders/RotateAnimationBuilder.cs
Normal file
87
Runtime/AnimationTypeBuilders/RotateAnimationBuilder.cs
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
using DC.Animator.Core;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DC.Animator.AnimationTypeBuilders
|
||||||
|
{
|
||||||
|
public class RotateAnimationBuilder : AnimationTypeBuilderBase
|
||||||
|
{
|
||||||
|
private Vector3 _fromEulerAngles;
|
||||||
|
private Vector3 _toEulerAngles;
|
||||||
|
private Quaternion _fromRotation;
|
||||||
|
private Quaternion _toRotation;
|
||||||
|
private bool _hasFromRotation;
|
||||||
|
private bool _useEuler = true;
|
||||||
|
|
||||||
|
public RotateAnimationBuilder(AnimationBuilder baseBuilder) : base(baseBuilder) { }
|
||||||
|
|
||||||
|
public RotateAnimationBuilder FromEuler(Vector3 eulerAngles)
|
||||||
|
{
|
||||||
|
_fromEulerAngles = eulerAngles;
|
||||||
|
_fromRotation = Quaternion.Euler(eulerAngles);
|
||||||
|
_hasFromRotation = true;
|
||||||
|
_useEuler = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RotateAnimationBuilder ToEuler(Vector3 eulerAngles)
|
||||||
|
{
|
||||||
|
_toEulerAngles = eulerAngles;
|
||||||
|
_toRotation = Quaternion.Euler(eulerAngles);
|
||||||
|
_useEuler = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RotateAnimationBuilder FromQuaternion(Quaternion rotation)
|
||||||
|
{
|
||||||
|
_fromRotation = rotation;
|
||||||
|
_fromEulerAngles = rotation.eulerAngles;
|
||||||
|
_hasFromRotation = true;
|
||||||
|
_useEuler = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RotateAnimationBuilder ToQuaternion(Quaternion rotation)
|
||||||
|
{
|
||||||
|
_toRotation = rotation;
|
||||||
|
_toEulerAngles = rotation.eulerAngles;
|
||||||
|
_useEuler = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RotateAnimationBuilder FromCurrent()
|
||||||
|
{
|
||||||
|
_hasFromRotation = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IAnimation Build()
|
||||||
|
{
|
||||||
|
var animation = BaseBuilder.Build();
|
||||||
|
|
||||||
|
var property = _useEuler ?
|
||||||
|
AnimatableProperty.EulerAngles :
|
||||||
|
AnimatableProperty.Rotation;
|
||||||
|
|
||||||
|
if (!_hasFromRotation)
|
||||||
|
{
|
||||||
|
if (_useEuler)
|
||||||
|
{
|
||||||
|
_fromEulerAngles = (Vector3)animation.GetValue(AnimatableProperty.EulerAngles);
|
||||||
|
_fromRotation = Quaternion.Euler(_fromEulerAngles);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_fromRotation = (Quaternion)animation.GetValue(AnimatableProperty.Rotation);
|
||||||
|
_fromEulerAngles = _fromRotation.eulerAngles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var fromValue = _useEuler ? (object)_fromEulerAngles : _fromRotation;
|
||||||
|
var toValue = _useEuler ? (object)_toEulerAngles : _toRotation;
|
||||||
|
|
||||||
|
animation.SetProperty(property, fromValue, toValue);
|
||||||
|
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 735103945dcb47a9b677d3f57350514f
|
||||||
|
timeCreated: 1747861191
|
57
Runtime/AnimationTypeBuilders/ScaleAnimationBuilder.cs
Normal file
57
Runtime/AnimationTypeBuilders/ScaleAnimationBuilder.cs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
using DC.Animator.Core;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DC.Animator.AnimationTypeBuilders
|
||||||
|
{
|
||||||
|
public class ScaleAnimationBuilder : AnimationTypeBuilderBase
|
||||||
|
{
|
||||||
|
private Vector3 _fromScale = Vector3.one;
|
||||||
|
private bool _hasFromScale;
|
||||||
|
private Vector3 _toScale = Vector3.one;
|
||||||
|
|
||||||
|
public ScaleAnimationBuilder(AnimationBuilder baseBuilder) : base(baseBuilder) { }
|
||||||
|
|
||||||
|
public ScaleAnimationBuilder From(Vector3 scale)
|
||||||
|
{
|
||||||
|
_fromScale = scale;
|
||||||
|
_hasFromScale = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScaleAnimationBuilder From(float uniformScale)
|
||||||
|
{
|
||||||
|
_fromScale = new Vector3(uniformScale, uniformScale, uniformScale);
|
||||||
|
_hasFromScale = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScaleAnimationBuilder To(Vector3 scale)
|
||||||
|
{
|
||||||
|
_toScale = scale;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScaleAnimationBuilder To(float uniformScale)
|
||||||
|
{
|
||||||
|
_toScale = new Vector3(uniformScale, uniformScale, uniformScale);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScaleAnimationBuilder FromCurrent()
|
||||||
|
{
|
||||||
|
_hasFromScale = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IAnimation Build()
|
||||||
|
{
|
||||||
|
var animation = BaseBuilder.Build();
|
||||||
|
|
||||||
|
if (!_hasFromScale) _fromScale = (Vector3)animation.GetValue(AnimatableProperty.Scale);
|
||||||
|
|
||||||
|
animation.SetProperty(AnimatableProperty.Scale, _fromScale, _toScale);
|
||||||
|
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7b6cf6ed822b434d9635fa7841093483
|
||||||
|
timeCreated: 1747861159
|
3
Runtime/Core.meta
Normal file
3
Runtime/Core.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7305d0795bef4bc7b5554a9a57e6d05d
|
||||||
|
timeCreated: 1748092703
|
15
Runtime/Core/AnimatableProperty.cs
Normal file
15
Runtime/Core/AnimatableProperty.cs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
namespace DC.Animator.Core
|
||||||
|
{
|
||||||
|
public enum AnimatableProperty
|
||||||
|
{
|
||||||
|
Position,
|
||||||
|
LocalPosition,
|
||||||
|
AnchoredPosition,
|
||||||
|
Scale,
|
||||||
|
Rotation,
|
||||||
|
EulerAngles,
|
||||||
|
Alpha,
|
||||||
|
Color,
|
||||||
|
TextColor
|
||||||
|
}
|
||||||
|
}
|
3
Runtime/Core/AnimatableProperty.cs.meta
Normal file
3
Runtime/Core/AnimatableProperty.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8be1c4fca1da458487554a4860fbd09d
|
||||||
|
timeCreated: 1747860604
|
185
Runtime/Core/Animation.cs
Normal file
185
Runtime/Core/Animation.cs
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using DC.Animator.Utils;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DC.Animator.Core
|
||||||
|
{
|
||||||
|
public class Animation : IAnimation
|
||||||
|
{
|
||||||
|
private readonly Dictionary<AnimatableProperty, AnimationProperty> _properties = new();
|
||||||
|
private float _currentTime;
|
||||||
|
private float _delay;
|
||||||
|
private float _delayTimer;
|
||||||
|
private float _duration;
|
||||||
|
private Easing.Function _easingFunction;
|
||||||
|
private bool _hasStarted;
|
||||||
|
|
||||||
|
private IAnimatable _target;
|
||||||
|
|
||||||
|
public Animation() { }
|
||||||
|
|
||||||
|
public Animation(IAnimatable target, float duration, float delay, Easing.Function easingFunction)
|
||||||
|
{
|
||||||
|
_target = target;
|
||||||
|
_duration = Mathf.Max(duration, 0.001f); // Avoid division by zero
|
||||||
|
_delay = delay;
|
||||||
|
_easingFunction = easingFunction ?? Easing.Linear;
|
||||||
|
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsComplete { get; private set; }
|
||||||
|
public bool IsPlaying { get; private set; }
|
||||||
|
|
||||||
|
public event Action<IAnimation> OnStart;
|
||||||
|
public event Action<IAnimation> OnComplete;
|
||||||
|
public event Action<IAnimation> OnUpdate;
|
||||||
|
|
||||||
|
public void SetProperty(AnimatableProperty property, object fromValue, object toValue)
|
||||||
|
{
|
||||||
|
if (!_target.SupportsProperty(property))
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"Target does not support property {property}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var propertyType = _target.GetPropertyType(property);
|
||||||
|
|
||||||
|
_properties[property] = new AnimationProperty
|
||||||
|
{
|
||||||
|
FromValue = fromValue,
|
||||||
|
ToValue = toValue,
|
||||||
|
PropertyType = propertyType
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public object GetValue(AnimatableProperty property)
|
||||||
|
{
|
||||||
|
if (_target != null && _target.SupportsProperty(property)) return _target.GetValue(property);
|
||||||
|
throw new ArgumentException(
|
||||||
|
$"Cannot get value for property {property}. Either target is null or property is not supported.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
if (IsPlaying) return;
|
||||||
|
|
||||||
|
IsPlaying = true;
|
||||||
|
IsComplete = false;
|
||||||
|
_currentTime = 0;
|
||||||
|
_delayTimer = 0;
|
||||||
|
_hasStarted = false;
|
||||||
|
|
||||||
|
foreach (var prop in _properties) _target.SetValue(prop.Key, prop.Value.FromValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Pause()
|
||||||
|
{
|
||||||
|
IsPlaying = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Resume()
|
||||||
|
{
|
||||||
|
if (!IsComplete) IsPlaying = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
IsPlaying = false;
|
||||||
|
|
||||||
|
foreach (var prop in _properties) _target.SetValue(prop.Key, prop.Value.ToValue);
|
||||||
|
|
||||||
|
IsComplete = true;
|
||||||
|
OnComplete?.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(float deltaTime)
|
||||||
|
{
|
||||||
|
if (!IsPlaying || IsComplete) return;
|
||||||
|
|
||||||
|
if (_delay > 0 && _delayTimer < _delay)
|
||||||
|
{
|
||||||
|
_delayTimer += deltaTime;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_hasStarted)
|
||||||
|
{
|
||||||
|
_hasStarted = true;
|
||||||
|
OnStart?.Invoke(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentTime += deltaTime;
|
||||||
|
var normalizedTime = Mathf.Clamp01(_currentTime / _duration);
|
||||||
|
var easedTime = _easingFunction(normalizedTime);
|
||||||
|
|
||||||
|
foreach (var prop in _properties)
|
||||||
|
{
|
||||||
|
var interpolatedValue = InterpolateValue(
|
||||||
|
prop.Value.FromValue,
|
||||||
|
prop.Value.ToValue,
|
||||||
|
easedTime,
|
||||||
|
prop.Value.PropertyType
|
||||||
|
);
|
||||||
|
|
||||||
|
_target.SetValue(prop.Key, interpolatedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
OnUpdate?.Invoke(this);
|
||||||
|
|
||||||
|
if (_currentTime >= _duration)
|
||||||
|
{
|
||||||
|
IsPlaying = false;
|
||||||
|
IsComplete = true;
|
||||||
|
OnComplete?.Invoke(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
IsComplete = false;
|
||||||
|
IsPlaying = false;
|
||||||
|
_hasStarted = false;
|
||||||
|
_currentTime = 0;
|
||||||
|
_delayTimer = 0;
|
||||||
|
_properties.Clear();
|
||||||
|
|
||||||
|
OnStart = null;
|
||||||
|
OnComplete = null;
|
||||||
|
OnUpdate = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize(IAnimatable target, float duration, float delay, Easing.Function easingFunction)
|
||||||
|
{
|
||||||
|
_target = target;
|
||||||
|
_duration = Mathf.Max(duration, 0.001f);
|
||||||
|
_delay = delay;
|
||||||
|
_easingFunction = easingFunction ?? Easing.Linear;
|
||||||
|
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private object InterpolateValue(object from, object to, float t, Type propertyType)
|
||||||
|
{
|
||||||
|
if (propertyType == typeof(float)) return Mathf.Lerp((float)from, (float)to, t);
|
||||||
|
|
||||||
|
if (propertyType == typeof(Vector2)) return Vector2.Lerp((Vector2)from, (Vector2)to, t);
|
||||||
|
|
||||||
|
if (propertyType == typeof(Vector3)) return Vector3.Lerp((Vector3)from, (Vector3)to, t);
|
||||||
|
|
||||||
|
if (propertyType == typeof(Color)) return Color.Lerp((Color)from, (Color)to, t);
|
||||||
|
|
||||||
|
if (propertyType == typeof(Quaternion)) return Quaternion.Slerp((Quaternion)from, (Quaternion)to, t);
|
||||||
|
|
||||||
|
return t < 0.5f ? from : to;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AnimationProperty
|
||||||
|
{
|
||||||
|
public object FromValue;
|
||||||
|
public Type PropertyType;
|
||||||
|
public object ToValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
Runtime/Core/Animation.cs.meta
Normal file
3
Runtime/Core/Animation.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a3d35500f1f6469cb3baa292cfc1f882
|
||||||
|
timeCreated: 1747860896
|
136
Runtime/Core/AnimationBuilder.cs
Normal file
136
Runtime/Core/AnimationBuilder.cs
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using DC.Animator.Adapters;
|
||||||
|
using DC.Animator.AnimationTypeBuilders;
|
||||||
|
using DC.Animator.Utils;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DC.Animator.Core
|
||||||
|
{
|
||||||
|
public sealed class AnimationBuilder
|
||||||
|
{
|
||||||
|
private IAnimatable _target;
|
||||||
|
private float _duration = 1f;
|
||||||
|
private float _delay;
|
||||||
|
private Easing.Type _easingType = Easing.Type.Linear;
|
||||||
|
private Action<IAnimation> _onStart;
|
||||||
|
private Action<IAnimation> _onComplete;
|
||||||
|
private Action<IAnimation> _onUpdate;
|
||||||
|
private static readonly Dictionary<Type, Func<object, IAnimatable>> AdapterFactories = new();
|
||||||
|
|
||||||
|
static AnimationBuilder()
|
||||||
|
{
|
||||||
|
RegisterAdapter<UnityEngine.UI.Image>((img) => new ImageAdapter(img));
|
||||||
|
RegisterAdapter<TMPro.TextMeshProUGUI>((text) => new TMPTextAdapter(text));
|
||||||
|
RegisterAdapter<TMPro.TextMeshPro>((text) => new TMPTextAdapter(text));
|
||||||
|
RegisterAdapter<SpriteRenderer>((sprite) => new SpriteAdapter(sprite));
|
||||||
|
RegisterAdapter<Transform>((transform) => new TransformAdapter(transform));
|
||||||
|
RegisterAdapter<RectTransform>((rectTransform) => new RectTransformAdapter(rectTransform));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RegisterAdapter<T>(Func<T, IAnimatable> adapterFactory)
|
||||||
|
{
|
||||||
|
AdapterFactories[typeof(T)] = obj => adapterFactory((T)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IAnimatable GetAdapter(object target)
|
||||||
|
{
|
||||||
|
var type = target.GetType();
|
||||||
|
|
||||||
|
if (AdapterFactories.TryGetValue(type, out var factory))
|
||||||
|
return factory(target);
|
||||||
|
|
||||||
|
foreach (var entry in AdapterFactories)
|
||||||
|
{
|
||||||
|
if (entry.Key.IsAssignableFrom(type))
|
||||||
|
return entry.Value(target);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AnimationBuilder For<T>(T target) where T : UnityEngine.Object
|
||||||
|
{
|
||||||
|
var adapter = GetAdapter(target);
|
||||||
|
if (adapter != null) return new AnimationBuilder().WithTarget(adapter);
|
||||||
|
Debug.LogError($"No animation adapter registered for {typeof(T).Name}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationBuilder WithTarget(IAnimatable target)
|
||||||
|
{
|
||||||
|
_target = target;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationBuilder WithDuration(float duration)
|
||||||
|
{
|
||||||
|
_duration = Mathf.Max(0.001f, duration);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationBuilder WithDelay(float delay)
|
||||||
|
{
|
||||||
|
_delay = Mathf.Max(0, delay);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationBuilder WithEasing(Easing.Type easingType)
|
||||||
|
{
|
||||||
|
_easingType = easingType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationBuilder OnStart(Action<IAnimation> callback)
|
||||||
|
{
|
||||||
|
_onStart = callback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationBuilder OnComplete(Action<IAnimation> callback)
|
||||||
|
{
|
||||||
|
_onComplete = callback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationBuilder OnUpdate(Action<IAnimation> callback)
|
||||||
|
{
|
||||||
|
_onUpdate = callback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FadeAnimationBuilder AsFade() => new(this);
|
||||||
|
|
||||||
|
public MoveAnimationBuilder AsMove() => new(this);
|
||||||
|
|
||||||
|
public ScaleAnimationBuilder AsScale() => new(this);
|
||||||
|
|
||||||
|
public RotateAnimationBuilder AsRotate() => new(this);
|
||||||
|
|
||||||
|
public ColorAnimationBuilder AsColor() => new(this);
|
||||||
|
|
||||||
|
public IAnimation Build()
|
||||||
|
{
|
||||||
|
var easingFunction = Easing.GetEasingFunction(_easingType);
|
||||||
|
var animation = AnimationRuntime.Instance.CreateAnimation(_target, _duration, _delay, easingFunction);
|
||||||
|
|
||||||
|
if (_onStart != null)
|
||||||
|
animation.OnStart += _onStart;
|
||||||
|
|
||||||
|
if (_onComplete != null)
|
||||||
|
animation.OnComplete += _onComplete;
|
||||||
|
|
||||||
|
if (_onUpdate != null)
|
||||||
|
animation.OnUpdate += _onUpdate;
|
||||||
|
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAnimation Start()
|
||||||
|
{
|
||||||
|
var animation = Build();
|
||||||
|
AnimationRuntime.Instance.RegisterAnimation(animation);
|
||||||
|
animation.Start();
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
Runtime/Core/AnimationBuilder.cs.meta
Normal file
3
Runtime/Core/AnimationBuilder.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7363902fe7234f8296b9860043ae5a31
|
||||||
|
timeCreated: 1747861027
|
95
Runtime/Core/AnimationRuntime.cs
Normal file
95
Runtime/Core/AnimationRuntime.cs
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using DC.Animator.Utils;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DC.Animator.Core
|
||||||
|
{
|
||||||
|
public class AnimationRuntime : MonoBehaviour
|
||||||
|
{
|
||||||
|
private static AnimationRuntime _instance;
|
||||||
|
|
||||||
|
private readonly List<IAnimation> _activeAnimations = new();
|
||||||
|
private readonly ObjectPool<Animation> _animationPool = new(() => new Animation());
|
||||||
|
private readonly List<IAnimation> _pendingAdditions = new();
|
||||||
|
private readonly List<IAnimation> _pendingRemovals = new();
|
||||||
|
|
||||||
|
public static AnimationRuntime Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_instance) return _instance;
|
||||||
|
|
||||||
|
var go = new GameObject("AnimationManager");
|
||||||
|
_instance = go.AddComponent<AnimationRuntime>();
|
||||||
|
DontDestroyOnLoad(go);
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
if (_instance && _instance != this)
|
||||||
|
{
|
||||||
|
Destroy(gameObject);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_instance = this;
|
||||||
|
DontDestroyOnLoad(gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (_pendingAdditions.Count > 0)
|
||||||
|
{
|
||||||
|
_activeAnimations.AddRange(_pendingAdditions);
|
||||||
|
_pendingAdditions.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
var deltaTime = Time.deltaTime;
|
||||||
|
foreach (var animation in _activeAnimations)
|
||||||
|
{
|
||||||
|
animation.Update(deltaTime);
|
||||||
|
|
||||||
|
if (animation.IsComplete) _pendingRemovals.Add(animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_pendingRemovals.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var animation in _pendingRemovals)
|
||||||
|
{
|
||||||
|
_activeAnimations.Remove(animation);
|
||||||
|
ReturnToPool(animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
_pendingRemovals.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterAnimation(IAnimation animation)
|
||||||
|
{
|
||||||
|
_pendingAdditions.Add(animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReturnToPool(IAnimation animation)
|
||||||
|
{
|
||||||
|
if (animation is not Animation pooledAnimation) return;
|
||||||
|
|
||||||
|
pooledAnimation.Reset();
|
||||||
|
_animationPool.Return(pooledAnimation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Animation GetFromPool()
|
||||||
|
{
|
||||||
|
return _animationPool.Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Animation CreateAnimation(IAnimatable target, float duration, float delay,
|
||||||
|
Easing.Function easingFunction)
|
||||||
|
{
|
||||||
|
var animation = _animationPool.Get();
|
||||||
|
animation.Initialize(target, duration, delay, easingFunction);
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
Runtime/Core/AnimationRuntime.cs.meta
Normal file
3
Runtime/Core/AnimationRuntime.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e9a1adb612d743eb87fca704d4335d1b
|
||||||
|
timeCreated: 1747860933
|
61
Runtime/Core/AnimationTypeBuilderBase.cs
Normal file
61
Runtime/Core/AnimationTypeBuilderBase.cs
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
using System;
|
||||||
|
using DC.Animator.Utils;
|
||||||
|
|
||||||
|
namespace DC.Animator.Core
|
||||||
|
{
|
||||||
|
public abstract class AnimationTypeBuilderBase
|
||||||
|
{
|
||||||
|
protected AnimationBuilder BaseBuilder { get; }
|
||||||
|
|
||||||
|
protected AnimationTypeBuilderBase(AnimationBuilder baseBuilder)
|
||||||
|
{
|
||||||
|
BaseBuilder = baseBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationTypeBuilderBase WithDuration(float duration)
|
||||||
|
{
|
||||||
|
BaseBuilder.WithDuration(duration);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationTypeBuilderBase WithDelay(float delay)
|
||||||
|
{
|
||||||
|
BaseBuilder.WithDelay(delay);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationTypeBuilderBase WithEasing(Easing.Type easingType)
|
||||||
|
{
|
||||||
|
BaseBuilder.WithEasing(easingType);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationTypeBuilderBase OnStart(Action<IAnimation> callback)
|
||||||
|
{
|
||||||
|
BaseBuilder.OnStart(callback);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationTypeBuilderBase OnComplete(Action<IAnimation> callback)
|
||||||
|
{
|
||||||
|
BaseBuilder.OnComplete(callback);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationTypeBuilderBase OnUpdate(Action<IAnimation> callback)
|
||||||
|
{
|
||||||
|
BaseBuilder.OnUpdate(callback);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract IAnimation Build();
|
||||||
|
|
||||||
|
public virtual IAnimation Start()
|
||||||
|
{
|
||||||
|
var animation = Build();
|
||||||
|
AnimationRuntime.Instance.RegisterAnimation(animation);
|
||||||
|
animation.Start();
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
Runtime/Core/AnimationTypeBuilderBase.cs.meta
Normal file
2
Runtime/Core/AnimationTypeBuilderBase.cs.meta
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b3992f2125ccd5e4686b9f5aba900567
|
12
Runtime/Core/IAnimatable.cs
Normal file
12
Runtime/Core/IAnimatable.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DC.Animator.Core
|
||||||
|
{
|
||||||
|
public interface IAnimatable
|
||||||
|
{
|
||||||
|
bool SupportsProperty(AnimatableProperty property);
|
||||||
|
object GetValue(AnimatableProperty property);
|
||||||
|
void SetValue(AnimatableProperty property, object value);
|
||||||
|
Type GetPropertyType(AnimatableProperty property);
|
||||||
|
}
|
||||||
|
}
|
3
Runtime/Core/IAnimatable.cs.meta
Normal file
3
Runtime/Core/IAnimatable.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b60cedf76ef14da8830e3b09f87fed52
|
||||||
|
timeCreated: 1747860577
|
23
Runtime/Core/IAnimation.cs
Normal file
23
Runtime/Core/IAnimation.cs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DC.Animator.Core
|
||||||
|
{
|
||||||
|
public interface IAnimation
|
||||||
|
{
|
||||||
|
bool IsComplete { get; }
|
||||||
|
bool IsPlaying { get; }
|
||||||
|
|
||||||
|
void Start();
|
||||||
|
void Pause();
|
||||||
|
void Resume();
|
||||||
|
void Stop();
|
||||||
|
void Update(float deltaTime);
|
||||||
|
|
||||||
|
void SetProperty(AnimatableProperty property, object fromValue, object toValue);
|
||||||
|
object GetValue(AnimatableProperty property);
|
||||||
|
|
||||||
|
event Action<IAnimation> OnStart;
|
||||||
|
event Action<IAnimation> OnComplete;
|
||||||
|
event Action<IAnimation> OnUpdate;
|
||||||
|
}
|
||||||
|
}
|
2
Runtime/Core/IAnimation.cs.meta
Normal file
2
Runtime/Core/IAnimation.cs.meta
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 81f201c1b2e3c4845b9becc70b689633
|
3
Runtime/Data.meta
Normal file
3
Runtime/Data.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e430bcc3743b4759ae5d6319ba0c6203
|
||||||
|
timeCreated: 1747861443
|
101
Runtime/Data/AnimationCollection.cs
Normal file
101
Runtime/Data/AnimationCollection.cs
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using DC.Animator.Core;
|
||||||
|
using DCAnimator.Data;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DC.Animator.Data
|
||||||
|
{
|
||||||
|
[CreateAssetMenu(fileName = "New Collection", menuName = "DCAnimator/Animation Collection")]
|
||||||
|
public class AnimationCollection : ScriptableObject
|
||||||
|
{
|
||||||
|
public enum AnimationType
|
||||||
|
{
|
||||||
|
Fade,
|
||||||
|
Move,
|
||||||
|
Scale,
|
||||||
|
Rotate,
|
||||||
|
Color
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AnimationData> animations = new();
|
||||||
|
|
||||||
|
public IAnimation CreateAnimation(IAnimatable target)
|
||||||
|
{
|
||||||
|
return animations.Count == 0 ? null : CreateAnimation(target, animations[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAnimation CreateAnimation(IAnimatable target, string name)
|
||||||
|
{
|
||||||
|
foreach (var animData in animations)
|
||||||
|
if (animData.name == name)
|
||||||
|
return CreateAnimation(target, animData);
|
||||||
|
|
||||||
|
Debug.LogWarning($"Animation preset {name} not found");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IAnimation CreateAnimation(IAnimatable target, AnimationData data)
|
||||||
|
{
|
||||||
|
var builder = new AnimationBuilder()
|
||||||
|
.WithTarget(target)
|
||||||
|
.WithDuration(data.duration)
|
||||||
|
.WithDelay(data.delay)
|
||||||
|
.WithEasing(data.easingType);
|
||||||
|
|
||||||
|
IAnimation animation;
|
||||||
|
|
||||||
|
switch (data.type)
|
||||||
|
{
|
||||||
|
case AnimationType.Fade:
|
||||||
|
animation = builder.AsFade()
|
||||||
|
.From(data.fromAlpha)
|
||||||
|
.To(data.toAlpha)
|
||||||
|
.Build();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnimationType.Move:
|
||||||
|
var moveBuilder = builder.AsMove()
|
||||||
|
.From(data.fromPosition)
|
||||||
|
.To(data.toPosition);
|
||||||
|
|
||||||
|
if (data.useLocalPosition)
|
||||||
|
moveBuilder.Local();
|
||||||
|
else if (data.useAnchoredPosition)
|
||||||
|
moveBuilder.Anchored();
|
||||||
|
|
||||||
|
animation = moveBuilder.Build();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnimationType.Scale:
|
||||||
|
animation = builder.AsScale()
|
||||||
|
.From(data.fromScale)
|
||||||
|
.To(data.toScale)
|
||||||
|
.Build();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnimationType.Rotate:
|
||||||
|
animation = builder.AsRotate()
|
||||||
|
.FromEuler(data.fromEulerAngles)
|
||||||
|
.ToEuler(data.toEulerAngles)
|
||||||
|
.Build();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AnimationType.Color:
|
||||||
|
var colorBuilder = builder.AsColor()
|
||||||
|
.From(data.fromColor)
|
||||||
|
.To(data.toColor);
|
||||||
|
|
||||||
|
if (data.isTextColor)
|
||||||
|
colorBuilder.AsTextColor();
|
||||||
|
|
||||||
|
animation = colorBuilder.Build();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
Runtime/Data/AnimationCollection.cs.meta
Normal file
3
Runtime/Data/AnimationCollection.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 19427cdf82c041459cba5387f8783925
|
||||||
|
timeCreated: 1747861458
|
41
Runtime/Data/AnimationData.cs
Normal file
41
Runtime/Data/AnimationData.cs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
using System;
|
||||||
|
using DC.Animator.Data;
|
||||||
|
using DC.Animator.Utils;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DCAnimator.Data
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class AnimationData
|
||||||
|
{
|
||||||
|
// Core properties
|
||||||
|
public string name;
|
||||||
|
public AnimationCollection.AnimationType type;
|
||||||
|
public float duration = 0.5f;
|
||||||
|
public float delay;
|
||||||
|
public Easing.Type easingType = Easing.Type.EaseOutQuad;
|
||||||
|
|
||||||
|
// Fade properties
|
||||||
|
public float fromAlpha;
|
||||||
|
public float toAlpha = 1f;
|
||||||
|
|
||||||
|
// Move properties
|
||||||
|
public Vector3 fromPosition;
|
||||||
|
public Vector3 toPosition;
|
||||||
|
public bool useLocalPosition = true;
|
||||||
|
public bool useAnchoredPosition;
|
||||||
|
|
||||||
|
// Scale properties
|
||||||
|
public Vector3 fromScale = Vector3.one;
|
||||||
|
public Vector3 toScale = Vector3.one;
|
||||||
|
|
||||||
|
// Rotate properties
|
||||||
|
public Vector3 fromEulerAngles;
|
||||||
|
public Vector3 toEulerAngles;
|
||||||
|
|
||||||
|
// Color properties
|
||||||
|
public Color fromColor = Color.white;
|
||||||
|
public Color toColor = Color.white;
|
||||||
|
public bool isTextColor;
|
||||||
|
}
|
||||||
|
}
|
3
Runtime/Data/AnimationData.cs.meta
Normal file
3
Runtime/Data/AnimationData.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5c42bc264cb1491aae30842803feb809
|
||||||
|
timeCreated: 1748092986
|
3
Runtime/Utils.meta
Normal file
3
Runtime/Utils.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b1241ae5d1614af4a88116a9e43b8bf5
|
||||||
|
timeCreated: 1748092717
|
278
Runtime/Utils/EasingFunctions.cs
Normal file
278
Runtime/Utils/EasingFunctions.cs
Normal file
|
@ -0,0 +1,278 @@
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DC.Animator.Utils
|
||||||
|
{
|
||||||
|
public static class Easing
|
||||||
|
{
|
||||||
|
public delegate float Function(float t);
|
||||||
|
|
||||||
|
public enum Type
|
||||||
|
{
|
||||||
|
Linear,
|
||||||
|
EaseInSine,
|
||||||
|
EaseOutSine,
|
||||||
|
EaseInOutSine,
|
||||||
|
EaseInQuad,
|
||||||
|
EaseOutQuad,
|
||||||
|
EaseInOutQuad,
|
||||||
|
EaseInCubic,
|
||||||
|
EaseOutCubic,
|
||||||
|
EaseInOutCubic,
|
||||||
|
EaseInQuart,
|
||||||
|
EaseOutQuart,
|
||||||
|
EaseInOutQuart,
|
||||||
|
EaseInQuint,
|
||||||
|
EaseOutQuint,
|
||||||
|
EaseInOutQuint,
|
||||||
|
EaseInExpo,
|
||||||
|
EaseOutExpo,
|
||||||
|
EaseInOutExpo,
|
||||||
|
EaseInCirc,
|
||||||
|
EaseOutCirc,
|
||||||
|
EaseInOutCirc,
|
||||||
|
EaseInBack,
|
||||||
|
EaseOutBack,
|
||||||
|
EaseInOutBack,
|
||||||
|
EaseInElastic,
|
||||||
|
EaseOutElastic,
|
||||||
|
EaseInOutElastic,
|
||||||
|
EaseInBounce,
|
||||||
|
EaseOutBounce,
|
||||||
|
EaseInOutBounce
|
||||||
|
}
|
||||||
|
|
||||||
|
private const float PI = Mathf.PI;
|
||||||
|
private const float C1 = 1.70158f;
|
||||||
|
private const float C2 = C1 * 1.525f;
|
||||||
|
private const float C3 = C1 + 1f;
|
||||||
|
private const float C4 = 2f * PI / 3f;
|
||||||
|
private const float C5 = 2f * PI / 4.5f;
|
||||||
|
|
||||||
|
public static Function GetEasingFunction(Type type)
|
||||||
|
{
|
||||||
|
return type switch
|
||||||
|
{
|
||||||
|
Type.Linear => Linear,
|
||||||
|
Type.EaseInSine => EaseInSine,
|
||||||
|
Type.EaseOutSine => EaseOutSine,
|
||||||
|
Type.EaseInOutSine => EaseInOutSine,
|
||||||
|
Type.EaseInQuad => EaseInQuad,
|
||||||
|
Type.EaseOutQuad => EaseOutQuad,
|
||||||
|
Type.EaseInOutQuad => EaseInOutQuad,
|
||||||
|
Type.EaseInCubic => EaseInCubic,
|
||||||
|
Type.EaseOutCubic => EaseOutCubic,
|
||||||
|
Type.EaseInOutCubic => EaseInOutCubic,
|
||||||
|
Type.EaseInQuart => EaseInQuart,
|
||||||
|
Type.EaseOutQuart => EaseOutQuart,
|
||||||
|
Type.EaseInOutQuart => EaseInOutQuart,
|
||||||
|
Type.EaseInQuint => EaseInQuint,
|
||||||
|
Type.EaseOutQuint => EaseOutQuint,
|
||||||
|
Type.EaseInOutQuint => EaseInOutQuint,
|
||||||
|
Type.EaseInExpo => EaseInExpo,
|
||||||
|
Type.EaseOutExpo => EaseOutExpo,
|
||||||
|
Type.EaseInOutExpo => EaseInOutExpo,
|
||||||
|
Type.EaseInCirc => EaseInCirc,
|
||||||
|
Type.EaseOutCirc => EaseOutCirc,
|
||||||
|
Type.EaseInOutCirc => EaseInOutCirc,
|
||||||
|
Type.EaseInBack => EaseInBack,
|
||||||
|
Type.EaseOutBack => EaseOutBack,
|
||||||
|
Type.EaseInOutBack => EaseInOutBack,
|
||||||
|
Type.EaseInElastic => EaseInElastic,
|
||||||
|
Type.EaseOutElastic => EaseOutElastic,
|
||||||
|
Type.EaseInOutElastic => EaseInOutElastic,
|
||||||
|
Type.EaseInBounce => EaseInBounce,
|
||||||
|
Type.EaseOutBounce => EaseOutBounce,
|
||||||
|
Type.EaseInOutBounce => EaseInOutBounce,
|
||||||
|
_ => Linear
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Linear(float t)
|
||||||
|
{
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInSine(float t)
|
||||||
|
{
|
||||||
|
return 1f - Mathf.Cos(t * PI / 2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseOutSine(float t)
|
||||||
|
{
|
||||||
|
return Mathf.Sin(t * PI / 2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInOutSine(float t)
|
||||||
|
{
|
||||||
|
return -(Mathf.Cos(PI * t) - 1f) / 2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInQuad(float t)
|
||||||
|
{
|
||||||
|
return t * t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseOutQuad(float t)
|
||||||
|
{
|
||||||
|
return 1f - (1f - t) * (1f - t);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInOutQuad(float t)
|
||||||
|
{
|
||||||
|
return t < 0.5f ? 2f * t * t : 1f - Mathf.Pow(-2f * t + 2f, 2f) / 2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInCubic(float t)
|
||||||
|
{
|
||||||
|
return t * t * t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseOutCubic(float t)
|
||||||
|
{
|
||||||
|
return 1f - Mathf.Pow(1f - t, 3f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInOutCubic(float t)
|
||||||
|
{
|
||||||
|
return t < 0.5f ? 4f * t * t * t : 1f - Mathf.Pow(-2f * t + 2f, 3f) / 2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInQuart(float t)
|
||||||
|
{
|
||||||
|
return t * t * t * t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseOutQuart(float t)
|
||||||
|
{
|
||||||
|
return 1f - Mathf.Pow(1f - t, 4f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInOutQuart(float t)
|
||||||
|
{
|
||||||
|
return t < 0.5f ? 8f * t * t * t * t : 1f - Mathf.Pow(-2f * t + 2f, 4f) / 2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInQuint(float t)
|
||||||
|
{
|
||||||
|
return t * t * t * t * t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseOutQuint(float t)
|
||||||
|
{
|
||||||
|
return 1f - Mathf.Pow(1f - t, 5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInOutQuint(float t)
|
||||||
|
{
|
||||||
|
return t < 0.5f ? 16f * t * t * t * t * t : 1f - Mathf.Pow(-2f * t + 2f, 5f) / 2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInExpo(float t)
|
||||||
|
{
|
||||||
|
return t == 0f ? 0f : Mathf.Pow(2f, 10f * t - 10f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseOutExpo(float t)
|
||||||
|
{
|
||||||
|
return t == 1f ? 1f : 1f - Mathf.Pow(2f, -10f * t);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInOutExpo(float t)
|
||||||
|
{
|
||||||
|
return t == 0f ? 0f :
|
||||||
|
t == 1f ? 1f :
|
||||||
|
t < 0.5f ? Mathf.Pow(2f, 20f * t - 10f) / 2f :
|
||||||
|
(2f - Mathf.Pow(2f, -20f * t + 10f)) / 2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInCirc(float t)
|
||||||
|
{
|
||||||
|
return 1f - Mathf.Sqrt(1f - Mathf.Pow(t, 2f));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseOutCirc(float t)
|
||||||
|
{
|
||||||
|
return Mathf.Sqrt(1f - Mathf.Pow(t - 1f, 2f));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInOutCirc(float t)
|
||||||
|
{
|
||||||
|
return t < 0.5f
|
||||||
|
? (1f - Mathf.Sqrt(1f - Mathf.Pow(2f * t, 2f))) / 2f
|
||||||
|
: (Mathf.Sqrt(1f - Mathf.Pow(-2f * t + 2f, 2f)) + 1f) / 2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInBack(float t)
|
||||||
|
{
|
||||||
|
return C3 * t * t * t - C1 * t * t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseOutBack(float t)
|
||||||
|
{
|
||||||
|
return 1f + C3 * Mathf.Pow(t - 1f, 3f) + C1 * Mathf.Pow(t - 1f, 2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInOutBack(float t)
|
||||||
|
{
|
||||||
|
return t < 0.5f
|
||||||
|
? Mathf.Pow(2f * t, 2f) * ((C2 + 1f) * 2f * t - C2) / 2f
|
||||||
|
: (Mathf.Pow(2f * t - 2f, 2f) * ((C2 + 1f) * (t * 2f - 2f) + C2) + 2f) / 2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInElastic(float t)
|
||||||
|
{
|
||||||
|
return t switch
|
||||||
|
{
|
||||||
|
0f => 0f,
|
||||||
|
1f => 1f,
|
||||||
|
_ => -Mathf.Pow(2f, 10f * t - 10f) * Mathf.Sin((t * 10f - 10.75f) * C4)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseOutElastic(float t)
|
||||||
|
{
|
||||||
|
return t switch
|
||||||
|
{
|
||||||
|
0f => 0f,
|
||||||
|
1f => 1f,
|
||||||
|
_ => Mathf.Pow(2f, -10f * t) * Mathf.Sin((t * 10f - 0.75f) * C4) + 1f
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInOutElastic(float t)
|
||||||
|
{
|
||||||
|
return t == 0f ? 0f :
|
||||||
|
t == 1f ? 1f :
|
||||||
|
t < 0.5f ? -(Mathf.Pow(2f, 20f * t - 10f) * Mathf.Sin((20f * t - 11.125f) * C5)) / 2f :
|
||||||
|
Mathf.Pow(2f, -20f * t + 10f) * Mathf.Sin((20f * t - 11.125f) * C5) / 2f + 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInBounce(float t)
|
||||||
|
{
|
||||||
|
return 1f - EaseOutBounce(1f - t);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseOutBounce(float t)
|
||||||
|
{
|
||||||
|
switch (t)
|
||||||
|
{
|
||||||
|
case < 1f / 2.75f:
|
||||||
|
return 7.5625f * t * t;
|
||||||
|
case < 2f / 2.75f:
|
||||||
|
t -= 1.5f / 2.75f;
|
||||||
|
return 7.5625f * t * t + 0.75f;
|
||||||
|
case < 2.5f / 2.75f:
|
||||||
|
t -= 2.25f / 2.75f;
|
||||||
|
return 7.5625f * t * t + 0.9375f;
|
||||||
|
default:
|
||||||
|
t -= 2.625f / 2.75f;
|
||||||
|
return 7.5625f * t * t + 0.984375f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float EaseInOutBounce(float t)
|
||||||
|
{
|
||||||
|
return t < 0.5f ? (1f - EaseOutBounce(1f - 2f * t)) / 2f : (1f + EaseOutBounce(2f * t - 1f)) / 2f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
Runtime/Utils/EasingFunctions.cs.meta
Normal file
3
Runtime/Utils/EasingFunctions.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 999e76d81bee4d159317479117798d57
|
||||||
|
timeCreated: 1747860988
|
21
Runtime/Utils/ObjectPool.cs
Normal file
21
Runtime/Utils/ObjectPool.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace DC.Animator.Utils
|
||||||
|
{
|
||||||
|
public class ObjectPool<T> where T : class
|
||||||
|
{
|
||||||
|
private readonly Stack<T> _pool = new Stack<T>();
|
||||||
|
private readonly Func<T> _createFunc;
|
||||||
|
|
||||||
|
public ObjectPool(Func<T> createFunc) => _createFunc = createFunc;
|
||||||
|
|
||||||
|
public T Get() => _pool.Count > 0 ? _pool.Pop() : _createFunc();
|
||||||
|
|
||||||
|
public void Return(T obj) => _pool.Push(obj);
|
||||||
|
|
||||||
|
public void Clear() => _pool.Clear();
|
||||||
|
|
||||||
|
public int Count => _pool.Count;
|
||||||
|
}
|
||||||
|
}
|
3
Runtime/Utils/ObjectPool.cs.meta
Normal file
3
Runtime/Utils/ObjectPool.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a9ab03e1fa84423481b0a96d7299431b
|
||||||
|
timeCreated: 1747860957
|
13
package.json
Normal file
13
package.json
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"name": "com.danielcumbor.dcanimator",
|
||||||
|
"version": "2.0.0",
|
||||||
|
"displayName": "DC Animator",
|
||||||
|
"description": "A custom Unity tool for animating objects.",
|
||||||
|
"unity": "6000.0",
|
||||||
|
"unityRelease": "23f1",
|
||||||
|
"author": {
|
||||||
|
"name": "Daniel Cumbor",
|
||||||
|
"email": "danc@ultr.uk",
|
||||||
|
"url": "https://www.danielcumbor.uk"
|
||||||
|
}
|
||||||
|
}
|
7
package.json.meta
Normal file
7
package.json.meta
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 124a82e8e8b1b684e88cc1017d606c62
|
||||||
|
PackageManifestImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
Reference in a new issue