Spotlight attached to object doesn't move with the object?

I have a camera drone animation model that I attach two objects to. The camera drone is just a black sphere with a texture. I attach a red sphere to the camera drone where the lens appears on its textureis, to make it look like a security camera lens. Works great. When I move the model, the red sphere moves with the camera drone perfectly as it moves and rotates.

However, I also attach a spotlight at the exact same place on the camera drone object. My desire is to have the spotlight beam come out of the camera drone lens so that it appears to emanate from the lens. However, when the camera drone moves, the spotlight stays in place and gets left behind, despite the fact I attach the spotlight the exact same way and in the exact same place as I attach the red sphere. In other words, when the camera drone moves away, I see the spotlight hanging in space where it was first created instead of it traveling in lock step with the camera drone.

Below is the code I use to create and attach the red sphere and spotlight. The code executes when the GLB loader callback executes.

Note: self.CAC.modelInstance is where the ThreeJS object for the camera drone animation model is stored. Also, AnimatedLight is the object I created to build a spotlight and animate it. Finally, initModelArgs is an object that contains some size, position, and other settings that are loaded from a file earlier.

Can someone tell me what I am doing wrong and how to fix this problem? Also, can you tell me what it is about the way that I think how the spotlight should work that is also wrong?

        // PARAMETERS: url, onLoad, onProgress, onError
        self.CAC.modelLoader.load(
            // url
            urlToModel,
            // onLoad
            (glb) => {
                // Size.
                glb.scene.scale.x = initModelArgs.theScale;
                glb.scene.scale.y = initModelArgs.theScale;
                glb.scene.scale.z = initModelArgs.theScale;

                self.CAC.setModelInstance(glb.scene);

                // Set the initial position.
                self.CAC.modelInstance.position.x = initModelArgs.initialPos_X;
                self.CAC.modelInstance.position.y = initModelArgs.initialPos_Y;
                self.CAC.modelInstance.position.z = initModelArgs.initialPos_Z;

                // Create an animation mixer for this model.
                self.CAC.modelAnimationMixer = new THREE.AnimationMixer(self.CAC.modelInstance);

                // Speed
                self.CAC.modelAnimationMixer.timeScale = initModelArgs.theTimeScale;

                // Add the model to the scene.
                g_ThreeJsScene.add(self.CAC.modelInstance);

                // Initialize the model completely.  The camera drone has no
                //  animations because we animate it manually, so we pass
                //  NULL to let the initializeModelCompletely() function
                //  know that.
                self.CAC.initializeModelCompletely(null);

                // NOTE: Camera drone has no animations/actions.  We animate it
                //  manually.

                // -------------------- BEGIN: SUB-OBJECTS ------------

                // Call updateCenterOfModel so our bounding box and center properties
                //  are correct.
                self.CAC.updateCenterOfModel();

                // Create the sub-objects necessary for emulating a light
                //  projector on the camera drone.

                // .................... BEGIN: SUB-OBJECT - Camera Lens ............

                const radius = 3;
                const cameraLensObj =
                    new THREE.Mesh(
                        new THREE.SphereBufferGeometry( radius, 20, 20 ),
                        new THREE.MeshPhongMaterial( { color: 0xFF0000 } ));

                cameraLensObj.position.set(0, 0, 15);

                // Add it to the top level animation model.
                self.CAC.modelInstance.add(cameraLensObj);

                // .................... END  : SUB-OBJECT - Camera Lens ............

                // .................... BEGIN: SUB-OBJECT - Light Beam ............

                const spotLightAsLightBeam_anim_obj =
                    new AnimatedLight(
                        `${self.CAC.modelName}-lens-light-beam`,
                        modelDeclJsonObj,
                        'SpotLight',
                        // Tell the animated light to augment our mini-menu
                        //  instead of creating its own.
                        self);

                // Call initialize model on the spotlight or we will not have
                //  the model instance filled in.
                spotLightAsLightBeam_anim_obj.initializeModel(self.CAC.parentAnimManagerObj, initModelArgs);

                const spotLightModelInstanceObj = spotLightAsLightBeam_anim_obj.CAC.modelInstance;

                // Position the spotlight that acts as the camera drone's light
                //  beam right on top of the small sphere we use to emulate
                //  a projector's lens.
                spotLightModelInstanceObj.position.set(0, 0, 15);

                // Add it to the top level animation model.
                self.CAC.modelInstance.add(spotLightAsLightBeam_anim_obj.CAC.modelInstance);

                // .................... END  : SUB-OBJECT - Light Beam ............

If you can’t reproduce the error in a small example, then the error must be in your framework. We cannot spot it with what you have posted.

Small tip: Perhaps you must also add spotLightModelInstanceObj.target to the model.

1 Like