Phaser AE

3D model files (.glb, .obj)

Free packv3.0.0-13DLogic

Loads models an artist made, glTF 2.0 binary (`.glb`) and Wavefront OBJ with its MTL, and turns them into meshes the 3D world can spawn, animated or not. Load once, spawn as often as you like.

This is a Free pack. Every phaser.io account can use it in their games.

Released October 19, 2026 · updated October 20, 2026

3D model files (.glb, .obj): a screenshot of its demo
A note about these graphics

Expansion packs don't come with graphics. This screenshot is one way of drawing what the pack does, made for its demo: none of the sprites, tiles or backgrounds in it are in the pack.

That's by design. A pack is a game's logic, mechanics and effects, and it works with whatever art you give it. Some packs draw effects, backdrops or 3D scenes of their own, but none carries a game's sprites.

So the look is yours. Make the art on phaser.io, bring your own, or let your agent draw it in code: the same pack can look like anything.

What it does

await game.modelFiles.load(key, url) fetches a file through the engine's loader, so the loading screen, progress and retries work as usual, and registers its meshes. game.modelFiles.spawn(key, …) then places a copy with a position, a size, a yaw, pitch and roll, and a tint, and every copy is another instance in the same draw call. An OBJ's MTL is fetched from beside it, and a missing one leaves the model grey rather than failing the load.

Every model is fitted to the unit box the other meshes use, so size is its largest dimension in world units, just as for a primitive; model.size reports the file's own dimensions if you want real-world scale back. A static model is merged to one mesh per material, so it costs as many draws as it has materials rather than nodes. Each part's vertices are available too, so a model can feed anything that needs geometry, such as a wireframe outline.

Animated .glb files play straight off the spawned handle. play takes a clip by name or index, loops or plays once and holds the last frame, scales speed, and crossfades from the current clip over a time you choose, so idle to walk reads as a transition. play(clip, { at }) starts part-way in, which stops a crowd of the same model marching in lockstep. Node animation (doors, wheels, mechanical rigs) is applied as ordinary transforms, and skinned characters are skinned on the CPU, both from one mixer so they stay in step.

Features

  • Two formats — .glb and .obj with .mtl, from a URL, a buffer or text you already have.
  • Instanced copies — load once, spawn many, all in the same draw call.
  • A common scale — every model fitted to the unit box, with its own dimensions still reported.
  • Materials and textures — base colour, metallic and roughness, normal maps and emissive colour, with embedded textures decoded into the atlas.
  • Animation mixer — clips by name or index, looping or one-shot, speed, scrubbing and crossfades.
  • Offset starts — at to start a clip part-way in, for crowds.
  • Node and skinned animation — skins with up to four joints a vertex, in step with node animation.
  • Honest refusals — compressed, quantized, sparse or split files fail with a message naming what was found.
  • A pure reader — parseGlb and the animation maths work on their own, for tools or a worker.

Good for

  • 3D games with artist-made assets — characters, props and environments from a modelling program.
  • Animated characters that walk, idle and run with crossfades between clips.
  • Crowds of the same model, staggered so they do not move as one.
  • Vehicles and machines whose wheels, doors and turrets are animated nodes in the file.
  • Mixing styles, with loaded hero models beside procedural primitives in the same scene.

Make it yours

The pack has no options; each spawn takes its own position, size, rotation and tint, and each handle its own clip, speed, fade and start time. Two different uses: a racing game that loads one car .glb and spawns a dozen tinted copies, each playing the file's own wheel animation; and a town scene where eight copies of a walker play the same Walk clip, each started a fraction of a second later than the last.

A quick look

Load an animated model, then spawn it and crossfade into a walk:

await game.modelFiles.load('robot', 'models/robot.glb');
const h = game.modelFiles.spawn('robot', { size: 3 });
h.play('Walk', { loop: true, fade: 0.25 });
for (let i = 0; i < 8; i++) game.modelFiles.spawn('walker', { x: i * 2, y: 1, size: 2 }).play('Walk', { loop: true, at: i * 0.17 });

Works with

  • world-3d and render-3d — the world it spawns into and the renderer that draws its materials.
  • model-3d — models built from data instead of files; the two work side by side.
  • hull-3d — a convex collider for a loaded model under physics-3d.
  • vector-3d — draws any loaded model as outline edges from its parts' vertices.

Good to know

  • Compressed files (Draco or meshopt), quantized attributes, sparse accessors, KTX2 or WebP textures and data outside the .glb's own chunk are refused with a clear message; export without them.
  • Textures are capped at 512 pixels on their longer side in the shared atlas, and an OBJ's texture maps are not loaded, so it wears its diffuse colours.
  • Morph targets, a second uv set, occlusion and emissive maps, cameras and lights are ignored.
  • Skinning runs on the CPU and re-uploads each frame: correct, but a large crowd of skinned characters will be costly.
  • A model is fitted round its centre, so spawn it at half its size above the ground to stand it on the floor.

More Logic packs

Show all →