Nodes/RyanOnTheInside/Static Body βš‘πŸ…‘πŸ…žπŸ…£πŸ…˜
ComfyUI Node

Static Body βš‘πŸ…‘πŸ…žπŸ…£πŸ…˜

An obstacle your particle sim actually bounces off

By ryanontheinsideΒ·Created 2 years agoΒ·Updated 5 months agoΒ· 852
Static Body βš‘πŸ…‘πŸ…žπŸ…£πŸ…˜
  • previous_body
  • STATIC_BODY
β—„shape_typeβ–Ύβ–Ί
β—„x10.00β–Ί
β—„y10.00β–Ί
β—„x21.00β–Ί
β—„y21.00β–Ί
β—„elasticity0.9β–Ί
β—„friction0.5β–Ί
β—„drawtrueβ–Ί
β—„color(255,255,255)β–Ί

If SpringJointSetting is about connecting particles to each other, StaticBody is about giving particles something fixed to collide with - a floor, a wall, a funnel, whatever shape you draw. It's the direct ComfyUI equivalent of a "static body" in the pymunk physics engine RyanOnTheInside's particle systems run on: an object with effectively infinite mass that never moves, but that other things can bounce, slide, or stop against. The README calls this out specifically - "boundary-respecting particles and static body interactions" is one of the Particle Systems bullets.

How it works

shape_type picks between a segment (a straight line defined by two points) or a polygon. For a segment, x1/y1 and x2/y2 define the two endpoints - and here's the thing to know before you place one: these are normalized 0–1 coordinates, not pixels. x=0.5, y=0.5 is the center of your canvas regardless of resolution; x=500 is meaningless and will just clamp to the edge. elasticity (0–1, default 0.9) is bounciness - 0 means a particle hits it and just stops, 1 means it bounces with essentially no energy lost. friction (0–1, default 0.5) governs how much particles slide versus grip on contact. draw and color only affect whether and how the body itself gets rendered visibly into the output - they don't change the physics.

The inputs and outputs that matter

Beyond the coordinates and physics pair above, there's one input worth understanding: the optional previous_body (type STATIC_BODY). This lets you chain multiple StaticBody nodes together - feed one node's output back into the next one's previous_body - so a whole obstacle course (walls, floor, funnel walls, whatever) collapses into a single wire carrying every obstacle at once, instead of needing a dedicated input slot per obstacle on the emitter node downstream.

The single output is STATIC_BODY - same custom type as previous_body, which is what makes the chaining trick work. It only connects to other RyanOnTheInside particle nodes.

How to install it

Via ComfyUI Manager, search "RyanOnTheInside." Or clone it manually:

cd ComfyUI/custom_nodes
git clone https://github.com/ryanontheinside/ComfyUI_RyanOnTheInside.git
cd ComfyUI_RyanOnTheInside
pip install -r requirements.txt

Restart ComfyUI. Like the rest of the particle system nodes, this depends on pymunk from the pack's requirements.txt - check your startup console for import errors if the particle-family nodes aren't showing up.

Common issues & troubleshooting

The normalized-coordinates trap is the one that gets almost everyone at least once: type in pixel coordinates thinking you're placing a wall at a specific spot, get a wall that's either invisible (clamped off-canvas) or in a completely wrong spot. Stick to 0–1 fractions of your canvas.

The other common one is the chaining trick above - if you drop several StaticBody nodes into a graph but forget to actually wire each one's output into the next one's previous_body, only the last node you feed into the emitter survives; the earlier obstacles you thought you'd added silently don't exist as far as the particle sim is concerned. If particles are sailing straight through an obstacle you swear you built, check that chain first.

elasticity at 0 with friction at 1 is a good combo for something that should feel like sticky sand rather than a wall; both maxed out is closer to a superball. There's no single "right" setting - it depends entirely on what the collision is supposed to look like.

CategoryRyanOnTheInside/ParticleSystems/Modulators

Inputs (10)

NameTypeDefaultDescription
shape_typeCOMBOType of shape ("segment" or "polygon")
x1FLOAT0.000–1First X coordinate
y1FLOAT0.000–1First Y coordinate
x2FLOAT1.000–1Second X coordinate
y2FLOAT1.000–1Second Y coordinate
elasticityFLOAT0.90–1Bounciness of the static body (0.0 to 1.0)
frictionFLOAT0.50–1Friction of the static body (0.0 to 1.0)
drawBOOLEANtrueWhether to visualize the static body and how thick
colorSTRING(255,255,255)Color of the static body (RGB tuple)
previous_bodyoptSTATIC_BODYβ€”

Outputs (1)

NameTypeDescription
STATIC_BODYSTATIC_BODYβ€”