在 ThreeJS 中访问 children of children

Accessing children of children in ThreeJS

我一直在学习 ThreeJs,天哪,我在尝试调用我的文件时卡住了吗?

让我先解释一下我想做什么! 我有 3 个模型要显示在一个页面上,当人们滚动时应该显示不同的表情符号,比如小部分,经典的 webapge 方式。

我将这些模型从 blender 导入到一个 gltb 文件中以提高性能,理论上,节省时间,object 中的两个是组,另一个是网格。导入中没有其他内容。

然而,在使用 gltf 加载程序加载我的模型后,我无法找到一种方法来访问它们以将它们容纳在我希望它们所在的位置和旋转中。请帮忙。

我加载了我的场景:

gltfLoader.load(
'EMOJIS.gltf',
(gltf) =>
{
    gltf.scene.scale.set(0.25, 0.25, 0.25)
    gltf.scene.position.set(0, 0, 0)

    mixer = new THREE.AnimationMixer(gltf.scene)
    scene.add(gltf.scene)
}

之后我检查了我的日志以获取 objects

console.log(scene)
console.log(scene.children)
console.log(scene.children[3])

第一条和第二条日志如下:

我意识到我应该到达场景 children 的 children 以获得我的 3 个表情符号:heart、peach、heartEyes。 例如,我想我可以直接调用 scene.children[3].children[0] 。并呼唤心脏 object 表情符号 但我不能打电话给他们?我试过很多方法,但总是显示未定义。

console.log(scene.children) 显示从 0 到 3 的数组,在 [3] 槽中我可以看到我想要的表情符号元素,但是调用 console.log(scene.children[3]) 显示未定义,如何访问我想要的组?

通话中

var heart = scene.getObjectByName( "heart", true );

或通过他们的 ID(16、15 和 23)调用也显示未定义。

非常感谢所有帮助。

编辑:

在我的 consolde 调试上放置 time-stamps 后,我意识到它在调用我的 object 表情符号引用后调用了 gltf 加载程序,但我不确定为什么会发生这种情况或如何以正确的顺序设置它们? gltf 加载程序位于脚本的顶部,随后调用下面的各行,它不应该 运行 正确吗?是因为加载模型需要时间吗?我该如何解决?

代码:

    gltfLoader.load(
    'EMOJIS.gltf',
    (gltf) => {
        gltf.scene.scale.set(0.5, 0.5, 0.5)
        gltf.scene.position.set(0, 0, 0)
        scene.add(gltf.scene)

        // Animation
        mixer = new THREE.AnimationMixer(gltf.scene)

        gui.add(gltf.scene.position, 'y').min(-3).max(3).step(0.01).name('position y')
        gui.add(gltf.scene.position, 'x').min(-3).max(3).step(0.01).name('position x')
        gui.add(gltf.scene.position, 'z').min(-3).max(3).step(0.01).name('position z')

        //gltf.scene.children[2].material.roughness = 1

        gltf.scene.children[0].position.x = 2
        gltf.scene.children[1].position.x = - 2
        gltf.scene.children[2].position.x = 2

        gltf.scene.children[0].position.y = - objectsDistance * 0
        gltf.scene.children[1].y = - objectsDistance * 1
        gltf.scene.children[2].y = - objectsDistance * 2

        console.log("Emoji Inside Loader, Line 99")
        console.log(gltf.scene.children[0])

        /*
        var heart = gltf.scene.getObjectByName("heart", true);
        var heartEyes = gltf.scene.getObjectByName("heartEyes", true);
        var peach = gltf.scene.getObjectByName("peach", true); */

        // loop through all children and create a property 
        // for every child based on it's name
        gltf.scene.children.forEach((item) => {
            emoji[item.name] = item;
        })
        // then you can access every child through 
        // the named property of the shirt object

        console.log("emoji array")
        console.log(emoji.peach)
        console.log(emoji.heart)
        console.log(emoji.heart.rotation)
        console.log(emoji.heartEyes)
        loaded = true;


      }
    )


    console.log("Main scene")
    console.log(scene)
    console.log(scene.children)
    console.log(scene.children[6])


    console.log("Emoji outside of the loader, line 133?")
    console.log(emoji)
    console.log(emoji[heart])
    console.log(emoji[0])
    console.log(emoji.name[heart])
    console.log("--- --- ---")

调试:

我在访问衬衫模型的子项时遇到了一些问题,因此我创建了一个对象,其中包含子项的名称(在 Blender 中命名)作为属性以便于访问。也许这会对你有所帮助:

     // prepare shirt (js) object
     let shirt = {};

        ... after importing the gltf ...

      scene.add(gltf.scene);

      // loop through all children and create a property 
      // for every child based on it's name
      gltf.scene.children.forEach((item) => {
        shirt[item.name] = item;
      });

      // then you can access every child through 
      // the named property of the shirt object

      shirt.Back.children[0].material = shirtMat;

      shirt.Sleeves.children[0].material = shirtMat;

      shirt.Front.children[0].material = shirtMat;
      shirt.Front.children[1].material = buttonMat;

      shirt.CollarClassic.children[0].material = shirtMat;

      shirt.CollarCut.children[0].material = shirtMat;
      shirt.CollarCut.visible = false;

      shirt.CollarButton.children[0].material = shirtMat;
      shirt.CollarButton.children[1].material = buttonMat;
      shirt.CollarButton.visible = false;

        ... etc