Everywhere actions, Material switch and animations

I have one model with animated parts triggered by the Everywhere action PlayAnimationOnClick, and I am changing the model’s material with the ChangeMaterialOnClick Everywhere action.

The problem is when I change the material, parts that have that material are no longer visible in the animation.

Here is the link to the video:

Hi Tomislav, it sounds like the animated parts (which are likely skinned meshes) are disappearing because the new material you apply isn’t set up to support skinning. When a skinned mesh is animated, its material needs its .skinning property enabled so that the bone-driven vertex deformations are correctly applied. If the new material (switched via ChangeMaterialOnClick) doesn’t have skinning enabled, those parts won’t render properly.

A straightforward fix is to make sure that after switching, the new material has skinning enabled. For example, you can create a custom behaviour that runs right after the material switch:


import { Behaviour, Renderer } from "@needle-tools/engine";

export class EnableSkinningOnMaterial extends Behaviour {
  onEnable() {
    const renderer = this.gameObject.getComponent(Renderer);
    if (!renderer) return;
    renderer.sharedMaterials.forEach(mat => {
      if (mat) {
        // Ensure the material supports skinning
        (mat as any).skinning = true;
      }
    });
  }
}

Attach this script to the same game object containing your animated skinned mesh. This ensures that even if the ChangeMaterialOnClick action swaps the material, the skinning flag is properly set.

Also, if you’re using a custom shader or a material that isn’t the default Three.js skinning material (such as MeshStandardMaterial with skinning enabled), double-check its settings. This approach is aligned with how the Everywhere Actions (see the ChangeMaterialOnClick component documentation (docs/everywhere-actions.html)) work in Needle Engine.

Give that a try, and let us know if it resolves your issue.

4 replies left
thread_tlwNmk87GTNN7dfJdtnAEUFU
Reply to this post directly if you need further help (bottom right button)

I have attached the script, and it didn’t work.

Hi Tomislav, thanks for sharing that your initial solution didn’t work. Since the animated parts disappear after switching the material, it’s highly likely that the new material isn’t correctly set up for skinned meshes. In three.js (and therefore in Needle Engine), when a mesh is animated via bone transformations, its material must have its skinning flag enabled at the time of shader compilation. Simply toggling the skinning flag after the fact may not work unless we also force a shader recompile.

Here are a couple of suggestions you can try:

  1. Ensure the target material is created (or cloned) from a material that already has skinning enabled. For example, when preparing your material in Unity (or in your material assets), adjust it so that its generated Three.js material has the skinning flag set. This is usually done by setting “skinning” in the material’s properties. This way the material is correctly compiled for skinned meshes straight away.

  2. If you need to enforce the skinning flag in code after the material switch, try adding a small delay before reapplying the skinning flag and forcing a recompile. For example, you might write a behaviour like this:

import { Behaviour, Renderer } from "@needle-tools/engine";

export class ReapplySkinningAfterMatSwitch extends Behaviour {
  async onEnable() {
    // Wait a short moment for the material change to complete.
    await new Promise(resolve => setTimeout(resolve, 50));
    const renderer = this.gameObject.getComponent(Renderer);
    if (!renderer) return;
    for (const mat of renderer.sharedMaterials) {
      if (mat) {
        (mat as any).skinning = true;
        mat.needsUpdate = true;
      }
    }
  }
}

Attaching this component to the same object with the animated (skinned) mesh can help ensure that—even after the ChangeMaterialOnClick action runs—the shader is recompiled with skinning enabled. You might need to tweak the delay (here 50 milliseconds) to match your scene’s update order.

  1. Verify that your target material’s shader supports skinning in the first place. If you’re using a custom shader or a material type that doesn’t include normal skinning support (for example, a MeshBasicMaterial), the animation may not show even when the skinning flag is enabled.

These points are in line with how the Change Material on Click action is designed in Needle Engine, which internally relies on proper material setups (see the Everywhere Actions docs (docs/everywhere-actions.html)). If none of these approaches work, please let me know more details about your material asset (for example, whether it’s a standard or custom shader) and the configuration of your animated skinned mesh. This additional information will help diagnose whether the issue stems from execution order, material compatibility, or something else.

Let me know how it goes, and thanks for your patience!

4 replies left
thread_tlwNmk87GTNN7dfJdtnAEUFU
Reply to this post directly if you need further help (bottom right button)

I am using UnityGLFT/PBRGraph shader and can’t see that option, what shader should I use?

Hi Tomislav, since the UnityGLTF/PBRGraph shader doesn’t expose a skinning option, you’ll need to use a shader that ensures skinning is enabled out of the box. For animated skinned meshes in Needle Engine, the recommended approach is to use a shader that converts to a Three.js MeshStandardMaterial with its skinning flag enabled. In practice, that means switching to a shader like the built-in URP/Lit shader (or another supported standard shader) rather than UnityGLTF/PBRGraph.

When you use URP/Lit, Unity’s export will convert it to a Three.js material where skinning is baked in, so your animated parts remain visible during animation. This is because Three.js’s MeshStandardMaterial automatically supports skinning when the skinning property is set to true at creation. If you’re setting up your animations via Needle Engine’s ChangeMaterialOnClick action, ensuring your material is based on a standard PBR shader (as provided by URP/Lit) will prevent issues with your animated (skinned) parts disappearing.

For more details on shader compatibility and recommendations for glTF exports, you can check the UnityGLTF documentation where they advise using UnityGLTF/PBRGraph by default—but note that advanced skinning support for animated models may require using a different shader variant (see at UnityGLTF-readme.md and (docs/export.html)).

Let me know if this helps or if you need more details!

3 replies left
thread_tlwNmk87GTNN7dfJdtnAEUFU
Reply to this post directly if you need further help (bottom right button)

I have changed the shader to Universal Renderer Pipeline/Lit, exported, and the behavior is the same as before; model parts that move are not visible when the color is changed.

Hello @Tomislav_Stefan could you send a bugreport with your scene?

I have sent a bug report.