相信您所需要的概念是相机架设置。在这种方法中,您首先建立一个
Object3D
作为“颈部”,然后将相机附加到该对象上并进行所需的旋转。然后,您可以应用旋转到
Object3D
以查看周围的情况,而不会出现晃动效果。进一步地,您可以将该“颈部”对象嵌套在另一个
Object3D
中,以充当“身体”,并对该对象应用平移以在场景中移动。通过这种方式,您拥有了一个基本的相机控制器架构。我修改了您的fiddle如下:
编辑:实施更改以更好地适应@ostapische使用情况。这是fiddle的链接:link
function degInRad(deg) {
return deg * Math.PI / 180;
}
function render() {
requestAnimationFrame(render);
if (leftPressed) {
neck.rotation.y += degInRad(1);
} else if (rightPressed) {
neck.rotation.y -= degInRad(1);
}
if (upPressed) {
camera.rotation.x += degInRad(1);
} else if (downPressed) {
camera.rotation.x -= degInRad(1);
}
renderer.render(scene, camera);
}
var scene, camera, renderer, grass, neck;
var leftPressed = false;
var rightPressed = false;
var upPressed = false;
var downPressed = false;
window.onload = function() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
cameraHolder = new THREE.Object3D();
cameraHolder.add( camera );
renderer = new THREE.WebGLRenderer();
renderer.rendererSize = {width: window.innerWidth, height: window.innerHeight, quality: 100, maxQuality: 400, minQuality: 20};
renderer.setSize( renderer.rendererSize.width, renderer.rendererSize.height );
document.body.appendChild( renderer.domElement );
var texture, material, geometry, element;
material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
material.side = THREE.DoubleSide;
geometry = new THREE.PlaneGeometry(24, 24);
grass = new THREE.Mesh( geometry, material );
grass.name = "grass";
scene.add( grass );
neck = new THREE.Object3D();
neck.rotateOnAxis(new THREE.Vector3(1, 0, 0), degInRad(90));
neck.up = new THREE.Vector3(0, 0, 1);
neck.position.z = 1;
neck.position.y = -5;
neck.add(camera);
scene.add(neck);
KeyboardJS.on('left', function() { leftPressed = true; }, function() { leftPressed = false; });
KeyboardJS.on('right', function() { rightPressed = true; }, function() { rightPressed = false; });
KeyboardJS.on('up', function() { upPressed = true; }, function() { upPressed = false; });
KeyboardJS.on('down', function() { downPressed = true; }, function() { downPressed = false; });
render();
}
我本来想提到PointLockControl或FirstPersonControl,但我看到WestLangley已经很好地建议了。无论如何祝你好运。
THREE.PointerLockControls
,而不是其他方法。请参见 http://threejs.org/examples/misc_controls_pointerlock.html。请注意,在指针锁源代码中,如何将相机添加为两个对象的子级/孙级,以实现所需效果。 - WestLangleycamera
只在controls = new THREE.PointerLockControls( camera ); scene.add( controls.getObject() );
中使用 - 是PointerLockControls
内部对象添加到场景中,而不是camera
本身,并且在onWindowResize
函数中 - 只是应用了新的属性,在renderer.render( scene, camera );
中 - 这里使用的是原始的camera
变量。至于您所说的“子/孙”是什么意思?我真的不理解,您能解释一下吗?提前致谢。 - ostapischePointerLockControls
如何根据您的需求旋转相机,但它使用鼠标而不是键盘。为了获得这种效果,它使用pitchObject
和yawObject
技术。请参见源代码。这就是我所说的“子/孙”意思。您不必使用PointerLockControls
;您可以自己实现类似的逻辑。 - WestLangleypitchObject.rotation.x = Math.max( - PI_2, Math.min( PI_2, pitchObject.rotation.x ) );
的结构。当我取消注释我的代码中的这些行时,垂直移动效果变差。你能解释一下吗?谢谢。 - ostapische