Live demo: gml-character-rig.netlify.app
Upload a single sprite sheet (3×3, 9 cells) and this web tool slices it into parts, previews the character's motions live, and lets you download a ready-to-use GML script for GameMaker Studio 2. You can also add a weapon image.
Everything runs locally in the browser — no image is ever uploaded to a server.
- Zero setup — a static site with no build step or dependencies. Open
index.htmlor visit the live demo. - Instant slicing — drop in any square sheet and it's sliced into 9 body parts automatically.
- Live motion preview — 8 built-in motions with adjustable playback speed, zoom, and pan.
- Fine-grained spacing controls — tune head/torso height, arm and leg spread, and weapon placement with sliders, then copy the result straight into GameMaker.
- One-click GML export — downloads a single, dependency-free
.gmlscript that mirrors the web preview exactly. - Optional weapon layer — a separate center-pivot image held in the right hand, drawn behind the arm normally and in front during attacks.
[Front Hair] [Face] [Back Hair]
[Left Arm] [Front Torso] [Right Arm]
[Left Leg] [Back Torso] [Right Leg]
- Any size works, as long as it's square. The sheet is sliced into 9 cells by dividing width/height into thirds. (each cell =
width/3 × height/3) - Arms and legs swing from a pivot at the top of the cell (shoulder/hip).
- The weapon is a separate image (origin = center) held in the right hand, drawn in front of the character. You can preview it in the extra cell below the bottom-left (left leg) cell.
- When the page loads, a built-in example (
example.png/example_weapon.png) appears in the preview. - Upload your own character sheet / weapon image (optional) — the preview updates instantly.
- Preview controls:
- Motion dropdown · play/pause · flip horizontally · show/hide weapon (⚔) · copy spacing (⧉) · zoom (0.5×/1×/2×/4×, drag to pan)
- Speed input, and spacing fine-tuning (body/face height, arm/leg X/Y, hand-to-weapon gap, weapon angle) — via sliders or direct numeric input
- ⬇ Download GML Script → paste it into GameMaker.
- ⧉ Copy → copies the currently tuned spacing as a
zuo_motion_setgaps(id, …)call to your clipboard.
idle · walk · run · jump · attack1 (Slash Down) · attack2 (Slash Up) · attack3 (Thrust) · hit
- Import the sheet PNG as a sprite (single frame). For the weapon sprite, set the origin to Middle Centre.
- Create a script asset and paste the contents of the downloaded
scr_zuo_motion.gml. - In your character object's 3 events:
// ① Create — register the character (weapon is optional)
zuo_motion_create("hero", spr_mysheet, spr_sword);
// (optional) apply the spacing you tuned in the web preview — the value copied by ⧉
zuo_motion_setgaps("hero", -1.95, 0.090, -1.65, 0.060, -1.40, 0.30, 1.00);
// ② Step — switch motions whenever you want
if (keyboard_check_pressed(vk_space)) zuo_motion_change("hero", "attack1");
if (hspeed != 0) zuo_motion_change("hero", "walk");
zuo_motion_change("hero", "run", 1.5); // 3rd argument = playback speed for that motion
// ③ Draw — draw the animation
zuo_motion_draw("hero", x, y, 1, image_xscale, image_yscale, image_alpha, c_white);| Argument | Meaning |
|---|---|
id |
the name used in create |
x, y |
draw position = the character's feet (ground). In a platformer, just pass the instance's x/y |
spd |
animation speed. 1 = normal, 2 = 2x, 0.5 = half (multiplied by the per-motion speed) |
xscale |
horizontal size. 1 = original, 2 = 2x. Negative faces right (left by default) |
yscale |
vertical size (usually the same as xscale) |
alpha |
opacity, 0–1 |
blend |
color tint. c_white = none. Hit-flash example: merge_colour(c_white, c_red, 0.5) |
[spacing] |
(optional) overall part-spacing multiplier. Uses the default if omitted |
| Function | Description |
|---|---|
zuo_motion_create(id, sprite, [weapon]) |
register a character (optional weapon sprite, origin = center) |
zuo_motion_draw(id, x, y, spd, xscale, yscale, alpha, blend, [spacing]) |
advance the timer and draw the assembled animation |
zuo_motion_change(id, motion, [speed]) |
switch motions (optional argument = playback speed for that motion) |
zuo_motion_setgaps(id, headY, armX, armY, legX, legY, handLen, handRot) |
apply fine-tuned spacing at runtime (copied from the web tool via ⧉) |
zuo_motion_get(id) |
current motion string |
zuo_motion_exists(id) |
whether the id exists |
zuo_motion_destroy(id) |
free an id |
zuo_motion_set_time(id, t) |
manually set the animation tick |
The #macro ZUO_* values at the top of the script are the global default spacing. They map 1:1 to the web tool's spacing controls.
| Macro | Meaning |
|---|---|
ZUO_HEAD_Y / ZUO_TORSO_Y |
head/face height and torso height (more negative = higher) |
ZUO_ARM_X / ZUO_ARM_Y |
arm left-right spread / vertical position |
ZUO_LEG_X / ZUO_LEG_Y |
leg left-right spread / vertical position |
ZUO_WPN_HANDLEN / ZUO_WPN_HANDROT |
hand-to-weapon gap / weapon angle |
ZUO_FACE |
default facing: -1 = left, 1 = right |
- Adjust global defaults via the macros, and per-character spacing via
zuo_motion_setgaps.
.
├── index.html # page markup / UI
├── style.css # styling
├── app.js # UI wiring: upload, slice guide, preview controls, downloads
├── rig.js # shared animation core (single source of truth for layout + motion math)
├── preview.js # canvas renderer for the web preview
├── gml-generator.js # builds the downloadable GML script text
├── template.js # generates the built-in example sheet as a fallback
├── example.png # default example character sheet
└── example_weapon.png # default example weapon image
rig.js is the single source of truth for the grid layout and motion math — both the web preview (preview.js) and the exported GML script (gml-generator.js) implement the exact same formulas, so what you see on the site is exactly what you get in GameMaker.
No build step, no dependencies — just open index.html directly in a browser, or serve the folder with any static file server.