Skip to content

t1k:cocos:base:spine

FieldValue
Modulebase
Version3.3.2
Effortlow
Tools—

Keywords: bone, cache-mode, cocos, cocos-creator, engine-feature-trimming, feature-cropping, jiggle, physics, physics-constraint, physics-inheritance, physicsTranslate, REALTIME, skeleton, sp.Skeleton, spine, spine-3.8, spine-4.2, spine-unity, wasm, wobble

/t1k:cocos:base:spine

Spine skeletons in Cocos Creator. This skill exists because the same .skel asset that behaves correctly in Spine Editor and in spine-unity can be silently inert under sp.Skeleton, with no error, no warning, and nothing in the console.

Version scope. Behavioural claims are verified against exactly one configuration: Cocos Creator 3.8.7, Feature Cropping set to the Spine 4.2 runtime, assets exported from Spine 4.2. Animation cache mode on that project was not recorded. Each claim below is tagged [verified] (reproduced first-hand or stated in vendor documentation, cited), or [inferred] (consistent with observed behaviour but not confirmed by a source or a controlled test). Re-run the probe in § 3 rather than assuming any of it carried to another version.

  • A Spine 4.2 physics constraint reacts in Spine Editor or in Unity, but does nothing in Cocos.
  • A skeleton renders correctly but never wobbles, jiggles, or lags behind movement.
  • Porting a Spine setup from Unity to Cocos, or migrating a project from the Spine 3.8 runtime to 4.2.
  • Anyone reaches for node.setPosition() on a Node that carries an sp.Skeleton with physics constraints.

1. Preflight — three conditions that leave physics inert

Section titled “1. Preflight — three conditions that leave physics inert”

Check all three before debugging anything else. Each one produces the identical symptom: a skeleton that renders perfectly and never reacts.

1.1 The project must be running the Spine 4.2 runtime, not 3.8 [verified]

Section titled “1.1 The project must be running the Spine 4.2 runtime, not 3.8 [verified]”

Physics constraints do not exist in Spine 3.8 — they are the headline feature of 4.2 (Spine 4.2: The physics revolution). A project on the 3.8 runtime has nothing to switch on.

Cocos Creator 3.8.6 and later ship BOTH runtimes and let the project choose. Select the version in Project Settings → Feature Cropping (the Engine Feature Trimming panel), then restart the editor or the scene process — the switch does not take effect in a running process (Cocos Creator 3.8.6 release).

So the fix depends on the Creator version, and this is the step most often got wrong:

Creator versionsp.spine.Physics undefined meansAction
3.8.6+The project is set to the 3.8 runtimeSwitch to 4.2 in Project Settings → Feature Cropping, restart the editor. Do not upgrade Creator — it already has 4.2.
below 3.8.6No 4.2 runtime ships with this CreatorUpgrade Creator to 3.8.6+, then select 4.2 as above

1.2 The asset must be exported from a Spine 4.2 editor [verified]

Section titled “1.2 The asset must be exported from a Spine 4.2 editor [verified]”

Switching the runtime is not enough. A skeleton exported from a pre-4.2 Spine editor carries no physics constraint data, so the 4.2 runtime loads it and finds nothing to simulate. Per the Cocos upgrade guidance: re-export the assets from Spine 4.2 first, then overwrite the files in the corresponding project assets directory.

This is the most common cause in practice, because it survives every runtime-side fix — the runtime probe reports a healthy 4.2 environment and the skeleton still does nothing.

1.3 Animation cache mode should be REALTIME [inferred]

Section titled “1.3 Animation cache mode should be REALTIME [inferred]”

Set Animation Cache Mode to REALTIME on the sp.Skeleton component. SHARED_CACHE and PRIVATE_CACHE pre-bake animation frames, and physics is a per-frame simulation of dynamic state that a baked frame set cannot represent.

Honesty note: that physics specifically is skipped in cached mode is an inference, not a verified claim. What the vendor documents is adjacent — cached mode “does not support motion fusion, motion overlay, and only supports motion start and end events” (Spine component reference), and vertex effects are REALTIME-only. Treat REALTIME as a cheap thing to rule out, not as a proven root cause, and if you confirm the behaviour either way, record it here.

1.4 Other Spine 4.2 migration notes [verified]

Section titled “1.4 Other Spine 4.2 migration notes [verified]”
  • JitterEffect and SwirlEffect are removed in Spine 4.2. Code referencing them breaks on the switch.
  • The Mini Game Engine Separation plugin does not support Spine 4.2.

2. Physics does not observe Node movement [verified]

Section titled “2. Physics does not observe Node movement [verified]”

