【问题标题】:I can't get the Perspective Camera to follow the player. Camera is stuck to the World origin我无法让透视相机跟随玩家。相机卡在世界原点
【发布时间】:2021-08-30 10:17:46
【问题描述】:

我是 THREE.js 的新手。

出于学习 JavaScript 和 THREE.js 的目的,我制作了这个(某种)小游戏,玩家可以在其中探索太空和不同的太空物体(正在进行中)。

无论如何,我的问题是当场景和对象被渲染时,当你开始移动你的长方体时,相机并没有随之移动(实际上它并没有从world origin) 只在原地旋转并看着玩家的对象

这是代码:

import './style.css'
import * as THREE from 'three'; 
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

// Scene object
const scene = new THREE.Scene();
const clock = new THREE.Clock();

var cameraObject, keys;
var temp = new THREE.Vector3;
var dir = new THREE.Vector3;
var a = new THREE.Vector3;
var b = new THREE.Vector3;
var distance = 0.3;
var velocity = 0.0;
var speed = 0.0;

// Camera object
const perspectiveCamera = new THREE.PerspectiveCamera( 25, window.innerWidth / window.innerHeight, 50, 1e7 )
perspectiveCamera.position.setZ(80);
cameraObject = new THREE.Object3D;
cameraObject.add(perspectiveCamera);
// perspectiveCamera.lookAt(scene.position)

// Renderer object
const renderer = new THREE.WebGLRenderer({
});
document.body.appendChild( renderer.domElement );

// Renderer
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.render( scene, perspectiveCamera )

// Light
// PointLight
const pointLight = new THREE.PointLight(0xffffff)
pointLight.position.set(20,20,20)
// AmbientLight
const ambientLight = new THREE.AmbientLight(0xffffff)
scene.add(pointLight, ambientLight)

// Helper classes
const lightHelper = new THREE.PointLightHelper(pointLight);
const axesHelper = new THREE.AxesHelper(5);
scene.add(lightHelper, axesHelper)

// Controls
const controls = new OrbitControls(perspectiveCamera, renderer.domElement);
controls.movementSpeed = 1000;
controls.domElement = renderer.domElement;
controls.rollSpeed = Math.PI / 24;
controls.autoForward = false;
controls.dragToLook = false;

let cube = new THREE.Group();
const cubeGeometry = new THREE.BoxGeometry(3,10,3)
const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0x238423 })
const cube1 = new THREE.Mesh( cubeGeometry, cubeMaterial );
cube.add(cube1)
scene.add(cube)

// Objects
// Stars
function addStar() {
  const geometry = new THREE.SphereGeometry(0.25, 24, 24);
  const material = new THREE.MeshStandardMaterial( { color: 0xffffff })
  const star = new THREE.Mesh( geometry, material );
  const [x, y, z] = Array(3).fill().map(() => THREE.MathUtils.randFloatSpread( 500 ));
  star.position.set(x,y,z);
  scene.add(star)
}
Array(1500).fill().forEach(addStar)

let keyState = {};
keys = {
  a: false,
  s: false,
  d: false,
  w: false,
  q: false,
  e: false,
  space: false,
  shiftleft: false,
};

document.addEventListener("keydown", function(e) {
  console.log(e.code);
  const key = e.code.replace('Key', '').toLowerCase();
    if ( keys[ key ] !== undefined )
      keys[ key ] = true;
});

document.body.addEventListener( 'keyup', function(e) {
    
  const key = e.code.replace('Key', '').toLowerCase();
  if ( keys[ key ] !== undefined )
    keys[ key ] = false;
});

