npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

threejs-easybugs

v0.1.2

Published

![Cover Image](cover.jpg)

Readme

Cover Image

Live Demo: https://bandinopla.github.io/threejs-easybugs/ Source code: demo/demo.ts

🤖 AI Docs: Chat with the documentation + Audio Guide

What is this?

Easily setup a rig to create bugs that have many legs and will stick to the surface in which they are walking. They use the CCDIKSolver to adjust the skeleton of the bug to move the legs using IK so it looks somewhat realistic. Great for decorative props in games or to simulate creatures walking on surfaces with varying height!

Features

  • Works nicely in conjuntion with InstancedAnimatedMesh to instantiate many bugs all sharing the same skeleton!
  • Plug in your own movement behaviour
  • Plug in your own raycast (ground finder) behaviour.
  • Minimal API ( no need to remember much )
  • Plug in your own custom gait function

How does it work?

There are 2 parts:

  1. The movement itself of the bug's body
  2. [Optional] the IK of the legs to move along the surface...

You can skip the IK part if you don't care about the movement of the legs. The main bug's handler just focuses on moving on top of a surface.

The surface

This implementation uses a "raycast cage" which basically means it expects a reference to a bounding box (empty object with non uniform scale and posibly even rotated) of the available area where the bugs can move AND the "strategy" to use to know how to cast rays to find the ground.

Currently there are 2 build in strategies:

  1. "DOME" : it will treate the bounding box as a dome, ignoring the bottom half. Rays are casted fromthe dome's surface inwards towards the center.
  2. "BASIC" : a box where rays are thrown from the top to the base.

Setup

Import the rigger:

import { BugRig } from "threejs-easybugs";

This is the rig's handler, it is not an object3d it just handles the internals to move the bug's body and optionally it's legs.

// here body is just the Object3D of your bug, the thing that represent's the bug's potition. 
const bug = new BugRig(body, {
		collisionLayer: 2, //Layer to use to "hit the ground" where you put your collidable objects so the raycast ignores everything else
});

// Optional, configure how the legs will move:
bug.setupLegsIK({
			// rig: roachRig, ///<--- Optional, in case the rig is not inside of "body"
			legs: [
				{
					goal: "legAfootGoal.L", // name of the goal gone
					foot: "legAfoot.L", // name of the foot bone
					chainLength: 3, // how many bones are in the leg
					mirror: true, // will copy and rename .L to .R

					// Limits for the rotation of the bones. If not set, there are no limits
					//rotationMin: new Vector3(x,y,z) for the min rotation
					//rotationMax: new Vector3(x,y,z) for the max rotation
				},
				{
					goal: "legAfootgoal.L.001",
					foot: "legAfoot.L.001",
					chainLength: 3,
					mirror: true,
				},
				{
					goal: "legAfootgoal.L.002",
					foot: "legAfoot.L.002",
					chainLength: 3,
					mirror: true,
				},
			],
			iterations: 13, // how many the IK solver will run
			stepTransitionDuration: 0.1, //seconds taken to a leg to move from pointA to B
			footMaxDistanceFromGoal: 0.01, //distance the foot has to be from the goal to trigger a new step

			
			stepHeight: 1 // how high the foot will lift from the ground when moving from one place to the other. In LOCAL SPACE of the body
		});

// the IK config from above will create a total of 6 legs

// here "dome" is just an empty object in stage scale and positioned where you want the bug to live inside of...
bug.setRaycastCage(dome, "dome");

// initialize the bug to a random location inside that raycast cage
bug.placeAtRandomPosition();

// and in your render loop...
bug.update( delta );

The skeleton's rig

Your skeleton should:

  • Have one goal bone per leg at the root of the armature.
  • the foot bone is what will try to achieve the goal bone. It works the same way as in blender's IK Constrain. In fact, it is advisable to setup an IK constraint on your skeleton so your animations respect the IK too during animation.

Rig setup

Custom body behaviour

The bug by default will use a "random walk" behaviour to pick the next step to walk to. But you can define your own behaviour extending the BugBehaviour class:

import { Object3D, Vector3 } from "three";
import { BugBehaviour } from "threejs-easybugs"; 

export class CustomBehaviourExample extends BugBehaviour {

	//
	// this is the method you override to pick a random point to walk next.
	// The "nextStep" shoudl be mutated bu you, and it is in the local space of the body.
	//
	protected override calculateNextStepFor(
		body: Object3D,
		nextStep: Vector3,
	): void {

		// for eaxample till will pick a point ahead by 3 units and to the right...

		nextStep.set(1, 0, 3);
	}
}

And you would assign your behaviour to your bug this way:

yourBug.behaviour = new CustomBehaviourExample();

Custom legs gait behaviour

A gait function tells the entire group of legs which leg and move and which leg has to stay in place. After the moving legs reach their next position, the gait function is called again to decide which legs have to move next and which legs have to stay in place. A gait can be as simple or complex as you want.

To define your own, in the setupLegsIK config define...

bug.setupLegsIK({
	...
	gaitFunction: yourCustomGaitFunction
	...
});

It should be a generator function and will recieve a list of ik goal bones and should set to true/false the ones that can move and the ones that can't. Example:

// THis will allow only 1 leg at a time...
function* yourCustomGaitFunction(bones: GaitBone[]) {
	let idx = 0;

	while (true) {
		bones[idx].canMove = true;
		yield;
		bones[idx].canMove = false;
		idx = (idx + 1) % bones.length;
	}
}

Questions?

@bandinopla