Once preflight passes and physics is genuinely live, this is the remaining failure.

Spine 4.2 has two coordinate spaces, and physics observes only one of them.

Skeleton space. Each bone carries worldX/worldY, derived from its parent chain plus skeleton.x/skeleton.y. Every frame, PhysicsConstraint compares the bone’s current world position against the position it remembered last frame, and turns that delta into inertial force. That comparison is the constraint’s only input.

Engine space. The Cocos Node sits outside the skeleton. Moving it multiplies a transform matrix at render time and changes nothing inside the runtime. Bone worldX/worldY are byte-identical before and after, so physics correctly concludes that nothing moved.

The rule: physics reacts to skeleton.x/skeleton.y, never to node.position.

Not a runtime difference — a bridge that Cocos lacks. The Spine 4.2 changelog states it directly: “Skeleton GameObjects now automatically apply Transform translation and rotation to the skeleton’s PhysicsConstraints. This can be disabled at the Skeleton component Inspector under Advanced - Physics Inheritance.” Position inheritance defaults to (1, 1), and the injection goes through Skeleton.PhysicsTranslate(). Setting those factors to 0 in Unity reproduces the Cocos behaviour exactly.

sp.Skeleton has no equivalent setting and performs no such injection.

Drive skeleton.x/skeleton.y instead of node.position. Get the raw runtime skeleton off the component:

const skeleton: any = (skeletonComponent as any)._skeleton;
StrategyRequirementNotes
skeleton.physicsTranslate(dx, dy)The wasm binding must expose the methodThe official Spine 4.2 API. Injects movement into the constraints without displacing the render, so the Node stays authoritative for position. Probe at runtime — whether the Cocos wasm binding exposes it is untested on any version. The one project this skill was written from used the fallback by explicit operator choice, which says nothing about availability.
Skeleton-offset bridgeNone[verified] working on 3.8.7. Park the Node at its start position and carry the whole drag offset in skeleton.x/skeleton.y.

Never apply both. Displacing the Node and the skeleton moves the character twice as far as intended.

The skeleton-offset bridge assumes the movement code sets an absolute position each frame (node.setPosition(pointerPos)). If the movement code accumulates (node.position = node.position + delta), the bridge will fight it — in that case stop moving the Node at all and drive skeleton.x/skeleton.y directly.

A drop-in component implementing both strategies, with auto-detection and startup diagnostics, ships at references/spine-physics-inheritance.ts.

Physics cannot distinguish a teleport from a violent yank. After a respawn, scene change, or any instant reposition, reset the bridge’s home position and set skeleton.x = skeleton.y = 0 in the same frame, or the character will detonate.

Run this before proposing any fix. It separates the three preflight failures from the missing bridge in one pass.

  1. Play an animation that moves a bone, touching nothing on the Node.
    • Wobble appears → physics is live. The problem is the missing node-to-skeleton bridge. Go to § 2.
    • No wobble → physics is not running. Go to step 2.
  2. Probe the runtime from the console or a start() hook:
    console.log('Physics enum:', !!(sp as any).spine?.Physics); // false -> § 1.1
    console.log('cached:', (skeletonComponent as any).isAnimationCached?.()); // true -> § 1.3
    const skeleton: any = (skeletonComponent as any)._skeleton;
    console.log('skeleton:', !!skeleton, 'physicsTranslate:', typeof skeleton?.physicsTranslate);
  3. If the probe reports a healthy 4.2 runtime and still nothing moves, suspect the asset (§ 1.2). Re-export from Spine 4.2 and overwrite. A 4.2 runtime loading a pre-4.2 export is the case that survives every runtime-side fix.
  4. Fire a synthetic impulse to test physics independently of any input code:
    skeleton.x += 150; // expect a visible reaction next frame
    Reaction here but not on drag confirms the bridge is what is missing, not the physics setup.

If _skeleton resolves to null, the binding on that Creator version stores it elsewhere. Try _instance.getSkeleton(), _instance._skeleton, then skeleton, and record the working path in this skill.

SymptomSection
sp.spine.Physics is undefined on Creator 3.8.6+§ 1.1 — switch the runtime in Feature Cropping, do not upgrade Creator
Runtime probe is healthy but nothing ever reacts§ 1.2 — asset predates Spine 4.2, re-export
Physics reacts to animation but not to movement§ 2
Character moves twice as far as the drag§ 2 — Node and skeleton both displaced
Character explodes after respawn or scene change§ 2 — Teleports
JitterEffect / SwirlEffect missing after upgrade§ 1.4 — removed in 4.2