首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JavaScript函数只适用于最后一个元素(Three.js)

JavaScript函数只适用于最后一个元素(Three.js)
EN

Stack Overflow用户
提问于 2018-11-12 10:13:13
回答 2查看 104关注 0票数 0

我试图用Three.js创建一个栅栏生成器函数,但是我的函数只返回最后一个栅栏,我不知道为什么.

代码语言:javascript
运行
复制
function generateFence(nb){
  var i;
  var value = -5;
  var loadingManager;
  for(i = 0; i < nb ; i++) {
    var arrayFence = [];
    loadingManager = new THREE.LoadingManager( function () {
      scene.add( arrayFence[i] );
    });

    var loader = new THREE.ColladaLoader( loadingManager );
    loader.load( 'fence/model.dae', function ( collada ) {
      arrayFence[i] = collada.scene;
      arrayFence[i].position.x = value;
      arrayFence[i].position.z = -5;
    });
    value = value + 3;      
  }
}

generateFence(3);
EN

回答 2

Stack Overflow用户

发布于 2018-11-12 12:12:46

您的代码有几个问题,但我认为问题是旧的async问题。加载器是异步的,这意味着代码实际上是稍后执行的,但是您的代码假设它是同步的。正因为如此,当所有的循环都完成时,所有的栅栏都在读取value,并且通常只有在它们全部完成之后才会触发。这里有一种方法来重构您的函数,以便它的行为与预期的一样:

代码语言:javascript
运行
复制
function generateFence(nb){
  
  // First we will load the model once, as we want to reuse it.
  // Lets wrap it in a promise so its easier to use later.
  
  const value = -5;
  const fences = new THREE.Group;
  const model = new Promise(function( resolve ){
  
    THREE.ColladaLoader( loadingManager ).load( 'fence/model.dae', resolve );
    
  });
  
  // Use a `let` declaration to ensure that each loop remembers 
  // what the value for i was wen it ran, even if you perform an async operation.
  
  for( let i = 0; i < nb; i++ ){
    
    // The bit after `then` happens asynchronously, waiting until the model is loaded
    // Because of this, we need to ensure we don't rely too much on values defined in the synchronous loop.
    
    model.then(model => {
      
      // Let's clone it so we create copies of the one model
      
      const fence = model.scene.clone();
      
      // Calculate the x position based on value and the current state of i.
      
      fence.position.set( value + i * 3, 0, -5 );
      fences.add( fence );
      
    });
    
  }
  
  return fences;
  
}

// Returns a THREE.Group. When the fences are loaded, they will 
// be added to the group, which is already an invisible part of the scene.
scene.add( generateFence(3) );

问题可能是,所有的栅栏都是完全相同的,而且由于异步操作,所有的计算结果都在同一个地方,看起来好像只有一个栅栏。

票数 0
EN

Stack Overflow用户

发布于 2018-11-12 18:04:43

有几个问题。

  • 代码正在为每个栅栏创建一个加载管理器。你最多只需要一个
  • 代码加载相同的栅栏5次。它可能应该加载一次并复制它。
  • 除了等待场景,代码没有对加载管理器做任何事情,但是它已经从ColladLoader获得了场景,所以它根本不需要加载管理器。加载管理器用于帮助等待多个要加载的东西,但它只加载一件东西
  • yThe代码在回调中使用value,但只有一个值实例。所有的回调都是一样的,所以所有的围栏都在同一个地方。

这应该能行。

代码语言:javascript
运行
复制
function generateFence(nb){
  const loader = new THREE.ColladaLoader();
  loader.load( 'fence/model.dae', function ( collada ) {
    const copy = collada.scene.clone();
    scene.add(copy);
    let value = -5;
    for(var i = 0; i < nb ; i++) {
      copy.position.x = value;
      copy.position.z = -5;
      value = value + 3;
    }
  });
}

generateFence(3);

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53259962

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档