我正在做一个项目,其中的人 (gltf对象) 是基于按键的行走。我可以根据按键更新对象的位置。
但是,当物体在行走时,我无法旋转物体。向左向右 鍵,並繼續朝該方向走。
附上代码供参考。
import { OrbitControls } from '../assets/js/OrbitControls.js';
import { GLTFLoader } from '../assets/js/GLTFLoader.js';
import { OBJLoader } from '../assets/js/OBJLoader.js';
var camera, scene, renderer, clock, man_walk, gltfLoader, mixer, action, objLoader, keyboard;
init();
animate();
function init(){
// Renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.gammaOutput = true
clock = new THREE.Clock();
document.body.appendChild(renderer.domElement);
// Scene
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xC3D8D6 );
// scene.fog = new THREE.Fog( 0xffffff, 0, 750 );
// Camera
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.y = 250;
camera.position.z = 600;
// Light
const light = new THREE.AmbientLight( 0x404040);
scene.add(light);
//keyevents
keyboard = new THREEx.KeyboardState();
// console.log(keyboard);
// // Controls
// var controls = new OrbitControls(camera, renderer.domElement);
// controls.enableDampling = true;
// controls.campingFactor = 0.25;
// controls.enableZoom = true;
// var vector = camera.getWorldDirection();
// console.log(vector);
getAlternateTiles();
getFloorMaterialByImage();
gltfLoader = new GLTFLoader();
objLoader = new OBJLoader();
loadDoor();
loadMan();
}
function loadDoor(){
objLoader.load('/assets/3d_models/Doorway/Doorway.obj', object => {
object.traverse(function (child) {
if (child.type == "Mesh") {
child.material = new THREE.MeshNormalMaterial();
}
});
scene.add(object);
object.rotation.z = -Math.PI / 2;
object.rotation.x = -Math.PI / 2;
object.scale.multiplyScalar(30);
object.position.z = 100
});
}
function loadMan(){
gltfLoader.load('/assets/3d_models/boy_animated/scene.gltf', gltf => {
man_walk = gltf.scene;
man_walk.position.set(0, 0, 60);
man_walk.rotateY(210.5);
scene.add(man_walk);
mixer = new THREE.AnimationMixer(man_walk);
mixer.clipAction(gltf.animations[0]).play();
});
}
function getAlternateTiles() {
var segments = 50;
var geometry = new THREE.PlaneGeometry(5000, 5000, segments, segments);
geometry.rotateX( - Math.PI / 2 );
var materialEven = new THREE.MeshBasicMaterial({color: 0x85A95D});
var materialOdd = new THREE.MeshBasicMaterial({color: 0x93BC54});
// #485C64
var materials = [materialEven, materialOdd];
for(var x=0; x<segments; x++) {
for(var y=0; y<segments; y++) {
var i = x * segments + y;
var j = 2 * i;
geometry.faces[ j ].materialIndex = geometry.faces[ j + 1 ].materialIndex = (x + y) % 2;
}
}
var mesh = new THREE.Mesh(geometry, materials);
scene.add(mesh);
}
function getFloorMaterialByImage() {
var geometry = new THREE.PlaneGeometry( 1000, 1000, 10, 10 );
geometry.rotateX( - Math.PI / 2 );
// lightwood.jpg, whitetiles.jpg, floorline.jpg, woodsheet.jpg, Carpet.jpeg, Wood_Bamboo.jpeg, corporate.jpg
var floorTexture = new THREE.TextureLoader().load( '/assets/img/floorline.jpg' );
floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
floorTexture.repeat.set(20, 20);
var material = new THREE.MeshBasicMaterial({map: floorTexture});
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
}
// Animate
function animate() {
requestAnimationFrame(animate);
render();
updateMan();
}
function updateMan(){
var delta = clock.getDelta(); // seconds.
var rotateAngle = Math.PI / 2 * delta;
var moveDistance = 150 * delta; // 100 pixels per second
var rotateAngle = Math.PI / 2 * delta; // pi/2 radians (90 degrees) per second
if ( keyboard.pressed("a") ){
man_walk.rotateOnAxis(new THREE.Vector3(0,1,0), rotateAngle);
}
if ( keyboard.pressed("d") ){
man_walk.rotateOnAxis(new THREE.Vector3(0,1,0), -rotateAngle);
}
if ( keyboard.pressed("w") ){
man_walk.translateZ(- moveDistance);
mixer.update(delta);
}
var relativeCameraOffset = new THREE.Vector3(0,250,600);
var cameraOffset = relativeCameraOffset.applyMatrix4( man_walk.matrixWorld );
camera.position.x = cameraOffset.x;
camera.position.y = cameraOffset.y;
camera.position.z = cameraOffset.z;
camera.lookAt(man_walk.position);
}
function render()
{
renderer.render( scene, camera );
}
动画使用为项目。
https:/sketchfab.com3d-modelsnathan-animated-003-walking-3d-man-143a2b1ea5eb4385ae90a73657aca3bc。
先谢谢你的时间。
我更新了我的 updateMan()
函数,以使摄像机始终注视着人物模型。而且相对CameraOffset应该与实际相机位置的方向相反。
请看后面的代码。
如果有什么不对的地方,请纠正我。
function updateMan(){
var delta = clock.getDelta(); // seconds.
var rotateAngle = Math.PI / 2 * delta;
var moveDistance = 150 * delta; // 100 pixels per second
var rotateAngle = Math.PI / 2 * delta; // pi/2 radians (90 degrees) per second
if ( keyboard.pressed("a") ){
man_walk.rotateOnAxis(new THREE.Vector3(0,1,0), rotateAngle);
}
if ( keyboard.pressed("d") ){
man_walk.rotateOnAxis(new THREE.Vector3(0,1,0), -rotateAngle);
}
if ( keyboard.pressed("w") ){
man_walk.translateZ(moveDistance);
mixer.update(delta);
}
var relativeCameraOffset = new THREE.Vector3(0,250,-600);
var cameraOffset = relativeCameraOffset.applyMatrix4( man_walk.matrixWorld );
camera.position.x = cameraOffset.x;
camera.position.y = cameraOffset.y;
camera.position.z = cameraOffset.z;
camera.lookAt(man_walk.position);
}