MovieClip Library
A .swf is not one animation - it is a library of them. SwfMesh imports the whole
library, and any MovieClip you exported for ActionScript can be played as a timeline in
its own right, by name, from that one imported asset.
So hero.swf holds Idle, Walk and Attack. One player plays Walk, another plays
Attack, a third plays the root timeline - all from the same file, sharing one parse and
one set of meshes.
What lands in the library#
A MovieClip shows up in the clip list when it is exported for ActionScript in Flash or Animate (right-click the symbol > Properties > Export for ActionScript). Both linkage forms are read:
| Authored as | SWF tag | Name SwfMesh uses |
|---|---|---|
| AS2 linkage identifier | ExportAssets |
The identifier, verbatim |
| AS3 class | SymbolClass |
The class name as written - including its package path, e.g. game.units.Walk |
Two things are deliberately not in the list:
- Non-clip exports. Exported bitmaps, sounds and shapes are imported and used normally, but only a MovieClip has a timeline to play, so only MovieClips are listed.
- The document class. A SWF's own main class is the root timeline, which is always offered as the first entry and needs no linkage name.
Symbols that are only ever placed on stage - never exported - still animate as part of whatever timeline contains them. Exporting is only about being selectable as a root.
Library name vs instance name#
Two different names doing two different jobs. Confusing them is the usual reason a clip "can't be found":
| Where you set it in Flash | What it selects | |
|---|---|---|
| Library (linkage) name | Symbol Properties > Export for ActionScript | Which timeline a player plays |
| Instance name | Properties panel, on a symbol placed on the stage | A nested clip inside a running timeline - GetClip("head") |
A symbol can carry both, and they do not have to match. The nested-clip surface is in Scripting API.
Choosing which clip a player plays#
| Unity | Godot | |
|---|---|---|
| Inspector | Movieclip dropdown on the Swf Player component | movieclip dropdown on the node |
| Root timeline | The first entry, SWF Timeline | The first entry, SWF Timeline |
| From script | player.movieclip = "Walk" |
movieclip = "Walk" |
| List what's available | player.GetMovieclipNames() · swfAsset.MovieclipNames |
swf_resource.movieclip_names |
// Unity
using SwfMesh;
public class ClipSwitcher : MonoBehaviour
{
public SwfPlayer player;
public void Attack()
{
player.movieclip = "Attack"; // "" = the root timeline
player.Refresh(); // re-resolves; does not re-parse the SWF
player.Play();
}
}# Godot
extends SwfNode3D
func attack() -> void:
movieclip = "Attack" # "" = the root timeline; applies immediately
playing = trueUnity's movieclip is a serialized field, so a change from script takes effect on the
next Refresh(). Godot's is a property with a setter, so assigning it switches the
timeline there and then.
The imported asset also lists its clips in the import inspector, so you can see what a
.swf contains without dropping it into a scene.
What the selection changes#
- Frame count and current frame follow the selected clip, not the document. A
3-frame
Idleinside a 400-frame SWF reports 3 frames and loops over 3. - The selected clip's own frame scripts run -
stop,play,gotoAndStop,gotoAndPlay, custom events and completion - exactly as they do on the root timeline. Its frame 1 scripts fire on the first tick after the switch. - Nested clips inside it keep auto-playing, and are still reachable by instance name.
- An unrecognised name falls back to the root timeline. Unity logs
[SwfMesh] exported symbol '…' not found.; Godot falls back silently.
Switching clips at runtime#
Switching is cheap: no re-import, no re-parse, and the tessellated geometry survives - the mesh cache is keyed per character, and characters are shared across every timeline that places them.
What a switch does and does not keep:
| Reset by a switch | Kept |
|---|---|
| Current frame - back to frame 1 | The parsed document |
Per-nested-clip playback control (GotoAndStop and friends on a child clip) |
Tessellated character geometry |
Per-nested-clip transform overrides (X, Y, Rotation, ScaleX, ScaleY) |
Loaded materials, textures and sounds |
AddChild attachments - re-applied for you |
Nested-clip state is dropped because those dot-paths (body.arm.hand) were addresses
into the previous timeline and mean nothing in the new one. If you drive nested clips
by hand, re-apply that state after switching.
One SWF, many players#
Everything derived from an imported asset is shared per asset, not per player:
- the parsed document - once, however many players use it
- tessellated character geometry - built lazily, once per character, reused by every clip that places it
- static frames - baked once per (clip, frame) and reused by every player showing that pair
- materials, the bitmap atlas, and decoded audio
A crowd of 200 players spread across Idle, Walk and Run from one hero.swf is one
parse and one mesh per (clip, frame) - not 200 of either.
The trade-off: the whole document is parsed and held in memory whatever you play.
Geometry is only tessellated for what actually gets shown, so unplayed clips cost no
triangles - but a 40-clip library is a 40-clip parse even for a player that only ever
shows one of them. Group a library by what loads together (a character, a level's UI)
rather than shipping one .swf per animation, which throws the sharing away.
Drawing a crowd. Copies showing the same frame draw together. If every copy runs its own nested animation out of step with the others, each one has to be drawn separately, so a big crowd of independently animating copies costs more than one running in step. Shorter, simpler loops crowd best.
For dense identical content, Godot's renderer already culls per instance and batches the survivors, which is the order you want. Unity ships an equivalent GPU-instancing path (Project Settings > SwfMesh > GPU Instancing) that is off by default on purpose: it is a measured trade that wins at high instance counts on constrained hardware and loses on desktop. Measure before enabling it.
Attaching one library clip inside another#
A second player pointed at another symbol can be attached into a running clip - the
equivalent of AS3's addChild. The library case is the tidy one: host and child come out
of the same .swf, so the sword and the hero share a parse and a mesh cache.
// Unity - a sword from the same library, following the hero's hand
var sword = new GameObject("Sword").AddComponent<SwfPlayer>();
sword.swfAsset = hero.swfAsset;
sword.movieclip = "Sword";
sword.Refresh();
hero.Clip.GetClip("hand").AddChild(sword);# Godot
var sword := SwfNode3D.new()
sword.swf_resource = swf_resource
sword.movieclip = "Sword"
clip.get_clip("hand").add_child(sword)How the attachment then behaves - depth, transform inheritance, surviving a clip switch, detaching, lifetime - is in Plugin Features. The methods themselves are in Scripting API.
Reserved export names#
Three linkage names are reserved and matched exactly - HitBox, HitBoxCircle and
HitBoxCapsule. They never appear in the clip list and are never rendered, whatever
their artwork or authored alpha: they become collision data instead. Don't use them for
anything you want on screen.
→ Hit Boxes - authoring them, and what each one becomes in each engine.
Troubleshooting#
A clip is missing from the dropdown. It is not exported for ActionScript, or it is not a MovieClip. Graphic and Button symbols have no library timeline to select.
The player shows the whole stage instead of my clip. The name did not resolve, so it fell back to the root timeline. Check for a typo, and remember that an AS3 class name includes its package path.
It played yesterday and plays the root today. The symbol was renamed in Flash. The selection is stored as a plain string, so a rename in the FLA silently detaches every scene that referenced the old name.
Nested clips stopped responding after a clip switch. Per-clip playback and transform overrides are cleared on a switch - see Switching clips at runtime.
See also#
- Plugin Features - what the plugin adds on top of Flash
- Scripting API - selecting and driving clips from code
- Hit Boxes - the three reserved export names
- Supported Features - what of the SWF format renders