IPointerClickHandler doesn't work with out Mesh Renderer

For a clickable collider with IPointerClickHandler - does not receive events. Unless i give it a Mesh Renderer and Material.

Optimally I would just give the game object a Box Collider with no need For a Mesh Renderer.

  • image
  • image

For clickable objects that need a bigger and less complex hitbox with out needing to add a invisible material or physics

Hi Ariel, this behavior comes from how the engine’s pointer events are set up. Under the hood, Needle Engine relies on three.js’ raycaster, which only picks up intersections with objects having actual rendered geometry (i.e. a MeshRenderer with a material attached). Without a mesh, even if you attach a collider (or BoxCollider‑like component), there’s simply no raycastable geometry for the event system to “hit” (see (docs/for-unity-developers.html) and at PointerEvents.d.ts.md).

A common workaround is to attach a minimal invisible mesh that matches your collider’s shape. For example, you can create a BoxGeometry with a MeshBasicMaterial set to transparent with opacity 0. This gives the engine the geometry it needs for the raycaster while keeping it visually hidden. Here’s a quick example:


import { Behaviour, IPointerClickHandler, PointerEventData } from "@needle-tools/engine";
import { Mesh, BoxGeometry, MeshBasicMaterial } from "three";

export class InvisibleClickable extends Behaviour implements IPointerClickHandler {
    awake() {
        // If no visible mesh is present, add a dummy one for raycasting.
        if (!this.gameObject.getComponent("MeshRenderer")) {
            const dummyMesh = new Mesh(
                new BoxGeometry(1, 1, 1),
                new MeshBasicMaterial({ transparent: true, opacity: 0, depthWrite: false })
            );
            this.gameObject.add(dummyMesh);
        }
    }
    
    onPointerClick(event: PointerEventData) {
        console.log("Clicked " + this.name);
    }
}

This approach ensures that even though the mesh isn’t rendered visibly, the pointer events will work correctly.

If you’d prefer not to add any extra mesh at all, you’d need to implement a custom raycasting solution that uses your collider data instead of the rendered geometry. However, that isn’t provided out of the box in Needle Engine right now.

I hope this clears things up! Let me know if you need further assistance.

1 replies left - Become PRO for more replies.
thread_1kJvqFQHDkzylc7Th6KgfDMx
Reply to this post directly if you need further help (bottom right button)

Hello @Ariel

Did you run into any performance issues with the default raycasting system - e.g. when you simply use your regular mesh that is also used for rendering?

Needle Engine does under the hood employ two strategies that make it more performant than you might think:

  • We use a lower-resolution mesh LOD that is automatically generated on export. So when you export with progressive meshes enabled (default) then your potentially high-poly mesh is not used for raycasting but instead a lowres mesh (similar to a proxy mesh)
  • We also use three-mesh-bvh which generates BVH structures on worker threads in the background to significantly improve raycasting performance.

If you have a case where raycasts are still slow or cause problems it would be great if you could share those!

This topic was automatically closed 13 days after the last reply. New replies are no longer allowed.