如何在 Three.js 中向前移动对象?

Posted

技术标签:

【中文标题】如何在 Three.js 中向前移动对象?【英文标题】:How to move an object forward in Three.js? 【发布时间】:2012-06-23 01:27:57 【问题描述】:

Three.js 中有没有办法让对象向前移动?

也许我应该将 rotation.x,y,z 转换为向量,然后处理它。但我是初学者,我不知道该怎么做。

【问题讨论】:

【参考方案1】:

请使用 ThreeJS 的创建者 @mrdoob 的上述回答:

object.translateZ( delta );

===旧答案===

适用于旧版 ThreeJS 的教程: http://www.aerotwist.com/tutorials/getting-started-with-three-js/

// set position of YOUR_OBJECT
YOUR_OBJECT.position.x = 10;
YOUR_OBJECT.position.y = 50;
YOUR_OBJECT.position.z = 130;

更多选项:

var STEP = 10;
var newCubeMatrix = cube.matrix;        
newCubeMatrix.identity();
//newCubeMatrix.multiplySelf(THREE.Matrix4.rotationYMatrix(cube.rotation.y));
newCubeMatrix.multiplySelf(THREE.Matrix4.translationMatrix(cube.position.x, cube.position.y, cube.position.z + STEP));
cube.updateMatrix();

详情张贴在这里https://gamedev.stackexchange.com/questions/7490/translate-object-in-world-space-usings-its-local-rotation

【讨论】:

对不起,我还是不知道怎么办 :S 你有一些 sn-p 开始吗?你尝试过任何教程吗?你检查链接了吗?告诉我你的顾虑? 我的场景中有一个红色立方体,它围绕 x、y 和 z 轴旋转。我想使用对象的当前方向并使用指定的步长值将其向前移动。 这个答案太老了,需要删除。最新的 ThreeJS 都不正确 @Tyguy7 感谢您的检查,这是 6 年前的事了,哈哈。刚刚更新了答案,这样观众就不会偏离真相。【参考方案2】:

Object3D 有一些方便的方法。

object.translateZ( 10 );

【讨论】:

谢谢。以及如何移动相机? @eqiproo camera.translateZ( 10 ); @mrdoob 是否可以为threejs 制作更详细的文档? 不要吹毛求疵,但我不会考虑 translateZ() “移动”,而是更多的瞬移。用 3D 对象描述时的移动通常意味着可以看到对象朝着指定的方向或方式移动。这个方法确实改变了对象的位置:) @Ian Steffy I 如果您以一定的速度以小增量重复 translateZ,则该对象似乎正在移动。【参考方案3】:

另一种选择是使用 Vector3 的 set 方法/函数。

   position.set(x, y, z);

【讨论】:

值得反思的事情。developer.mozilla.org/en-US/docs/Web/javascript/Reference/… 这实际上是我正在寻找的答案,因为“前进”并不完全针对 Z 轴。 +1 翻译方法只是执行此操作的别名——为什么这个答案被否决了? 为了常识,你可能会将它投票回零。【参考方案4】:

相机是空间中的一个点。 “前进”是空间的另一个点。 因此您可以简单地使用第二个点的坐标,并使相机位置更接近“前”位置。

但是,您可能还需要左右转,这可能涉及极坐标。

为方便起见调整这些值:

var scene;
var camera;
var playerDirection = 0;//angles 0 - 2pi
var dVector;
var angularSpeed = 0.01;
var playerSpeed = 0.075;
var playerBackwardsSpeed = playerSpeed * 0.4;

这个函数将初始化场景:

function init()
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

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

    camera.position.z = 5;

    dVector = new THREE.Vector3( 0, 0, 0 ) ;
    camera.lookAt( dVector );

    animate();


当玩家按下向上键时,玩家的移动停止。

function key_up(event)
    playerIsMovingForward = 0;
    playerIsMovingBackwards = 0;
    playerIsRotatingLeft = 0;
    playerIsRotatingRight = 0;
    playerGoesUp = 0;
    playerGoesDown = 0;

当玩家移动时,我们更新位置:

function updatePlayer()
    if(playerIsRotatingLeft) // rotate left
        playerDirection -= angularSpeed;
    
    if(playerIsRotatingRight) // rotate right
        playerDirection += angularSpeed;
    
    if(playerIsRotatingRight || playerIsRotatingLeft)
        setPlayerDirection();

    
    if(playerIsMovingForward) // go forward
        moveForward(playerSpeed);

    
    if(playerIsMovingBackwards) // go backwards
        moveForward(-playerBackwardsSpeed);

    


我们假设转发您的意思是“使用 WASD 键”

function key_down(event)
    var W = 87;
    var S = 83;
    var A = 65;
    var D = 68;
    var minus = 189;
    var plus = 187;

    var k = event.keyCode;
    console.log(k);
    if(k == A) // rotate left
        playerIsRotatingLeft = 1;
    
    if(k == D) // rotate right
        playerIsRotatingRight = 1;
    
    if(k == W) // go forward
        playerIsMovingForward = 1;
    
    if(k == S) // go back 
        playerIsMovingBackwards = 1;
    



玩家的移动速度与他的浏览器一样快。 所以也许可以调整这段代码?

function animate() 
    requestAnimationFrame( animate );

    updatePlayer();



    renderer.render( scene, camera );

这是将相机移动到 dVector 对象位置的代码 并重新定位方向向量(dVector),使其始终从相机向前。

function moveForward(speed)
    var delta_x = speed * Math.cos(playerDirection);
    var delta_z = speed * Math.sin(playerDirection);
    var new_x = camera.position.x + delta_x;
    var new_z = camera.position.z + delta_z;
    camera.position.x = new_x;
    camera.position.z = new_z;

    var new_dx = dVector.x + delta_x;
    var new_dz = dVector.z + delta_z;
    dVector.x = new_dx;
    dVector.z = new_dz;
    camera.lookAt( dVector );    


向前移动通常涉及向左和向右转动,这里有一些代码可以做到这一点,它还使用极坐标来移动相对于相机的点(即“圆”的中心)给定的量度数(弧度)

function setPlayerDirection()
    //direction changed.
    var delta_x = playerSpeed * Math.cos(playerDirection);
    var delta_z = playerSpeed * Math.sin(playerDirection);

    var new_dx = camera.position.x + delta_x;
    var new_dz = camera.position.z + delta_z;
    dVector.x = new_dx;
    dVector.z = new_dz;
    console.log(dVector);
    camera.lookAt( dVector ); 


animate();

希望对你有帮助。

【讨论】:

这是一个更好的方法。这里要注意的一件事是在 setPlayerDirection(); 之后返回。调用 updatePlayer 方法将停止播放器。移除平滑动画的返回语句 我会试一试并得到结果。 @HiteshSahu,我去掉了return语句,现在动画流畅了很多,请问你是怎么得出这个结论的?

以上是关于如何在 Three.js 中向前移动对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何在three.js对象渲染中从中心向左更改轴(x,y,z)位置?

如何在旋转场景中查找对象的全局位置 THREE.JS

Three.js - 如何修复控件与最后一个摄像头位置相关的工作?

three.js如何让场景中模型跟随鼠标旋转呀

如何在 THREE.JS 中将对象放在相机前面?

如何通过鼠标移动事件获取相机位置并在three.js中转换为屏幕坐标? [关闭]