Phaser AE

3D Attachments

Free packv3.0.0-23DLogic

Anything that rides something else, a turret on a tank, a weapon in a hand, a light on a lamp post, keeps its place on its parent. And one object can be built from two meshes, a tile and its number, a card and its border, that move, turn and scale as one.

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

Released October 14, 2026 · updated October 19, 2026

3D Attachments: 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.

The pack

attach3d

function attach3d(): Pack<{ attach: Attach3dApi }>

The attach-3d pack: local poses composed into world poses every step. Requires a 3D world. The child is written in WORLD space, so nothing else in the engine has to know it is attached.

Types

Attach3dApi

interface Attach3dApi

game.attach.

  • to(child: Handle, parent: Handle, offset?: AttachOffset): void — Attach child to parent at a local offset. Re-attaching moves it.
  • detach(child: Handle): void — Detach, leaving the child where it currently is in the world.
  • parentOf(child: Handle): Handle | null — The parent of a child, or null.
  • childrenOf(parent: Handle): ReadonlyArray<Handle> — Everything attached to a parent, direct children only.
  • offset(child: Handle, offset: AttachOffset): void — Change a child's local offset without re-attaching. Only the fields given are written.
  • readonly count: number — How many attachments are live.

AttachFace

type AttachFace = 'top' | 'bottom' | 'left' | 'right' | 'front' | 'back'

A face of the parent's box, named by the direction it looks. The child is laid ON that face: its local +Y — the way every geometry-3d plane already faces — is turned to point out along the face normal, and its position is the centre of that face, in the parent's own units, so it stays put however the parent is scaled or turned.

AttachOffset

interface AttachOffset

Where a child sits relative to its parent.

  • x?: number — Local x. Default 0. In the PARENT's units when face or inheritScale is set, world units otherwise.
  • y?: number — Local y. Default 0. In the PARENT's units when face or inheritScale is set, world units otherwise.
  • z?: number — Local z. Default 0. In the PARENT's units when face or inheritScale is set, world units otherwise.
  • yaw?: number — Local yaw, radians. Default 0. Applied within the child's own frame, so it spins in place on a face.
  • pitch?: number — Local pitch, radians. Default 0.
  • roll?: number — Local roll, radians. Default 0.
  • sx?: number — The child's local x scale. Defaults to whatever it had when it was attached.
  • sy?: number — The child's local y scale. Defaults to whatever it had when it was attached.
  • sz?: number — The child's local z scale. Defaults to whatever it had when it was attached.
  • inheritScale?: boolean — Ride the parent's SIZE as well as its pose: the child's own scale becomes its local scale times the parent's, per axis, and its offset is measured in the parent's units. Default false — a crate's size never inflates its rider, and that remains the common case. Turn it on when parent and child are one object made of two meshes: a tile and the number on it, a card and its border, a button and its cap. Then one tween of the parent's scale — a pop, a squash, a shrink into nothing — moves the whole assembly, instead of every mesh being driven by hand in step.
  • face?: AttachFace — Lay the child ON a face of the parent's box: see AttachFace. Position, orientation and the parent's units are all handled, so a label stays centred and flat on a face of a box that is being scaled, spun and tweened.
  • lift?: number — How far clear of that face to sit, in WORLD units. Default 0.002. Two exactly coplanar surfaces fight for the depth buffer and the seam flickers as the camera moves, so a plate on a face needs a hair of clearance. This is that hair, not a design offset — it stays a fixed world distance however the parent is scaled, because depth precision does not care how big the parent is. Put deliberate distance in y instead, which is measured in the parent's units.