在update中使用 nodePool 發生異常

  • Creator 版本:2.0.9

  • 目标平台: Web

  • 详细报错信息,包含调用堆栈:
    沒有error

  • 重现方式:建立一個 子彈容器 prefab ,此 子彈容器 prefab 的子物件包含 多個 子彈,子彈身上有腳本在 update中做往前走的計算,與判斷超過螢幕邊際就 呼叫本身的子彈容器腳本方法,檢查是否所有子彈都擊中或超過邊際時,回收此子彈容器。
    當多個子彈容器存在時,前一個子彈容器被回收後,會影響到下一個子彈容器中某個子彈的update多跑了一次(不確定),導致此子彈多往前走一步,例如兩顆平行射出的子彈,另一顆多走一步,就沒有平行飛行了。

目前解決方法是在 lateUpdate 才做回收的動作(NodePool.Put),就不會有上述情形發生。

想問有沒有人有遇到類似情況,一起討論原因,謝謝大家

  • 出现概率:100%

繁体不是中国的?你有脑子么?

你每次回收的时候有没有把原来的那个子弹给还原初始化


我有還原他們的位置,印出log顯示開始位置是一樣的,兩顆子彈有對齊

事後又錄影看了幾次,發現一開始發射都是有對齊的,兩顆子彈還在平行飛的時候,有時候其中一個會突然往前多飛一格

推測可能是剛好此時有別的子彈被回收(使用了pool.put)

之後發現一個解決方法是不要在update使用pool.put(做回收的事),在lateUpdate做就正常了

原理還不清楚

你是父节点用getchildren
然后for循环来操作子弹移动的吧
当你回收一个以后,children的length会发生变化
你可以试试在这个for循环里不回收,只是把他加入到一个数组里,在这个for循环外面,把数组里的node回收掉

比如这样:

    let bullets=this.node.getChildren();
    let putNods=[];
    for(let i = 0; i < bullets.length; i++) {
        bullets[i].getComponent('bullet').move(dt);
        if(this.isOutScreen(bullets[i].position)){
            putNods.push(bullets[i]);
        }
    }
    for(let i=0;i<putNods.length;i++){
        this.putBullet(putNods[i]);
    }