-
Notifications
You must be signed in to change notification settings - Fork 137
AnimationAsset Guide
All assets are known engine types that allow instances to be created at runtime. The "AnimationAsset", like all assets, is derived from a base type of "AssetBase". That means it includes all the fields from that type as well as adding its own fields specific to itself.
The AnimationAsset provides a way to refer to any ImageAsset that contains frames and select those frames for playing in a specified order to produce an animation of images.
For an AnimationAsset to be valid, it must contain at least a single frame selected from a valid ImageAsset.
Frames are selected in one of two ways, and which one is decided by the image, not by the animation. An ImageAsset in "explicit" mode cuts its image into cells that each carry a name, so an animation on it selects frames by name. An ImageAsset that generates its frames from a cell grid has no names to select, so an animation on it selects frames by zero-based index. See ImageAsset for the two modes.
The AnimationAsset type exposes the following fields in addition to those it inherits. Shown are the equivalent methods available that perform the same action in setting and getting the respective field:
-
Image
- setImage(imageAssetId)
- getImage()
-
AnimationFrames
- setAnimationFrames(string)
- getAnimationFrames()
-
NamedAnimationFrames
- setNamedAnimationFrames(string)
- getNamedAnimationFrames()
-
AnimationTime
- setAnimationTime(float)
- getAnimationTime();
-
AnimationCycle
- setAnimationCycle(bool)
- getAnimationCycle()
-
RandomStart
- setRandomStart(bool)
- getRandomStart()
The following is a complete description of each of these fields.
This is a mandatory field and refers to the image asset that should be used as the source for frames. This field should be an asset-Id that refers to an ImageAsset. If it does not refer to a valid asset (or the module the asset is defined in has not been loaded) or it is not an ImageAsset or the asset is not valid then the animation is not be valid.
An example is:
<AnimationAsset
AnimationName="FireAnimation"
Image="EffectsModule:FireImage"
...
/>This example defines an animation named "FireAnimation" and refers to an ImageAsset named "FireImage" in the "EffectsModule" i.e. its asset-Id is "EffectsModule:FireImage".
This is the mandatory field when the selected ImageAsset generates its frames from a cell grid i.e. when that image's "ExplicitMode" is false. This specifies the actual frames to use from the selected ImageAsset. You can select any number of frames and use each as many times as you like:
<AnimationAsset
AnimationName="FireAnimation"
Image="EffectsModule:FireImage"
AnimationFrames="0 1 2 3 4 5 4 3 2 1"
/>This example defines an animation that plays, in sequence, frames 0 to 5 to 1 i.e. it is a 10 frame animation.
This is the mandatory field when the selected ImageAsset is in explicit mode. This specifies the actual frame names to use from the selected ImageAsset. You can select any number of frames and use each as many times as you like:
<AnimationAsset
AnimationName="ExtinguishFireAnimation"
Image="EffectsModule:ExplicitFireImage"
NamedAnimationFrames="fire_01 fire_02 fire_03 fireWithSmoke_01 fireWithSmoke_02 onlySmoke"
/>This example defines a 6 frame animation sequence. There is no flag to set: the image "EffectsModule:ExplicitFireImage" is in explicit mode, which is what makes these names meaningful and what makes this the field the animation reads.
Only one of the two fields is ever written to the file - whichever one the animation is actually using. Both are kept in memory though, which is what makes changing an image's mode reversible; see "Changing an image's mode" below.
A name that no cell of the image answers to is kept, not dropped. It draws nothing, and both the console and the Asset Manager report it, but it stays in the list so that deleting a cell by mistake does not silently cost you the frame as well. This is the opposite of how an out-of-range frame number behaves, which is described under "Additional API" below.
Whilst this field is not mandatory as it defaults to one (second), it's obviously important in determining how fast the animation runs.
The animation time is how long it takes, in seconds, for the animation to play *all the specified animation frames.
<AnimationAsset
AnimationName="FireAnimation"
Image="EffectsModule:FireImage"
AnimationFrames="0 1 2 3 4 5 4 3 2 1"
AnimationTime="5"
/>This example plays all 10 frames in 5 seconds i.e. 0.5 seconds per frame. You are free to use any value greater than zero including floating-point values.
This is an optional field that controls whether the animation, when reaching the end of the selected frames should start again at the beginning or not. By default, animation cycle is true therefore all animations are "cyclic" animations by default therefore unless you want an animation that plays only once then you do not need to specify it.
<AnimationAsset
AnimationName="FireAnimation"
Image="EffectsModule:FireImage"
AnimationFrames="0 1 2 3 4 5 4 3 2 1"
AnimationTime="5"
AnimationCycle="false"
/>The example plays all 10 frame 0 to 5 to 1 then stops because the animation cycle is false.
This is an optional field that controls whether the animation, when starting, should start at a random selection of one of the specified frames. By default, random start is off therefore the animation will start at the first frame specified.
<AnimationAsset
AnimationName="FireAnimation"
Image="EffectsModule:FireImage"
AnimationFrames="0 1 2 3 4 5 4 3 2 1"
AnimationTime="5"
RandomStart="true"
/>The example animation could start at any of the frames specified i.e. 0, 1, 2, 3, 4, 5, 4, 3, 2 or 1.
When starting lots of animations at the same time, having them all synchronized can look very odd, especially if the animation represents something typically random in nature such as fire, a flicker light, a swarm of insects etc. By using random start, you ensure that all these animations appear more random.
Whether an animation selects its frames by name or by index is read from the image asset and is not a field you set. An ImageAsset in explicit mode has named cells, so an animation on it uses NamedAnimationFrames; an ImageAsset that generates frames from a cell grid has none, so an animation on it uses AnimationFrames.
getNamedCellsMode() answers the question and there is no matching setter. To change the answer, change the image the animation points at, or change that image's ExplicitMode.
Changed in 4.0. This used to be a saved
NamedCellsModefield with asetNamedCellsMode()setter, and the two could disagree: setting it true on an image with no named cells produced an animation with no frames and no explanation, and re-cutting an image left the flag saying something the image no longer agreed with.Existing files carrying
NamedCellsModestill load, and load correctly - the mode is taken from the image either way, so an animation whose flag was right gets the same answer and one whose flag was wrong is fixed by the upgrade. The attribute itself is no longer a field though, so it is read as an ordinary dynamic field: it is kept, and written back out on every subsequent save, indefinitely and without comment. Delete the attribute to be rid of it.setNamedCellsMode()no longer exists; script calling it gets the usual "Unknown command" warning and nothing happens.
Turning an ImageAsset's explicit mode on or off moves every animation built on it between the two kinds of frame list. This is done for you: index N becomes the name of cell N, and a name becomes its cell's index.
Both lists are kept in memory, so the switch is reversible. Turning explicit mode on converts the numbers to names and leaves the numbers where they were; turning it back off finds those numbers again rather than rebuilding them, so any editing done while the animation was named is preserved on the way back.
An entry that cannot be translated is skipped, with a warning naming the animation and the position. That means an index pointing past the end of the cell list, or at a cell with no name.
The AnimationAsset exposes a few additional methods that can be useful under certain circumstances.
The frames you specify are validated against the ImageAsset, and the result is kept as a second list. This happens when the animation is loaded and again whenever either asset changes - including when the image is re-cut, which is the common way a working animation goes wrong.
What validation does to a bad frame depends on which kind it is, and the difference matters - including in how you detect one:
- An out-of-range frame number is clamped to the nearest valid frame. It is not dropped, and the animation goes on playing - it just quietly shows the wrong art. Halving an image's cell count, for example, leaves every frame past the halfway point playing the last frame of the sheet. Because clamping changes the value, the specified and validated lists differ, and comparing them is how you find it.
- A frame name that no cell answers to is kept as it is. It draws nothing at all, so the gap is visible rather than silent, and the name survives so that restoring the cell restores the animation. Because nothing is changed, the two lists stay identical and comparing them tells you nothing - use
getMissingFrames()for this case.
Neither invalidates the animation, so neither raises an error, only a console warning. Between the list comparison and getMissingFrames(), a tool can notice either without reading the log.
Get the frames that compose the animation as a space-separated list, in the same form they were specified. Pass "true" to get the validated list instead.
Each refuses to answer for an animation using the other kind of frame, warning to the console and returning an empty string. Use getNamedCellsMode() to pick, or use getFrameCount() below when all you want is the count.
getAnimationFrameCount( [bool validatedFrames] ) / getNamedAnimationFrameCount( [bool validatedFrames] )
The same, as a count rather than a list. These refuse in the same way, returning -1 rather than an empty string.
How many frames the animation has, whichever kind it uses. Unlike the two above, this never refuses, so script that only wants the count does not have to ask which mode the animation is in first.
The frame names that no cell of the image answers to, space separated, and an empty string when they all resolve.
Also empty for an animation using frame numbers, which cannot have this problem - an out-of-range number is clamped rather than lost, and is found by comparing the specified and validated lists instead.
Whether this animation selects frames by name. Read from the image asset; there is no setter. See "Named cells" above.