🚶♂️基于 Three.js 的自定义角色漫游系统实战:支持碰撞检测与动画控制
在三维场景开发中,**自由漫游(Free Roaming)**功能是虚拟仿真、数字孪生、数字展厅等项目中常见的用户交互方式之一。尤其当角色需要在复杂地形或建筑中穿行时,基于物理碰撞与动画系统的角色控制器就显得尤为重要。
今天我们分享一个用 Three.js + three-mesh-bvh 实现的 自定义角色漫游类 CustomRoaming
,它支持以下高级特性:
✨ 功能亮点
✅ 支持角色三维模型加载与动画切换
✅ 支持重力模拟与跳跃控制
✅ 支持BVH加速的物理碰撞检测(基于胶囊体)
✅ 支持第一人称 / 第三人称视角切换
✅ 支持键盘WASD移动控制
✅ 支持BVH树与碰撞体可视化调试
✅ 结构清晰,易于集成进任何Three.js项目中
🧱 类结构一览
CustomRoaming
是一个 JavaScript/ES6 类,其核心职责可以归纳为五大模块:
1️⃣ 初始化阶段
js
constructor(scene, camera, renderer, controls, options)
- 接收 Three.js 的核心组件(Scene、Camera、Renderer、OrbitControls)
- 支持通过配置开启第一人称模式、显示碰撞体等功能
2️⃣ 角色与场景设置
initPlayScene()
:主入口,异步加载角色和场景碰撞网格_setupPlayer()
:自动计算角色高度并设置胶囊体参数_setupCollision()
:将 GLTF 场景静态化并生成MeshBVH
加速结构用于碰撞检测
3️⃣ 动画系统
js
_setupAnimations()
switchAnimation(newAction)
- 自动识别并绑定 GLTF 动画
stand / walk / jump
三种状态 - 支持通过
crossFade
实现平滑切换
4️⃣ 控制逻辑与物理更新
- 键盘监听
_keydown/_keyup
控制WASD+空格
updatePlayer(delta)
根据键盘状态、重力、速度、相机角度更新位置_handleCollisions()
使用 BVH 进行三维胶囊体-三角面片间的精确检测与反应
5️⃣ 渲染与相机控制
render()
每帧更新物理状态、动画、相机与可视化组件_updateCamera()
根据角色位置动态调整第三人称或第一人称相机位置
🔍 碰撞检测详解:BVH + 胶囊体碰撞
传统的 AABB 碰撞适用于盒子体模型,但角色模型往往是人形或者不规则。此类中采用了**胶囊体(Capsule)**来模拟角色体积。
通过 three-mesh-bvh
提供的 shapecast()
方法,可以高效检测胶囊与三角面片之间的最短距离,并进行空间位置修正,避免角色穿模。
js
this.collider.geometry.boundsTree.shapecast({
intersectsBounds: (box) => box.intersectsBox(tempBox),
intersectsTriangle: (tri) => {
const dist = tri.closestPointToSegment(...)
if (dist < capsule.radius) {
// 进行碰撞修正
}
}
})
🎮 支持动画的角色控制逻辑
此类支持 GLTF
动画中的 stand
、walk
和 jump
三种状态,通过控制器的输入与地面状态自动切换:
js
if (this.playerIsOnGround && pressingWASD) {
this.switchAnimation(this.actionWalk)
} else {
this.switchAnimation(this.actionIdle)
}
跳跃动作 采用 THREE.LoopOnce
模式,在空中播放一次动画,然后根据重力模拟自由落体。
🛠️ 如何使用
✅ 引入并初始化
js
const roaming = new CustomRoaming(scene, camera, renderer, controls, {
scene: 'scene.gltf',
player: 'player.gltf',
firstPerson: false,
playerPosition: new THREE.Vector3(0, 5, 0)
})
await roaming.initPlayScene()
🎞️ 在 render 循环中执行:
js
function animate() {
roaming.render()
renderer.render(scene, camera)
requestAnimationFrame(animate)
}
animate()
🧩 集成建议
- 用于数字展厅或建筑漫游:加载建筑GLTF模型后作为碰撞体
- 用于游戏项目原型:角色控制、跳跃、动画支持一应俱全
- 用于教育仿真:在三维空间中进行漫游教学与可视化交互
📦 未来可扩展方向
- ✅ 添加鼠标拾取(Raycaster)与交互物体联动
- ✅ 加入音效与UI提示
- ✅ 支持移动端触控控制
- ✅ 动态加载不同的 BVH 地形
🧠 总结
Three.js 提供了极强的三维渲染能力,而通过 three-mesh-bvh
和合理封装控制逻辑,我们可以将其扩展为一个完整的三维漫游系统。
如果你正在构建一个含有"人-场景-交互"的Web3D项目,不妨尝试将这套 CustomRoaming
控制器集成进你的系统中。它将是你构建虚拟世界的重要基石。
📌 源码地址: 你可以在留言区回复「漫游控制」获取源码文件!