forked from Straafe/unity-editor-tools
/
ReverseAnimationContext.cs
127 lines (114 loc) · 4.51 KB
/
ReverseAnimationContext.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
using UnityEditor;
using UnityEngine;
using System.IO;
using System.Collections.Generic;
using UnityEditor.Animations;
public static class ReverseAnimationContext
{
[MenuItem("Assets/Create Reversed Clip", false, 14)]
private static void ReverseClips()
{
List<AnimatorController> animConts = new List<AnimatorController>();
var animators = Object.FindObjectsOfType<Animator>();
AssetDatabase.FindAssets("t:AnimatorController");
List<AnimationClip> clips = GetSelectedClips();
if (clips != null && clips.Count > 0)
{
foreach (AnimationClip clip in clips)
{
ReverseClip(clip, animators);
}
Debug.Log("All selected clips reversed");
}
}
public static List<AnimationClip> GetSelectedClips()
{
var clips = Selection.GetFiltered(typeof(AnimationClip), SelectionMode.Assets);
List<AnimationClip> animClips = new List<AnimationClip>();
if (clips.Length > 0)
{
foreach (var clip in clips)
{
animClips.Add(clip as AnimationClip);
}
return animClips;
}
return null;
}
private static void ReverseClip(AnimationClip clip, Animator[] animators)//List<AnimatorController> animConts
{
AnimationClip originalClip = clip;
string directoryPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(clip)); //Selection.activeObject
string fileName = Path.GetFileName(AssetDatabase.GetAssetPath(clip));
string fileExtension = Path.GetExtension(AssetDatabase.GetAssetPath(clip));
fileName = fileName.Split('.')[0];
string copiedFilePath = directoryPath + Path.DirectorySeparatorChar + fileName + "_Reversed" + fileExtension;
AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(clip), copiedFilePath);
clip = (AnimationClip)AssetDatabase.LoadAssetAtPath(copiedFilePath, typeof(AnimationClip));
if (clip == null)
return;
float clipLength = clip.length;
var curves = AnimationUtility.GetCurveBindings(clip);
foreach (EditorCurveBinding binding in curves)
{
var animCurve = AnimationUtility.GetEditorCurve(clip, binding);
var keys = animCurve.keys;
int keyCount = keys.Length;
for (int i = 0; i < keyCount; i++)
{
Keyframe K = keys[i];
K.time = clipLength - K.time;
var tmp = -K.inTangent;
K.inTangent = -K.outTangent;
K.outTangent = tmp;
keys[i] = K;
}
animCurve.keys = keys;
clip.SetCurve(binding.path, binding.type, binding.propertyName, animCurve);
}
var events = AnimationUtility.GetAnimationEvents(clip);
if (events.Length > 0)
{
for (int i = 0; i < events.Length; i++)
{
events[i].time = clipLength - events[i].time;
}
AnimationUtility.SetAnimationEvents(clip, events);
}
foreach (Animator anim in animators)
{
AnimationClip[] clips = AnimationUtility.GetAnimationClips(anim.gameObject);
bool foundClip = false;
foreach (AnimationClip c in clips)
{
if (c == originalClip)
{
foundClip = true;
break;
}
}
if (foundClip)
{
Debug.Log("Found the animator containing the original clip that was reversed, adding new clip to its state machine...");
AnimatorController controller= UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEditor.Animations.AnimatorController>(UnityEditor.AssetDatabase.GetAssetPath(anim.runtimeAnimatorController));
AnimatorStateMachine asm = controller.layers[0].stateMachine;
AnimatorState animState = asm.AddState(clip.name);
animState.motion = clip;
}
}
}
[MenuItem("Assets/Create Reversed Clip", true)]
static bool ReverseClipValidation()
{
return Selection.activeObject && Selection.activeObject.GetType() == typeof(AnimationClip);
}
public static AnimationClip GetSelectedClip()
{
var clips = Selection.GetFiltered(typeof(AnimationClip), SelectionMode.Assets);
if (clips.Length > 0)
{
return clips[0] as AnimationClip;
}
return null;
}
}