Three.js 点击第三人称移动教程

发布时间:2026/7/16 9:24:50

Three.js 点击第三人称移动教程 点击第三人称移动 ·Person Move· ▶ 在线运行案例案例合集三维可视化功能案例threehub.cn开源仓库github地址https://github.com/z2586300277/three-cesium-examples400个案例代码:网盘链接你将学到什么AnimationMixer 骨骼动画播放与过渡glTF/FBX/OBJ 外部模型加载相机交互控制器GSAP / anime.js 属性动画requestAnimationFrame 渲染循环效果说明本案例演示点击第三人称移动效果支持鼠标拾取、绘制或拖拽交互核心用到 OrbitControls、glTF/Draco、GSAP。建议先打开文首在线案例查看动态画面再对照下方源码逐步理解。核心概念AnimationMixer驱动 glTF 骨骼动画每帧mixer.update(delta)。动作切换可用crossFadeTo平滑过渡。Loader异步加载模型glTF 返回gltf.scene加载后注意scale与坐标系。Draco 需配置DRACOLoader。OrbitControls轨道旋转缩放开enableDamping时每帧需controls.update()。时间线库驱动 position/rotation/uniform与 rAF 渲染循环配合。实现步骤搭建 Scene / Camera / Renderer 与 OrbitControlsLoader 异步加载模型/纹理资源rAF 循环中 update 并 render代码要点import * as THREE from threeimport { OrbitControls } from three/examples/jsm/controls/OrbitControls.js import { GLTFLoader } from three/examples/jsm/loaders/GLTFLoader.js import gsap from gsapconst box document.getElementById(box)const scene new THREE.Scene()const camera new THREE.PerspectiveCamera(75, box.clientWidth / box.clientHeight, 0.1, 1000)camera.position.set(5, 5, 5)const renderer new THREE.WebGLRenderer({ antialias: true, alpha: true, logarithmicDepthBuffer: true })renderer.setSize(box.clientWidth, box.clientHeight)box.appendChild(renderer.domElement)const controls new OrbitControls(camera, renderer.domElement)scene.add(new THREE.AmbientLight(0xffffff, 4), new THREE.GridHelper(40, 20))animate()function animate() {requestAnimationFrame(animate)renderer.render(scene, camera)}let group nullnew GLTFLoader().load(FILE_HOST files/model/Soldier.glb,gltf {group gltf.scenescene.add(group)const clock new THREE.Clock() // 时钟const mixer new THREE.AnimationMixer(group) // 模型动画group.mixerAnimateRender () mixer.update(clock.getDelta()) // 动画帧group.currentAction mixer.clipAction(gltf.animations[3]) // walk 动画})const raycaster new THREE.Raycaster() // 射线const targetPositon new THREE.Vector3() // 目标位置const plane new THREE.Plane(new THREE.Vector3(0, 1, 0), 0) // 碰撞面// 点击事件 box.addEventListener(click, (event) {const mouse new THREE.Vector2((event.offsetX / event.target.clientWidth)2 - 1, -(event.offsetY / event.target.clientHeight)2 1)raycaster.setFromCamera(mouse, camera)raycaster.ray.intersectPlane(plane, targetPositon)const mesh new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.1, 0.1), new THREE.MeshBasicMaterial())mesh.position.copy(targetPositon)scene.add(mesh)goAddress(group, targetPositon)})let oldgsap nullfunction goAddress(group, targetPositon) {oldgsap?.kill() // 停止上一个动画const distance group.position.distanceTo(targetPositon) // 距离const vector camera.position.clone().sub(group.position) // camera 和 group 差向量group.lookAt(targetPositon) // 模型朝向group.rotation.y Math.PI // 朝向纠正const duration distance / 3 // 距离 / 速度oldgsap gsap.to(group.position, {...targetPositon, duration, ease: none,onStart: () {controls.enabled false // 禁止控制group.currentAction.play() // 播放动画},onUpdate: () {group.mixerAnimateRender() // 动画帧controls.target.copy(group.position) // 目标跟随 camera.position.lerp(group.position.clone().add(vector), 0.1) // 相机跟随},onComplete: () controls.enabled true // 恢复控制})}完整源码GitHub小结本文提供点击第三人称移动完整 Three.js 源码与在线 Demo建议先运行案例再改 uniform/参数做二次实验更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库

相关新闻