项目框架:
vue
+typescript
相机跟随曲线运动
首先要实现人物的曲线运动,坐标点是设计师直接放在模型上的,导入模型后,用模型上的点生成曲线,再用曲线的getPoint
方法获取点坐标。
获取模型上的点并转为世界坐标
1 | const points = [] |
生成曲线获取新的坐标组
1 | const ARC_SEGMENTS = 50 // 希望得到的点数量 |
相机跟随
将人物和相机放到一个父对象下,用父对象去做运动
1 | private myAnimationBox: any = new THREE.Object3D() // 父元素 |
用tweenjs动画库实现运动
这里顺便提一下在vue+typescript里使用tween.js的问题,直接引用threejs里面的tween会报错,所以要npm i @tweenjs/tween.js
,再引入:1
2import * as T from '@tweenjs/tween.js'
const TWEEN:any = T.default
跟随运动:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25...
// walkPoints即上面使用``getPoint``方法获得的点坐标
// animationIndex是当前的下标
_this.myAnimation = new TWEEN.Tween(_this.myAnimationBox.position)
.to({
x: _this.walkPoints[_this.animationIndex].x / 1,
y: _this.walkPoints[_this.animationIndex].y / 1,
z: _this.walkPoints[_this.animationIndex].z / 1
}, tweenTime)
.onUpdate(() => {
var a = _this.myAnimationBox.position.clone()
a.y += 20 // 这里在y轴加20是因为视角要往上一些
_this.control.target.copy(a)
// 保证相机朝向正确
_this.myAnimationBox.matrix.lookAt(_this.myAnimationBox.position, new THREE.Vector3(0, _this.myAnimationBox.position.y, 0), new THREE.Vector3(0, 1, 0))
_this.myAnimationBox.quaternion.setFromRotationMatrix(_this.myAnimationBox.matrix)
})
.onComplete(() => {
_this.animationIndex++
animation(_this.animationIndex)
})
.start()
...
无限循环
这边要实现一个人物无限向上运动的功能,当然模型不可能做成无限循环的,这边的处理非常简单,就是不停改变模型的位置,使用三组模型,每次把最下面一层移到最上面1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21// 每次改变坐标点的Y值,因为X和Z是不变的
for (let j = 0; j < _this.walkPoints.length; j++) {
_this.walkPoints[j].y += ADD_HEIGHT
}
let changeIndex = 0
// roadIndex是一个不断往上增长的数字变量,代表当前所在的层数
// 由此算出现在要移动第几个模型
if (_this.roadIndex % 3 == 0) {
changeIndex = 2
} else if ((_this.roadIndex + 1) % 3 == 0) {
changeIndex = 1
} else {
changeIndex = 0
}
// ADD_HEIGHT是每层的高度,每次将最下面一层移到最上面
_this.groupRoad.children[changeIndex].position.y += ADD_HEIGHT * 3
_this.groupModel.children[changeIndex].position.y += ADD_HEIGHT * 3
_this.groupModelShadow.children[changeIndex].position.y += ADD_HEIGHT * 3
参考文档
https://threejs.org/examples/#webgl_geometry_extrude_splines