// Animate objects
function animate() {
  const delta = clock.getDelta();

  requestAnimationFrame( animate );
  speed = 0.0;

  if ( keys.w )
    cube.rotateX(-0.03);

  if ( keys.s )
  cube.rotateX(0.03);

  if ( keys.a )
  cube.rotateZ(0.03);

  if ( keys.d )
  cube.rotateZ(-0.03);

  if ( keys.q )
  cube.rotateY(-0.06);

  if ( keys.e )
  cube.rotateY(0.06);

  if ( keys.space )
    speed = 0.9;

  velocity += ( speed - velocity ) * .3;
  cube.translateY( velocity );

  if ( keys.shiftleft )
    speed = 0.9*5;
    velocity += ( speed - velocity ) * .3; 
    cube.translateY( velocity );

  perspectiveCamera.lookAt( cube.position ); 
  controls.update(delta);
  renderer.render( scene, perspectiveCamera );
}
animate();

我实际上是在尝试制作某种第三人称相机。为了使相机跟随这个小长方体并随着物体在屏幕上旋转而旋转。

第一次尝试:

const idealOffset = new THREE.Vector3(0, 0, -80);
function animate(){
  ...
  perspectiveCamera.position.set(0, 0, -80);
  perspectiveCamera.applyQuaternion(cube.rotation);
  perspectiveCamera.position.add(cube.position);
  perspectiveCamera.lookAt(idealOffset);
  ...
}

相机随着立方体移动,但几秒钟后转回来查看世界原点。

第二次尝试:

// Animate objects
  requestAnimationFrame( function animate(milliseconds) {
  const delta = clock.getDelta();
  let moveDistance = 10*delta;
  let rotateAngle = Math.PI/2*delta;
  requestAnimationFrame( animate );
  speed = 0.0;

  if ( keys.w ){
    cube.rotateX(-0.03);
  }
  if ( keys.s ){
    cube.rotateX(0.03);
  }

  let rotation_matrix = new THREE.Matrix4().identity();
  if ( keys.a ){
    cube.rotateZ(rotateAngle);
  }
  if ( keys.d ){
    cube.rotateZ(-rotateAngle);
  }
  if ( keys.q ){
    cube.rotateY(-rotateAngle);
  }
  if ( keys.e ){
    cube.rotateY(rotateAngle);
  }
  if ( keys.space ){
    speed = 0.9;
    velocity += ( speed - velocity ) * .3;
    cube.translateY( velocity );
  }
  if ( keys.shiftleft ){
    speed = 0.9*5;
    velocity += ( speed - velocity ) * .3; 
    cube.translateY( velocity );
  }
  
  var relativeCameraOffset = new THREE.Vector3(0,-80,0);
  var cameraOffset = relativeCameraOffset.applyMatrix4(cube.matrixWorld);
  perspectiveCamera.position.x = cameraOffset.x;
  perspectiveCamera.position.y = cameraOffset.y;
  perspectiveCamera.position.z = cameraOffset.z;
  perspectiveCamera.lookAt(cube.position);
  renderer.render( scene, perspectiveCamera );
});

相机确实跟随我的立方体,但是当我在 x 轴上将它旋转 180 度时,它会倒置,它固定在播放器上,移动不顺畅,它直接看着播放器(立方体的背面) .

这激发了我阅读更多关于 3d 空间中的旋转/平移、欧拉角、四元数、万向节锁的信息。我只是不太确定如何将这些可怕的四元数应用到我的项目中......

任何帮助,参考,任何将不胜感激。

提前致谢。

【问题讨论】:

    标签: javascript three.js


    【解决方案1】:

    如果您使用 OrbitControls,只需将 .target 属性更新为您希望它关注的对象的位置。当立方体移动时,相机将随之移动。见here for more on the docs

    orbitControls.target = cube.position;
    

    我不确定你为什么这样做:cameraObject.add(perspectiveCamera);。如果您不对cameraObject 进行任何更改,这不会做任何事情。

    【讨论】:

    • 感谢您的快速回复。这并没有给我想要的结果。相机仍然粘在中心。至于“cameraObject”……嗯,我正在尝试透视相机和四元数……我忘了在发布代码之前删除这两行。我编辑了我的问题,向您展示了我的尝试。
    猜你喜欢
    • 2015-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    • 2023-03-15
    • 1970-01-01
    相关资源
    最近更新 更多