Three.js FirstPersonControl 什么都不做

Three.js FirstPersonControl does nothing

我实现了以下简短脚本:

var screenWidth = window.innerWidth;
var screenHeight = window.innerHeight;

var camera;
var controls;
var scene;
var renderer;
var container;

var controls;
var keyboard = new THREEx.KeyboardState();
var clock = new THREE.Clock();

var light;
var floor;
var movingGeometry;

function setup() 
{
    var viewAngle = 45;
    var aspect = screenWidth / screenHeight;
    var near = 0.1;
    var far = 20000;

    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera(viewAngle, aspect, near, far);
    camera.position.set(0,150,400);
    camera.lookAt(scene.position);  

    scene.add(camera);

    controls = new THREE.FirstPersonControls(camera);
    controls.movementSpeed = 70;
    controls.lookSpeed = 0.05;
    controls.noFly = true;
    controls.lookVertical = false;

    renderer = new THREE.WebGLRenderer();
    renderer.setSize(screenWidth, screenHeight);

    container = document.getElementById('canvas');
    container.appendChild( renderer.domElement );

    createLight();
    createFloor();
    createSkyBox();
    createGeometry();

    animate();
}

function createLight()
{
    light = new THREE.PointLight(0xffffff);
    light.position.set(0,250,0);

    scene.add(light);
}

function createFloor()
{
    var floorMaterial = new THREE.MeshLambertMaterial({color: 0x00FF00});

    floor = new THREE.Mesh(new THREE.BoxGeometry(1000, 1000, 3, 1, 1, 1), floorMaterial);
    floor.position.y = -0.5;
    floor.rotation.x = Math.PI / 2;

    scene.add(floor);   
}

function createSkyBox()
{
    var skyBoxGeometry = new THREE.BoxGeometry(10000, 10000, 10000);
    var skyBoxMaterial = new THREE.MeshBasicMaterial({color: 0x0000FF, side: THREE.BackSide});
    var skyBox = new THREE.Mesh(skyBoxGeometry, skyBoxMaterial);

    scene.add(skyBox);
}

function createGeometry()
{
    var material = new THREE.MeshNormalMaterial();
    var geometry = new THREE.BoxGeometry(50, 50, 50);

    movingGeometry = new THREE.Mesh(geometry, material);
    movingGeometry.position.set(0, 28, 0);

    scene.add(movingGeometry);  
}

function animate() 
{
    requestAnimationFrame(animate);
    render();       
    update();
}

function render() 
{
    renderer.render(scene, camera);

    controls.update();
}

function update()
{
    var delta = clock.getDelta(); // seconds.
    var moveDistance = 200 * delta; // 200 pixels per second
    var rotateAngle = Math.PI / 2 * delta;   // pi/2 radians (90 degrees) per second

    if (keyboard.pressed("W"))
    {
        movingGeometry.translateZ(-moveDistance);
    }

    if (keyboard.pressed("S"))
    {
        movingGeometry.translateZ(moveDistance);
    }

    if (keyboard.pressed("A"))
    {
        movingGeometry.rotateOnAxis(new THREE.Vector3(0,1,0), rotateAngle);
    }

    if (keyboard.pressed("D"))
    {
        movingGeometry.rotateOnAxis(new THREE.Vector3(0,1,0), -rotateAngle);
    }

    var relativeCameraOffset = new THREE.Vector3(0,50,200);
    var cameraOffset = relativeCameraOffset.applyMatrix4(movingGeometry.matrixWorld);

    camera.position.x = cameraOffset.x;
    camera.position.y = cameraOffset.y;
    camera.position.z = cameraOffset.z;
    camera.lookAt(movingGeometry.position);
}

我想实现一个贴在物体上的相机。如果我使用 'w'、'a'、's'、'd',我可以移动物体并且相机跟随。但我也希望能够通过左键单击 + 拖动来旋转相机(在其位置),我还想通过右键单击 + 拖动来旋转对象(典型的第一人称行为)。

所以我将 Three.js 中的 FirstPersonControls 添加到相机中。结果:当我使用鼠标或点击或任何东西时没有任何反应,我也不知道我需要做什么来通过右键单击和拖动来旋转对象。

有人可以帮忙吗?

乍一看,您似乎无法覆盖相机 lookAt 因为在 update() 你这样做: camera.lookAt(movingGeometry.position); 项目清单 您的执行顺序是:

  • 动画
    • (你的)渲染
    • (threejs) 渲染
    • (threejs) 控件更新
  • (你的)更新

并且在您的更新中,您覆盖了从第一人称控件看的相机。