这里主要用到了 一个方法 obj.getWorldDirection();
obj.getWorldDirection()
表示的获取obj对象自身z轴正方向在世界坐标空间中的方向。
按下 W键前进运动;
<template>
<div>
<el-container>
<el-main>
<div class="box-card-left">
<div id="threejs"></div>
{{ movementX }}
</div>
</el-main>
</el-container>
</div>
</template>s
<script>
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import TWEEN from '@tweenjs/tween.js';
export default {
data() {
return {
scene: null,
camera: null,
renderer: null,
res1: null,
res2: null,
clock: null,
left_mouse_down: false,
keyState: {
W: false,
S: false,
A: false,
D: false,
},
left_rotation: true, // 向左旋转的标志
right_rotation: true, // 向右旋转的标志
VW: new this.$three.Vector3(0, 0, 0),
VS: new this.$three.Vector3(0, 0, 0),
curr_v: new this.$three.Vector3(0, 0, 0),
person: null,
movementX: null,
deltaTime: 0,
a: 60, // 加速度
damping: -0.04,
};
},
created() {},
mounted() {
this.init();
},
methods: {
goBack() {
this.$router.go(-1);
},
init() {
// 创建场景对象
this.scene = new this.$three.Scene();
// 创建坐标轴辅助对象
const axesHelper = new this.$three.AxesHelper(100);
this.scene.add(axesHelper);
// 创建时钟对象
this.clock = new this.$three.Clock();
// 创建环境光对象
const ambientLight = new this.$three.AmbientLight(0xffffff, 6);
this.scene.add(ambientLight);
// this.createMesh();
// 创建相机对象
this.camera = new this.$three.PerspectiveCamera(60,1,0.01,2000);
// this.camera.position.set(0,5,-5);
// this.camera.lookAt(0,0,0);
// 创建渲染器对象
this.renderer = new this.$three.WebGLRenderer();
this.renderer.setSize(1000,800);
// 创建gltfLoader加载器对象
const gltfLoader = new GLTFLoader();
gltfLoader.load("models/gltf/person2/scene.gltf", gltf => {
this.person = gltf.scene;
// 将相机添加到人物模型上
this.person.add(this.camera);
// 调整相机位置
this.camera.position.add(new this.$three.Vector3(0,5,-6));
this.camera.translateZ(-1);
let camera_look_position = this.person.position.clone().add(new this.$three.Vector3(0,4,0));
// 设置相机指向
this.camera.lookAt(camera_look_position);
this.scene.add(gltf.scene);
this.renderer.render(this.scene, this.camera);
window.document.getElementById("threejs").appendChild(this.renderer.domElement);
})
// 监听事件方法
this.addEventListenerFn();
this.renderLoop();
},
createMesh() {
const geometry = new this.$three.BoxGeometry(1,1,1);
const material = new this.$three.MeshBasicMaterial({color: 0xffaadd});
const mesh = new this.$three.Mesh(geometry, material);
// mesh.rotateY(Math.PI / 2);
const dir = new this.$three.Vector3();
mesh.getWorldDirection(dir);
this.scene.add(mesh);
console.log('dir', dir);
},
addEventListenerFn() {
document.addEventListener("mousemove", e => {
// 鼠标左键按下的情况
if(this.left_mouse_down) {
this.movementX = e.movementX;
this.person.rotation.y -= e.movementX / 100;
// this.camera.rotateY(e.movementX / 100);
const dir = new this.$three.Vector3();
this.person.children[0].getWorldDirection(dir);
this.renderer.render(this.scene, this.camera);
}
})
document.addEventListener("mousedown", e => {
// e.button == 0 左键;e.button == 2 右键;
if(e.button == 0) {
this.left_mouse_down = true;
}
})
document.addEventListener("mouseup", e => {
// e.button == 0 左键;e.button == 2 右键;
if(e.button == 0) {
this.left_mouse_down = false;
}
})
// 监听键盘按下
document.addEventListener("keydown", e => {
// 如果按下的是 w键
if(e.code == "KeyW") {
this.keyState.W = true;
}
if(e.code == "KeyS") {
this.keyState.S = true;
}
})
// 监听键盘弹起
document.addEventListener("keyup", e => {
// 如果按下的是 w键
if(e.code == "KeyW") {
this.keyState.W = false;
}
if(e.code == "KeyS") {
this.keyState.S = false;
}
})
},
renderLoop() {
let deltaTime = this.clock.getDelta();
if(this.keyState.W) {
const front = new this.$three.Vector3();
this.person.getWorldDirection(front);
let person_v = this.curr_v.clone().add(front.multiplyScalar(deltaTime * this.a));
const pos = person_v.clone().multiplyScalar(deltaTime);
this.person.position.add(pos);
}
if(this.keyState.S) {
const front = new this.$three.Vector3();
this.person.getWorldDirection(front);
let person_v = this.curr_v.clone().add(front.multiplyScalar(deltaTime * (-this.a)));
const pos = person_v.clone().multiplyScalar(deltaTime);
this.person.position.add(pos);
}
this.renderer.render(this.scene, this.camera);
window.requestAnimationFrame(this.renderLoop);
},
},
};
</script>
<style lang="less" scoped>
.box-card-left {
display: flex;
align-items: flex-start;
flex-direction: row;
width: 100%;
.box-right {
img {
width: 500px;
user-select: none;
}
}
}
</style>