You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js中满足条件语句后如何继续动画——实现网格墙体无限垂直上移动画

如何实现Three.js中墙体/网格的垂直无限循环移动效果?

Hey there! Let's break down why your current code isn't working and walk through the right ways to get that infinite vertical loop going.


问题出在哪?

你的动画逻辑有个关键漏洞:你用time(一个持续递增的全局时间值)直接计算墙体的绝对位置Wall.position.y = -15 + time / 200;。当墙体的y值超过5时,你把它设为0,但下一次执行animate时,time已经变得更大了,计算出来的-15 + time/200肯定还是远大于5,于是立刻又被重置为0——这就导致墙体卡在y=0的位置,看起来完全不动了。

另外还有个小细节:Three.js的旋转用弧度而非角度,你写的Wall.rotation.x = 180;会让网格旋转180弧度(相当于转了近29圈),这可能也不是你想要的效果,正确的180度旋转应该用Math.PI。


正确实现方式(两种方案)

方案1:复用现有网格(性能更优)

不需要删除重建,只需要在网格移出视野时,把它重置到视野下方的起始位置,让它继续向上移动。核心是用相对位移更新位置,而不是依赖全局time的绝对计算。

修改后的代码:

import * as THREE from 'three';

const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set(0, 0, 10);

// 创建墙体(这里用GridHelper,你也可以换成Mesh)
const wall = new THREE.GridHelper( 10, 5 );
wall.rotation.x = Math.PI; // 180度对应的弧度值
scene.add( wall );

// 移动速度(可根据需求调整)
const moveSpeed = 0.1;
// 墙体移出视野后的重置位置(设为视野下方足够远的地方)
const resetYPosition = -15;
// 墙体需要重置的阈值(比如摄像机视野上方5个单位)
const resetThreshold = 5;

function animate() {
    // 每次动画帧让墙体向上移动固定步长
    wall.position.y += moveSpeed;

    // 当墙体超出视野上方时,重置到下方起始位置
    if (wall.position.y > resetThreshold) {
        wall.position.y = resetYPosition;
    }

    renderer.render( scene, camera );
}

renderer.setAnimationLoop( animate );

方案2:动态创建/删除网格(适合多墙体流场景)

如果需要多个墙体连续循环出现,你可以维护一个墙体数组,在动画中检查每个墙体的位置,移出视野的就销毁,同时创建新的墙体补充到下方。

示例代码:

import * as THREE from 'three';

const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set(0, 0, 10);

// 墙体数组,用于跟踪所有活跃的墙体
const walls = [];
const moveSpeed = 0.1;
const resetThreshold = 5;
const spawnYPosition = -15;
const wallCount = 2; // 同时存在的墙体数量

// 创建单个墙体的函数
function spawnWall() {
    const wall = new THREE.GridHelper( 10, 5 );
    wall.rotation.x = Math.PI;
    wall.position.y = spawnYPosition;
    scene.add( wall );
    walls.push( wall );
}

// 初始化创建指定数量的墙体,错开位置避免重叠
for (let i = 0; i < wallCount; i++) {
    spawnWall();
    walls[i].position.y = spawnYPosition + (i * 10);
}

function animate() {
    // 倒序遍历数组,避免删除元素时索引混乱
    for (let i = walls.length - 1; i >= 0; i--) {
        const wall = walls[i];
        wall.position.y += moveSpeed;

        // 如果墙体超出视野上方,移除并销毁,同时补充新墙体
        if (wall.position.y > resetThreshold) {
            scene.remove( wall );
            walls.splice( i, 1 );
            spawnWall();
        }
    }

    renderer.render( scene, camera );
}

renderer.setAnimationLoop( animate );

内容的提问来源于stack exchange,提问作者Seelum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 09:59:06