getObjectByName() - how hard can it be?

Hi there!

I load in a model, traverse through it and can see mesh names perfectly in console.log. Outside this function i try to get acces to these meshes by their names but when i console.log the output it’s “undefined”. I tried a million things (or at leat it feels like it) but i’m getting nowhere. I even tried making the geometry name the same as the mesh name but no difference. Apparently my approach is wrong…

This is my model loading function

function loadModel(){
                colorValue = document.getElementById("chaircolor").value;
                colorValue = new THREE.Color(colorValue);
                let loader = new GLTFLoader().setPath('./models/');
                    loader.load('chair3207.gltf', function(gltf){

                        gltf.scene.traverse(function(child){
                            if (child.isMesh){
                        
                                if (child.name) {
                                    child.material = new THREE.MeshPhongMaterial({color: colorValue, flatShading: false});
                                }
                                console.log(child.name);

                            }
                        });
                    
                        scene.add(gltf.scene);

                        render();
                    });
            }

And my little test to try access the meshes and manipulate their attributes (this is outside any functions:

let theResult = scene.getObjectByName("cloth", true);
        console.log(theResult);

I’m a beginner with javascript and moving forward but this has just caught me up. Hope you can help me out here.
Many thanks,
Henrik

2 things:

  • Are you searching scene.getObjectByName before or after the GLTF is loaded? You might be searching for it before anything has loaded, since the load happens asynchronously.
  • What do you get when you output the names of all children?
gltf.scene.traverse(function(child){
    console.log(child.name);
});

does "cloth" show up on any of those logs?

Hi Marquizzo,

I’m sure you are right! First of i’m not sure how the load order works or how to control it in a situation like this.

Every mesh names shows up fine in the traverse function - also “cloth”.

Is there a way i can see in which order things are loading? What’s the best way to get around issues like this?

console.log() and debugger are the jist of it :slight_smile:

With debugger you can pause the execution and then inspect the variables in the stack. These are all concepts a bit outside of three.js, so it might be worth looking for some more basic asynchronous examples with JS.

First of all, you should read up on asynchronous functions. Here’s a really good StackoOverflow thread with lots of explanations on how asynchronous resource requests work on JS and how to handle them.

It all boils down to this:

var object;

loader.load("chair.gltf", function(gltf){
	object = gltf;
	console.log(object); // Here you get the GLTF scene
});

console.log(object); // Here you get undefined

The log at the bottom is undefined because the resource hasn’t been retrieved yet, even though it’s written after the first log.

3 Likes

Thank for your help - it makes sense.
I have put getObjectByName() inside a function where it was going to end up anyway. For testing purposes i kept it in the root of the script and that was obviously a bad idea :roll_eyes:

Many thanks,
Henrik