【问题标题】:random plancement issue three.js with for-loop带有for循环的随机平面问题three.js
【发布时间】:2022-01-13 22:51:37
【问题描述】:

我正在尝试制作一个随机放置我导入的一些云的功能,但问题是,它生成了云的数量,但位置相同!我随机化了位置,但是当代码运行时,我在同一位置有 10 朵云。我能做些什么?这是代码:

loader.load('/clouds/clouds1/scene.gltf', function (clouds1) {


  var clouds1array = []
  function addClouds1(){

    for (var i = 1; i < 10; i++) {
      const clouds1Mesh = clouds1.scene
      const clouds1Position = clouds1Mesh.position
      clouds1Position.x = Math.random() * 10
      clouds1Position.y = Math.random() * 10
      clouds1Position.z = (Math.random() - 0.5 ) * 300

      clouds1Mesh.scale.setX(0.05)
      clouds1Mesh.scale.setY(0.05)
      clouds1Mesh.scale.setZ(0.05)
      
  
      scene.add(clouds1Mesh)
      clouds1array.push(clouds1Mesh)
  
      
    }
    
  }

  
  addClouds1()
  
})

编辑:clouds1.scene 结构是这样的:

我不知道为什么它有这么多的孩子,我试图用答案来解决,但它仍然不起作用。最后的第三个孩子包含网格,我尝试使用它来工作,但它说我不能在 scene.add() 函数中使用它

编辑:我解决了这个问题!我只需要将 for 循环放在加载函数之外

 for(let i = 0; i < 30; i+= 3)

loader.load('/clouds/clouds1/scene.gltf', function (clouds1) {

 
 const cloud = clouds1.scene

 const child1 = clouds1.scene.children[0].children[0].children[0].children[2].children[0]


 child1.material = new THREE.MeshStandardMaterial({ emissive: 'white', emissiveIntensity: 0.5})

 cloud.scale.set(0.05, 0.05, 0.05)

 cloud.position.x = (Math.random() - 0.5) * 500
 cloud.position.y = (Math.random() + ((Math.random() + 20 ) + 70))
 cloud.position.z = (Math.random() - 1) * 500

 cloud.rotation.x = Math.random()
 cloud.rotation.y = Math.random() 
 cloud.rotation.z = Math.random() 



 scene.add(cloud)


})

【问题讨论】:

  • 请注意,按照您现在的设置方式,three.js 将为每个云加载一个 GLTF 模型。由于浏览器缓存,这将很快,但内存效率低。您可以研究的一些技术包括:使用Object3D.clone()、在多个网格中重复使用几何体和材质,以及InstancedMesh
  • @TheJim01 谢谢!我将会。我是编程新手,所以我有点想探索

标签: javascript for-loop random three.js mesh


【解决方案1】:

GLTFLoader 结果,clouds1 是一个通用对象,您可以从中正确提取 clouds1.scene。但是,clouds1.scene 也是单个 Scene 对象。如果您在加载的 GLTF 模型中有 10 个云,那么 clouds1.scene 将有 10 个孩子,您需要像这样循环它们:

loader.load('/clouds/clouds1/scene.gltf', function (clouds1) {

  var clouds1array = []

  const clouds1Children = clouds1.scene.children

  for (var i = 1; i < 10; i++) {

    const clouds1Mesh = clouds1Children[i]
    const clouds1Position = clouds1Mesh.position
    clouds1Position.x = Math.random() * 10
    clouds1Position.y = Math.random() * 10
    clouds1Position.z = (Math.random() - 0.5 ) * 300

    clouds1Mesh.scale.setX(0.05)
    clouds1Mesh.scale.setY(0.05)
    clouds1Mesh.scale.setZ(0.05)
      
    scene.add(clouds1Mesh)
    clouds1array.push(clouds1Mesh)
  
  }
  
})

【讨论】:

  • 返回此错误:main.js:200 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'position') at addClouds1 (main.js:200)
  • @SaverioScagnoli 我更新了我的答案。我删除了不必要的功能,并更正了一个错字。如果它仍然不起作用,您将需要通过在回调的第一行放置一个断点来调试您的代码。从那里,您可以检查 clouds1 以查看它真正包含的内容。使用您找到的有关 scene 结构的任何其他信息更新您的问题。
  • 已编辑 :) 感谢您的帮助。
猜你喜欢
  • 2018-01-20
  • 2017-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-01
  • 1970-01-01
相关资源
最近更新 更多