
第三人称移动 ·Third Move· ▶ 在线运行案例案例合集三维可视化功能案例threehub.cn开源仓库github地址https://github.com/z2586300277/three-cesium-examples400个案例代码:网盘链接你将学到什么AnimationMixer 骨骼动画播放与过渡glTF/FBX/OBJ 外部模型加载天空盒与环境贴图requestAnimationFrame 渲染循环Clock 帧间隔计时效果说明本案例演示第三人称移动效果基于 WebGL 实现「第三人称移动」可视化效果附完整可运行源码核心用到 glTF/Draco、骨骼动画与。建议先打开文首在线案例查看动态画面再对照下方源码逐步理解。核心概念AnimationMixer驱动 glTF 骨骼动画每帧mixer.update(delta)。动作切换可用crossFadeTo平滑过渡。Loader异步加载模型glTF 返回gltf.scene加载后注意scale与坐标系。Draco 需配置DRACOLoader。CubeTexture六面贴图作scene.backgroundscene.environment供 PBR 材质反射。实现步骤搭建 Scene / Camera / Renderer 与 OrbitControlsLoader 异步加载模型/纹理资源rAF 循环中 update 并 render代码要点import * as THREE from three;import { GLTFLoader } from three/examples/jsm/loaders/GLTFLoader.js;const scene new THREE.Scene();const camera new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);const renderer new THREE.WebGLRenderer({ antialias: true, alpha: true, logarithmicDepthBuffer: true });renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement)const urls [0, 1, 2, 3, 4, 5].map(k (FILE_HOST files/sky/skyBox0/ (k 1) .png))const textureCube new THREE.CubeTextureLoader().load(urls)scene.background textureCubescene.add(new THREE.GridHelper(100, 40))let characternew GLTFLoader().load(FILE_HOST files/model/Fox.glb, (gltf) {character gltf.scene character.traverse(i i.isMesh (i.material.envMap textureCube))scene.add(character) character.scale.multiplyScalar(0.03)const mixer new THREE.AnimationMixer(character) // 模型动画 const action mixer.clipAction(gltf.animations[1]) const clock new THREE.Clock() character.mixerUpdate () mixer.update(clock.getDelta()) action.play()})// 相机参数 const cameraOffset new THREE.Vector3(0, 5, -5); const smoothFactor 0.1; const moveSpeed 0.06; const turnSpeed 0.03;// 移动状态 const keys { w: false, s: false, a: false, d: false }; document.addEventListener(keydown, e keys[e.key.toLowerCase()] true); document.addEventListener(keyup, e keys[e.key.toLowerCase()] false);function update() {if (!character) returnif (keys.a) character.rotation.y turnSpeed; if (keys.d) character.rotation.y - turnSpeed; if (keys.w || keys.s) { const dir new THREE.Vector3(); character.getWorldDirection(dir); character.position.add(dir.multiplyScalar(keys.w ? moveSpeed : -moveSpeed)); } character.mixerUpdate()const targetPos character.position.clone().add(cameraOffset.clone().applyQuaternion(character.quaternion)); camera.position.lerp(targetPos, smoothFactor); camera.lookAt(character.position.clone().add(new THREE.Vector3(0, 1, 0)));}// 动画循环 animate(); function animate() {update() requestAnimationFrame(animate) renderer.render(scene, camera)}// 窗口自适应 window.addEventListener(resize, () {camera.aspect window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight);})GLOBAL_CONFIG.ElMessage(键盘事件WASD移动)完整源码GitHub小结本文提供第三人称移动完整 Three.js 源码与在线 Demo建议先运行案例再改 uniform/参数做二次实验更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库