当角色移动时,聚焦视角在Three JS中不起作用



我正在探索三个JS。我是3D编程的初学者。我正在遵循这本书中的教程,https://canvas.projekti.info/ebooks/3D%20Game%20Programming%20for%20Kids.pdf。基本上,这款游戏就是控制角色在树上移动。我现在正在做的是,当角色在3D空间中移动时,我试图让相机始终聚焦在角色的背部。

我已经为此创建了一个标记。标记被附加到角色上。然后摄像头对准了标记。但是当我移动角色时,摄像机不会随着摄像机移动。

这是我的代码:

var scene = new THREE.Scene();
var aspectRatio = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspectRatio, 1, 10000);
camera.position.z = 500;
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// **************** start coding here *********************
var marker = new THREE.Object3D();
scene.add(marker);
var cover = new THREE.MeshNormalMaterial();
var body = new THREE.SphereGeometry(100);
var avatar = new THREE.Mesh(body, cover);
marker.add(avatar);
var hand = new THREE.SphereGeometry(50);
var rightHand = new THREE.Mesh(hand, cover);
rightHand.position.set(-150, 0, 0);
avatar.add(rightHand);
var leftHand = new THREE.Mesh(hand, cover);
leftHand.position.set(150, 0, 0);
avatar.add(leftHand);
var feet = new THREE.SphereGeometry(50);
rightFeet = new THREE.Mesh(feet, cover);
rightFeet.position.set(-75, -125, 0);
avatar.add(rightFeet);
leftFeet = new THREE.Mesh(feet, cover);
leftFeet.position.set(75, -125, 0);
avatar.add(leftFeet);
marker.add(camera);// Focus the camera on the marker.
function makeTreeAt(x, z) {
var trunk = new THREE.Mesh(
new THREE.CylinderGeometry(50, 50, 200),
new THREE.MeshBasicMaterial({ color: 0xA0522D })
)
var top = new THREE.Mesh(
new THREE.SphereGeometry(150),
new THREE.MeshBasicMaterial({ color: 0x228B22 })
)
top.position.y = 175;
trunk.add(top);
trunk.position.set(x, -75, z);
scene.add(trunk);
}
makeTreeAt(500, 0);
makeTreeAt(-500, 0);
makeTreeAt(750, -1000);
makeTreeAt(-750, -1000);
var isCartWheeling = false;
var isFlipping = false;
function animate() {
requestAnimationFrame(animate);
if (isCartWheeling) {
avatar.rotation.z = avatar.rotation.z + 0.05;
}
if (isFlipping) {
avatar.rotation.x = avatar.rotation.x + 0.05;
}
renderer.render(scene, camera);
}
document.addEventListener('keydown', function (event) {
var code = event.keyCode;
if (code ==  37) avatar.position.x = avatar.position.x - 5; // move left
if (code == 38) avatar.position.z = avatar.position.z - 5; // up - move forward
if (code == 39) avatar.position.x = avatar.position.x + 5; // move right
if (code == 40) avatar.position.z = avatar.position.z + 5; // down - move backward
if (code == 67) isCartWheeling = ! isCartWheeling; // C
if (code == 70) isFlipping = ! isFlipping; // F
});
animate();
body {
margin: 0px;
}
canvas {
width: 100%;
height: 100%;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>First 3D avatar game</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r125/three.min.js"></script>
</head>
<body>
</body>
</html>

我的代码有什么问题,我该如何修复它?

你必须小心你的对象嵌套。这就是现在的结果

Marker
├── Avatar
└── Camera

你有Avatar和Camera作为Marker的子元素,但是你只是在更新Avatar的位置,所以Marker保持不变,而Camera不会跟随。

不更新Avatar的位置,如果你想让摄像机跟随,你就必须更新Marker的位置,这样它的两个子元素就会同步移动,就像下面的演示一样:

var scene = new THREE.Scene();
var aspectRatio = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspectRatio, 1, 10000);
camera.position.z = 500;
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// **************** start coding here *********************
var marker = new THREE.Object3D();
scene.add(marker);
var cover = new THREE.MeshNormalMaterial();
var body = new THREE.SphereGeometry(100);
var avatar = new THREE.Mesh(body, cover);
marker.add(avatar);
var hand = new THREE.SphereGeometry(50);
var rightHand = new THREE.Mesh(hand, cover);
rightHand.position.set(-150, 0, 0);
avatar.add(rightHand);
var leftHand = new THREE.Mesh(hand, cover);
leftHand.position.set(150, 0, 0);
avatar.add(leftHand);
var feet = new THREE.SphereGeometry(50);
rightFeet = new THREE.Mesh(feet, cover);
rightFeet.position.set(-75, -125, 0);
avatar.add(rightFeet);
leftFeet = new THREE.Mesh(feet, cover);
leftFeet.position.set(75, -125, 0);
avatar.add(leftFeet);
marker.add(camera);// Focus the camera on the marker.
function makeTreeAt(x, z) {
var trunk = new THREE.Mesh(
new THREE.CylinderGeometry(50, 50, 200),
new THREE.MeshBasicMaterial({ color: 0xA0522D })
)
var top = new THREE.Mesh(
new THREE.SphereGeometry(150),
new THREE.MeshBasicMaterial({ color: 0x228B22 })
)
top.position.y = 175;
trunk.add(top);
trunk.position.set(x, -75, z);
scene.add(trunk);
}
makeTreeAt(500, 0);
makeTreeAt(-500, 0);
makeTreeAt(750, -1000);
makeTreeAt(-750, -1000);
var isCartWheeling = false;
var isFlipping = false;
function animate() {
requestAnimationFrame(animate);
if (isCartWheeling) {
marker.rotation.z = marker.rotation.z + 0.05;
}
if (isFlipping) {
marker.rotation.x = marker.rotation.x + 0.05;
}
renderer.render(scene, camera);
}
document.addEventListener('keydown', function (event) {
var code = event.keyCode;
if (code ==  37) marker.position.x = marker.position.x - 5; // move left
if (code == 38) marker.position.z = marker.position.z - 5; // up - move forward
if (code == 39) marker.position.x = marker.position.x + 5; // move right
if (code == 40) marker.position.z = marker.position.z + 5; // down - move backward
if (code == 67) isCartWheeling = ! isCartWheeling; // C
if (code == 70) isFlipping = ! isFlipping; // F
});
animate();
body {
margin: 0px;
}
canvas {
width: 100%;
height: 100%;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>First 3D avatar game</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r125/three.min.js"></script>
</head>
<body>
</body>
</html>

最新更新