# Animating multiple objects simultaneously

**URL:** <https://discourse.threejs.org/t/animating-multiple-objects-simultaneously/52778>\
**Category:** Questions\
**Tags:** animation\
**Created:** [June 13, 2023, 8:05pm UTC](https://discourse.threejs.org/t/animating-multiple-objects-simultaneously/52778 "2023-06-13T20:05:52Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kmetho](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/kmetho/32/37198_2.png) [@Kmetho](https://discourse.threejs.org/u/Kmetho)\
**Post date:** [June 13, 2023, 8:05pm UTC](https://discourse.threejs.org/t/animating-multiple-objects-simultaneously/52778/1 "2023-06-13T20:05:52Z")

</div>

I have exported 8 animated objects from blender as ‘.glb’ files into my three.js code, but when I’m loading them into a website, only the first is animated. Why is that?  
Here’s my whole code, because maybe I’m missing something out of tiredness:

```javascript
import "./style.css";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";

// setup

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector("#bg"),
});

renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.setZ(30);

renderer.outputColorSpace = THREE.SRGBColorSpace;

// setting controls

const controls = new OrbitControls(camera, renderer.domElement);

// light

const pointLight = new THREE.PointLight(0xffffff);
pointLight.position.set(5, 5, 5);
const ambientLight = new THREE.AmbientLight(0xffffff);
scene.add(pointLight, ambientLight);

// helpers

const lightHelper = new THREE.PointLightHelper(pointLight);
const gridHelper = new THREE.GridHelper(200, 50);
scene.add(lightHelper, gridHelper);

// cubeMap texture images
const cubeTextureLoader = new THREE.CubeTextureLoader();
const cubeMap = cubeTextureLoader.load([
  "/images/px.png",
  "/images/nx.png",
  "/images/py.png",
  "/images/ny.png",
  "/images/pz.png",
  "/images/nz.png",
]);

//stars
Array(400)
  .fill()
  .forEach(() => {
    const geometry = new THREE.SphereGeometry(0.2, 24, 24);
    const material = new THREE.MeshStandardMaterial({ color: 0xffffff });
    material.envMap = cubeMap;
    material.envMapIntensity = 10;
    const star = new THREE.Mesh(geometry, material);
    const [x, y, z] = Array(3)
      .fill()
      .map(() => THREE.MathUtils.randFloatSpread(100));
    star.position.set(x, y, z);
    scene.add(star);
  });

// bg
const bg = new THREE.TextureLoader().load("/images/bg.png");
scene.background = bg;

// crystals
let materials = [
  new THREE.MeshStandardMaterial({
    color: 0xe7e2da,
    emissive: 0x000fe7,
    roughness: 0,
    metalness: 1,
    flatShading: true,
    vertexColors: true,
    fog: true,
  }),

  new THREE.MeshStandardMaterial({
    color: 0x1e00c4,
    emissive: 0x5700e7,
    roughness: 0,
    metalness: 1,
    flatShading: true,
    vertexColors: true,
    fog: true,
  }),

  new THREE.MeshStandardMaterial({
    color: 0xe7d29a,
    emissive: 0x0b0b0b,
    roughness: 0,
    metalness: 1,
    flatShading: true,
    vertexColors: true,
    fog: true,
  }),

  new THREE.MeshStandardMaterial({
    color: 0x77feff,
    emissive: 0x949494,
    roughness: 0,
    metalness: 1,
    flatShading: true,
    vertexColors: true,
    fog: true,
  }),

  new THREE.MeshStandardMaterial({
    color: 0x1a00e7,
    emissive: 0x000000,
    roughness: 0,
    metalness: 1,
    flatShading: true,
    vertexColors: true,
    fog: true,
  }),

  new THREE.MeshStandardMaterial({
    color: 0xb4895a,
    emissive: 0x684f31,
    roughness: 0,
    metalness: 1,
    flatShading: true,
    vertexColors: true,
    fog: true,
  }),

  new THREE.MeshStandardMaterial({
    color: 0xfffffd,
    emissive: 0x8a00e7,
    roughness: 0,
    metalness: 1,
    flatShading: true,
    vertexColors: true,
    fog: true,
  }),

  new THREE.MeshStandardMaterial({
    color: 0x9dc1e7,
    emissive: 0x001be7,
    roughness: 0,
    metalness: 1,
    flatShading: true,
    vertexColors: true,
    fog: true,
  }),
];

materials.forEach((element) => {
  element.envMap = cubeMap;
  element.envMapIntensity = 1;
});

let crystals = ["c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8"];
let mixers = [];
let loader = new GLTFLoader();

crystals.forEach((element, index) => {
  let material = materials[index];
  loader.load(
    "/action/" + element + ".glb",
    function (gltf) {
      gltf.scene.traverse(function (node) {
        if (node.isMesh) {
          node.material = material;
        }
      });
      scene.add(gltf.scene);
      mixers[index] = new THREE.AnimationMixer(gltf.scene);
      let clips = gltf.animations;
      let clip = THREE.AnimationClip.findByName(clips, element + "-action");
      mixers[index].clipAction(clip).play();
    },
    undefined,
    function (error) {
      console.error(error);
    }
  );
});

// loop
const clock = new THREE.Clock();

function animate() {
  requestAnimationFrame(animate);
  mixers.forEach((mixer) => {
    mixer && mixer.update(clock.getDelta());
  });

  controls.update();

  renderer.render(scene, camera);
}

animate();

window.addEventListener("resize", () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});

```

Thank you for your time!

---

<div class="post-metadata">

**Author:** ![mjurczyk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mjurczyk/32/10995_2.png) [@mjurczyk](https://discourse.threejs.org/u/mjurczyk)\
**Post date:** [June 13, 2023, 8:54pm UTC](https://discourse.threejs.org/t/animating-multiple-objects-simultaneously/52778/2 "2023-06-13T20:54:58Z")

</div>

> [@Kmetho](#):
>
> I’m missing something out of tiredness:

1. Rest.
2. When faced with issue like this, reduce amount of duplicated / iterated elements to 2 (max. 3.) Then start console logging values of `index`, `mixers`, etc - anything that may be connected to the crystals being animated - then just compare logs and determine what doesn’t look right.
3. When using older versions of three, you may need to set `skinning = true` on the overriding materials to make animations work ([github](https://github.com/mrdoob/three.js/pull/21788).)

---

<div class="post-metadata">

**Author:** ![Kmetho](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/kmetho/32/37198_2.png) [@Kmetho](https://discourse.threejs.org/u/Kmetho)\
**Post date:** [June 14, 2023, 5:24pm UTC](https://discourse.threejs.org/t/animating-multiple-objects-simultaneously/52778/3 "2023-06-14T17:24:12Z")

</div>

Ok so I discovered that only the first animation is playing because it’s first in my code. When I put animation nr 2 ahead, then only nr 2 is moving etc. I’m still learning how to code, is there a way around this that I don’t know of?

---

<div class="post-metadata">

**Author:** ![seanwasere](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/seanwasere/32/20864_2.png) [@seanwasere](https://discourse.threejs.org/u/seanwasere)\
**Post date:** [June 14, 2023, 5:43pm UTC](https://discourse.threejs.org/t/animating-multiple-objects-simultaneously/52778/4 "2023-06-14T17:43:25Z")

</div>

Look at this section

> [@Kmetho](#):
>
> ```javascript
> mixers.forEach((mixer) => {
> mixer && mixer.update(clock.getDelta());
> });
> 
> ```

use `getDelta()` once per loop, and then reuse it.

```javascript
delta = clock.getDelta()
mixers.forEach((mixer) => {
    mixer && mixer.update(delta);
});

```

Example : [Sharing Animation Clips - Three.js Tutorials](https://sbcode.net/threejs/sharing-animationclips/)

[![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/0/0/004cbf5dcbd2280ee07c38d59176550af87bf634.png)](https://sbcode.net/threejs/sharing-animationclips/)

---

<div class="post-metadata">

**Author:** ![phil\_crowther](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/phil_crowther/32/64202_2.png) [@phil\_crowther](https://discourse.threejs.org/u/phil_crowther)\
**Post date:** [June 14, 2023, 5:45pm UTC](https://discourse.threejs.org/t/animating-multiple-objects-simultaneously/52778/5 "2023-06-14T17:45:18Z")

</div>

In my experience, if you are loading Blender objects with animations, you need to also load the animations. Once you loaded and saved them you can activate as many of them as you want. Does each object only have a single animation?

Here is an extract from a file that loads a gltf/glb object and loads the animations by name:

```javascript
function loadACMine(filename) {
	gltfLoader.load(filename, function (gltf) {	
		ACMine = gltf.scene; // a gltf/glb file is really a collection
		/* Animations ------------------------------------------------------------- */
		// Propeller
		let clip = THREE.AnimationClip.findByName(gltf.animations, "propellerAction");
		mxProp = new THREE.AnimationMixer(ACMine);
		let actun = mxProp.clipAction(clip);
		actun.play();
		if (mxProp) mxProp.setTime(spnprp/anmfps);
		// Rudder
		mxRudr = new THREE.AnimationMixer(ACMine);
		clip = THREE.AnimationClip.findByName(gltf.animations, "rudderAction");
		actun = mxRudr.clipAction(clip);
		actun.play();
		if (mxRudr) mxRudr.setTime(rudder/anmfps);
		****
		// Add to Scene
		scene.add(ACMine);
	});
}

```

---

<div class="post-metadata">

**Author:** ![Kmetho](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/kmetho/32/37198_2.png) [@Kmetho](https://discourse.threejs.org/u/Kmetho)\
**Post date:** [June 15, 2023, 11:35am UTC](https://discourse.threejs.org/t/animating-multiple-objects-simultaneously/52778/6 "2023-06-15T11:35:40Z")

</div>

I can’t believe how easy the solution is! Thank you so much!

---

<div class="post-metadata">

**Author:** ![Kmetho](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/kmetho/32/37198_2.png) [@Kmetho](https://discourse.threejs.org/u/Kmetho)\
**Post date:** [June 15, 2023, 11:36am UTC](https://discourse.threejs.org/t/animating-multiple-objects-simultaneously/52778/7 "2023-06-15T11:36:11Z")

</div>

Thank you for your time and effort!

---

<div class="post-metadata">

**Author:** ![Harold](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/harold/32/32136_2.png) [@Harold](https://discourse.threejs.org/u/Harold)\
**Post date:** [June 15, 2023, 2:05pm UTC](https://discourse.threejs.org/t/animating-multiple-objects-simultaneously/52778/8 "2023-06-15T14:05:11Z")

</div>

> [@seanwasere](#):
>
> use `getDelta()` once per loop, and then reuse it.

This is a bad design decision. A _getter_ accessor should never modify the state of itself.  
Too bad fixing it would introduce a huge bc-break. ☹

---

<div class="post-metadata">

**Author:** ![interface2037](https://avatars.discourse-cdn.com/v4/letter/i/ee7513/32.png) [@interface2037](https://discourse.threejs.org/u/interface2037)\
**Post date:** [May 20, 2025, 10:55pm UTC](https://discourse.threejs.org/t/animating-multiple-objects-simultaneously/52778/9 "2025-05-20T22:55:09Z")

</div>

Work for me !
