#javascript #for-loop #random #three.js #mesh
#язык JavaScript #для-петли #Случайный #three.js #меш
Вопрос:
Я пытаюсь создать функцию, которая рандомизирует размещение некоторых импортированных мной облаков, но проблема в том, что она генерирует количество облаков, но в одном и том же положении! Я произвел рандомизацию позиции, но когда код запускается, у меня примерно 10 облаков в одной и той же позиции. Что я могу сделать? это и есть код:
loader.load('/clouds/clouds1/scene.gltf', function (clouds1) { var clouds1array = [] function addClouds1(){ for (var i = 1; i lt; 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.структура сцены такова:
Я не знаю, почему у него такое количество детей, я пытался решить с помощью ответа, но это все равно не работает. 3-й дочерний элемент в конце содержит сетку, и я попытался использовать ее для работы, но в ней говорится, что я не могу использовать ее в scene.add()
функции
правка: Я решил проблему! Мне просто нужно было вывести цикл for за пределы функции загрузки
for(let i = 0; i lt; 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) })
Комментарии:
1. Обратите внимание, что то, как вы это настроили сейчас, three.js будет загружена одна модель GLTF на облако. Это будет быстро из-за кэширования браузера, но неэффективно для памяти. Некоторые методы , которые вы можете изучить, следующие: использование
Object3D.clone()
, повторное использование геометрии и материалов в нескольких сетках, аInstancedMesh
также .2. @TheJim01 Спасибо тебе! Я буду. Я новичок в программировании, поэтому я вроде как хочу исследовать
Ответ №1:
GLTFLoader
Результаты, которые у вас есть, clouds1
являются общим объектом, из которого вы правильно извлекаете clouds1.scene
. Однако clouds1.scene
это также единый Scene
объект. Если у вас есть 10 облаков в загруженной вами модели GLTF, то clouds1.scene
у вас будет 10 детей, и вам нужно будет пройти через них вот так:
loader.load('/clouds/clouds1/scene.gltf', function (clouds1) { var clouds1array = [] const clouds1Children = clouds1.scene.children for (var i = 1; i lt; 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) } })
Комментарии:
1. он возвращает эту ошибку:
main.js:200 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'position') at addClouds1 (main.js:200)
2. @SaverioScagnoli Я обновил свой ответ. Я удалил ненужную функцию и исправил опечатку. Если это все еще не работает, вам нужно будет отладить свой код, поместив точку останова в первую строку обратного вызова. Оттуда вы можете проверить
clouds1
, что в нем на самом деле содержится. Обновите свой вопрос любой дополнительной информацией, которую вы найдете о структуреscene
.3. отредактировано 🙂 спасибо за вашу любезную помощь.