AnimationClip









How do I use Animation Clip
Below are practical examples compiled from projects for learning and reference purposes

Featured Snippets


File name: AnimationBuilder.cs Copy
57         public List BuildAnimationClips(GameObject root, Entity entity, string scmlAssetPath)
58         {
59             var allAnimClips = AssetDatabase.LoadAllAssetRepresentationsAtPath(scmlAssetPath).OfType().ToList();
60             Debug.Log(string.Format("Found {0} animation clips at {1}", allAnimClips.Count, scmlAssetPath));
61
62             var newAnimClips = new List();
63
64             foreach (var animation in entity.Animations)
65             {
66                 var animClip = MakeAnimationClip(root, animation, Path.GetDirectoryName(scmlAssetPath));
67                 Debug.Log(string.Format("Added animClip({0}) to asset path ({1}) WrapMode:{2}", animClip.name, scmlAssetPath, animClip.wrapMode));
68                 newAnimClips.Add(animClip);
69
70                 var originalAnimClip = allAnimClips.Where(clip => clip.name == animClip.name).FirstOrDefault();
71                 if (originalAnimClip != null)
72                 {
73                     Debug.Log("Replacing animation clip " + animClip.name);
74                     EditorUtility.CopySerialized(animClip, originalAnimClip);
75                     allAnimClips.Remove(originalAnimClip);
76                 }
77                 else
78                     AssetDatabase.AddObjectToAsset(animClip, scmlAssetPath);
79             }
80
81             //Remove any animation clips that are no longer present in the SCML
82             foreach(var clip in allAnimClips)
83             {
84                 //This may be a bad idea
85                 UnityEngine.Object.DestroyImmediate(clip, true);
86             }
87
88             return newAnimClips;
89         }
File name: AnimationBuilder.cs Copy
91         public AnimationClip MakeAnimationClip(GameObject root, Animation animation, string baseFolderPath)
92         {
93             //Clear local caches
94             lastGameObjectCache.Clear();
95             animationEvents.Clear();
96             lastKeyframeCache.Clear();
97             spriteChangeKeys.Clear();
98             spriteBaseFolder = baseFolderPath;
99
100             var animClip = new AnimationClip();
101             animClip.name = animation.Name;
102
103             //Set clip to Generic type
104             //AnimationUtility.SetAnimationType(animClip, ModelImporterAnimationType.Generic);
105
106             //Populate the animation curves & events
107             MakeAnimationCurves(root, animClip, animation);
108
109             return animClip;
110         }
File name: AnimationBuilder.cs Copy
112         private void MakeAnimationCurves(GameObject root, AnimationClip animClip, Animation animation)
113         {
114             acb = new AnimationCurveBuilder();
115
116             //Get a list of all sprites on this GO
117             var allSprites = root.GetComponentsInChildren(true).Select(sr => AnimationUtility.CalculateTransformPath(sr.transform, root.transform));
118
119             //Add a key for all objects on the first frame
120             SetGameObjectForKey(root, animClip, animation.MainlineKeys.First(), 0);
121
122             foreach (var mainlineKey in animation.MainlineKeys)
123             {
124
125                 var visibleSprites = SetGameObjectForKey(root, animClip, mainlineKey);
126                 var hiddenSprites = allSprites.Except(visibleSprites);
127                 HideSprites(root, hiddenSprites, mainlineKey.Time);
128             }
129
130             switch (animation.LoopType)
131             {
132                 case LoopType.True:
133                     //Cycle back to first frame
134                     SetGameObjectForKey(root, animClip, animation.MainlineKeys.First(), animation.Length);
135                     break;
136                 case LoopType.False:
137                     //Duplicate the last key at the end time of the animation
138                     SetGameObjectForKey(root, animClip, animation.MainlineKeys.Last(), animation.Length);
139                     break;
140                 default:
141                     Debug.LogWarning("Unsupported loop type: " + animation.LoopType.ToString());
142                     break;
143             }
144
145             //Add the curves to our animation clip
146             //NOTE: This MUST be done before modifying the settings, thus the double switch statement
147             acb.AddCurves(animClip);
148
149             foreach (var sprite in spriteChangeKeys)
150             {
151                 if (sprite.Value.Count > 0)
152                 {
153                     BuildSpriteChangeCurve(ref animClip, sprite);
154                 }
155             }
156
157             //Set the loop/wrap settings for the animation clip
158             var animSettings = AnimationUtility.GetAnimationClipSettings(animClip);
159             switch(animation.LoopType)
160             {
161                 case LoopType.True:
162                     animClip.wrapMode = WrapMode.Loop;
163                     animSettings.loopTime = true;
164                     break;
165                 case LoopType.False:
166                     animClip.wrapMode = WrapMode.ClampForever;
167                     break;
168                 case LoopType.PingPong:
169                     animClip.wrapMode = WrapMode.PingPong;
170                     animSettings.loopTime = true;
171                     break;
172                 default:
173                     Debug.LogWarning("Unsupported loop type: " + animation.LoopType.ToString());
174                     break;
175             }
176
177             animClip.SetAnimationSettings(animSettings);
178
179             //Debug.Log(string.Format("Setting animation {0} to {1} loop mode (WrapMode:{2} LoopTime:{3}) ", animClip.name, animation.LoopType, animClip.wrapMode, animSettings.loopTime));
180         }
File name: AnimationBuilder.cs Copy
201         private HashSet SetGameObjectForKey(GameObject root, AnimationClip animClip, MainlineKey mainlineKey, float time = -1)
202         {
203             HashSet paths = new HashSet();
204             //Could do this recursively - this is easier
205             Stack toProcess = new Stack(mainlineKey.GetChildren(null));
206
207             while (toProcess.Count > 0)
208             {
209                 var next = toProcess.Pop();
210
211                 paths.Add(next.RelativePath);
212                 SetGameObjectForRef(root, next, time);
213                 SetSpriteEvent(animClip, time, next);
214
215                 var children = mainlineKey.GetChildren(next);
216                 foreach (var child in children) toProcess.Push(child);
217             }
218
219             return paths;
220         }
File name: AnimationBuilder.cs Copy
312         private void BuildSpriteChangeCurve(ref AnimationClip clip, KeyValuePair> timeline)
313         {
314             // First you need to create Editor Curve Binding
315             EditorCurveBinding curveBinding = new EditorCurveBinding();
316
317             // I want to change the sprites of the sprite renderer, so I put the typeof(SpriteRenderer) as the binding type.
318             curveBinding.type = typeof(SpriteRenderer);
319
320             // Regular path to the GameObject that will be changed
321             curveBinding.path = timeline.Key;
322
323             // This is the property name to change the sprite of a sprite renderer
324             curveBinding.propertyName = "m_Sprite";
325
326             // An array to hold the object keyframes
327             ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[timeline.Value.Count];
328
329             int i = 0;
330             foreach (var key in timeline.Value)
331             {
332                 keyFrames[i] = new ObjectReferenceKeyframe();
333                 // set the time
334                 keyFrames[i].time = key.Time;
335                 // set reference for the sprite you want
336                 keyFrames[i].value = key.Sprite;
337                 i++;
338
339             }
340
341             AnimationUtility.SetObjectReferenceCurve(clip, curveBinding, keyFrames);
342         }
File name: AnimationBuilder.cs Copy
358         /// Creates an event to change the sprite for the specified Ref (if applicable)
363         private void SetSpriteEvent(AnimationClip clip, float time, Ref reference)
364         {
365             var spriteKey = reference.Referenced as SpriteTimelineKey;
366             //Only add event for SpriteTimelineKey objects
367             if (spriteKey != null)
368             {
369                 if (time < 0) time = spriteKey.Time;
370                 if (!spriteChangeKeys.ContainsKey(reference.RelativePath))
371                 {
372                     spriteChangeKeys[reference.RelativePath] = new List();
373                 }
374
375                 //Add the key to the dictionary to later build all the curves at once.
376                 spriteChangeKeys[reference.RelativePath].Add(new SpriteChangeKey() { Time = time, Sprite = AssetUtils.GetSpriteAtPath(spriteKey.File.Name, spriteBaseFolder) });
377             }
378         }
File name: AnimationCurveBuilder.cs Copy
45         public void AddCurves(AnimationClip animClip)
46         {
47             foreach(var kvp in curveCache)
48             {
49                 var curves = kvp.Value.Curves;
50                 //Position curves
51                 SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(Transform), "localPosition.x", curves[(int)AnimationCurveIndex.LocalPositionX]);
52                 SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(Transform), "localPosition.y", curves[(int)AnimationCurveIndex.LocalPositionY]);
53                 SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(Transform), "localPosition.z", curves[(int)AnimationCurveIndex.LocalPositionZ]);
54
55                 //Rotation curves
56                 SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(Transform), "localRotation.x", curves[(int)AnimationCurveIndex.LocalRotationX]);
57                 SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(Transform), "localRotation.y", curves[(int)AnimationCurveIndex.LocalRotationY]);
58                 SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(Transform), "localRotation.z", curves[(int)AnimationCurveIndex.LocalRotationZ]);
59                 SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(Transform), "localRotation.w", curves[(int)AnimationCurveIndex.LocalRotationW]);
60
61                 //Scale curves
62                 SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(Transform), "localScale.x", curves[(int)AnimationCurveIndex.LocalScaleX]);
63                 SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(Transform), "localScale.y", curves[(int)AnimationCurveIndex.LocalScaleY]);
64                 SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(Transform), "localScale.z", curves[(int)AnimationCurveIndex.LocalScaleZ]);
65
66                 //IsActive curve
67                 SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(GameObject), "m_IsActive", curves[(int)AnimationCurveIndex.IsActive]);
68
69                 if (kvp.Value.IsSpriteKey)
70                 {
71                     //Color Tint curve
72                     SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(SpriteRenderer), "m_Color.r", curves[(int)AnimationCurveIndex.ColorR]);
73                     SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(SpriteRenderer), "m_Color.g", curves[(int)AnimationCurveIndex.ColorG]);
74                     SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(SpriteRenderer), "m_Color.b", curves[(int)AnimationCurveIndex.ColorB]);
75                     SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(SpriteRenderer), "m_Color.a", curves[(int)AnimationCurveIndex.ColorA]);
76                     SetCurveIfNotEmpty(ref animClip, kvp.Key, typeof(SortingOrderUpdate), "SortingOrder", curves[(int)AnimationCurveIndex.ZIndex]);
77                 }
78             }
79
80             //animClip.EnsureQuaternionContinuity();
81         }
File name: AnimationCurveBuilder.cs Copy
120         private void SetCurveIfNotEmpty(ref AnimationClip clip, string path, Type component, string property, AnimationCurve curve)
121         {
122             if (curve.keys.Length > 0)
123             {
124                 clip.SetCurve(path, component, property, curve);
125             }
126         }
File name: ScmlPostProcessor.cs Copy
66         static void ImportScml(string assetPath)
67         {
68             string folderPath = Path.GetDirectoryName(assetPath);
69
70             //Load the SCML as XML
71             var doc = new XmlDocument();
72             doc.Load(assetPath);
73
74             //Parse the SCML file
75             var scml = new Spriter.ScmlObject(doc);
76
77             //TODO: Verify that all files/folders exist
78             var pb = new PrefabBuilder();
79             foreach (var entity in scml.Entities)
80             {
81                 //TODO: Settings file to customize prefab location
82                 var prefabPath = Path.Combine(folderPath, entity.Name + ".prefab");
83
84                 //Change to forward slash for asset database friendliness
85                 prefabPath = prefabPath.Replace('\\', '/');
86
87                 //Either instantiate the existing prefab or create a new one
88                 GameObject go;
89                 var prefabGo = AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject));
90                 if (prefabGo == null)
91                 {
92                     go = new GameObject();
93                     prefabGo = PrefabUtility.CreatePrefab(prefabPath, go, ReplacePrefabOptions.ConnectToPrefab);
94                 }
95                 else
96                 {
97                     go = GameObject.Instantiate(prefabGo) as GameObject;
98
99                     var oldAnimator = go.GetComponent();
100                     if (oldAnimator) GameObject.DestroyImmediate(oldAnimator);
101                 }
102
103                 //Build the prefab based on the supplied entity
104                 pb.MakePrefab(entity, go, folderPath);
105
106                 var animator = go.AddComponent();
107
108
109
110                 //Add animations to prefab object
111                 var anim = new AnimationBuilder();
112                 var allAnimClips = anim.BuildAnimationClips(go, entity, prefabPath);
113                 AssetDatabase.SaveAssets();
114
115                 var animatorControllerPath = Path.ChangeExtension(prefabPath, "controller");
116                 UnityEditor.Animations.AnimatorController oldController = (UnityEditor.Animations.AnimatorController)AssetDatabase.LoadAssetAtPath(animatorControllerPath, typeof (UnityEditor.Animations.AnimatorController));
117                 UnityEditor.Animations.AnimatorController controller = oldController;
118
119                 if (!oldController)
120                 {
121                     controller = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(animatorControllerPath);
122                     foreach (var animationClip in allAnimClips)
123                     {
124                         if (animationClip)
125                         {
126                             //UnityEditor.Animations.AnimatorController.AddAnimationClipToController(controller, animationClip);
127                         }
128                     }
129                 }
130                 UnityEditor.Animations.AnimatorController.SetAnimatorController(animator, controller);
131                 go.SetActive(true);
132                 //Update the prefab
133                 PrefabUtility.ReplacePrefab(go, prefabGo, ReplacePrefabOptions.ConnectToPrefab);
134
135                 //Add a generic avatar - because why not?
136                 //TODO: May need to eventually break this into a separate class
137                 // ie: if we want to look for a root motion node by naming convention
138                 //var avatar = AvatarBuilder.BuildGenericAvatar(go, "");
139                 //avatar.name = go.name;
140                 //AssetDatabase.AddObjectToAsset(avatar, prefabPath);
141
142                 GameObject.DestroyImmediate(go);
143
144                 AssetDatabase.SaveAssets();
145             }
146         }
File name: AnimationCurveUtils.cs Copy
189         public static void SetAnimationSettings(this AnimationClip animClip, AnimationClipSettings settings)
190         {
191             //Use reflection to get the internal method
192             BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.NonPublic;
193             MethodInfo mInfo = typeof(AnimationUtility).GetMethod("SetAnimationClipSettings", bindingFlags);
194             mInfo.Invoke(null, new object[] { animClip, settings });
195         }

AnimationClip 199 lượt xem

Gõ tìm kiếm nhanh...