相机系统
生产级相机系统 — 5 种模式、Trauma 抖动、弹簧臂、轨道相机、过渡混合
anvilkit-camera 提供生产级的相机系统,基于可组合的 ECS 组件。
模块结构
anvilkit_camera
├── controller CameraMode + CameraController
├── input_curve 死区 + 响应曲线
├── systems 核心 ECS 系统 (输入、模式、特效)
├── plugin CameraPlugin 注册
├── orbit/ 轨道子系统
│ ├── OrbitState 距离、目标、限制
│ ├── rig 实体跟随 + 偏移 + 阻尼
│ └── spring_arm 碰撞避免 (Ray-AABB)
├── effects/ 视觉特效子系统
│ ├── CameraEffects Trauma 抖动、头部摆动、FOV
│ ├── noise Perlin 梯度噪声
│ └── transition 相机平滑混合 (5 种缓动)
└── constraints/ 相机约束
├── look_at 软注视约束 + 死区
└── rail 轨道/推轨相机 (线性 + Catmull-Rom)CameraController
use anvilkit_camera::prelude::*;
let controller = CameraController {
mode: CameraMode::FirstPerson,
move_speed: 10.0,
mouse_sensitivity: 0.003,
base_fov: 70.0,
input_curve: InputCurve::quadratic(0.05), // 5% 死区,二次响应
..Default::default()
};系统管线自动从 InputState::mouse_delta() 读取鼠标增量,无需手动管理。
摄像机模式
| 模式 | 说明 | 所需组件 |
|---|---|---|
FirstPerson | 第一人称,直接控制偏航/俯仰 | — |
ThirdPerson | 第三人称,围绕跟随实体旋转 | OrbitState + CameraRig |
Orbit | 围绕固定点旋转(检查/编辑器) | OrbitState |
Free | 六自由度自由飞行 | — |
Rail | 沿预定义路径运动 | CameraRail |
系统管线
所有系统在 PostUpdate 按顺序执行:
rig → input → rail → mode → spring_arm → look_at → effects → transition轨道 + 实体跟随
use anvilkit_camera::prelude::*;
// 生成跟随玩家实体的摄像机
world.spawn((
CameraController { mode: CameraMode::ThirdPerson, ..default() },
OrbitState::new(Vec3::ZERO, 8.0)
.with_distance_limits(3.0, 20.0)
.with_target_offset(Vec3::new(0.0, 1.6, 0.0)), // 眼高
CameraRig::new(player_entity)
.with_offset(Vec3::new(0.0, 1.6, 0.0))
.with_damping(10.0),
SpringArm::new(0.3).with_margin(0.2), // 碰撞避免
CameraComponent::default(),
Transform::default(),
));摄像机特效(Trauma 系统)
基于 Squirrel Eiserloh GDC 2016 的 Trauma 系统,使用 Perlin 噪声:
use anvilkit_camera::effects::CameraEffects;
let mut fx = CameraEffects::default();
fx.head_bob_enabled = true;
// 触发抖动(如着陆、爆炸)
fx.add_trauma(0.5); // 累加到 trauma [0,1],随时间衰减
// 抖动强度 = trauma^power * noise(time)
fx.fov_target = 10.0; // 冲刺 FOV 偏移(平滑插值)add_shake() 保留为 add_trauma() 的向后兼容别名。
摄像机过渡
模式切换时的平滑混合:
use anvilkit_camera::prelude::*;
// 附加到摄像机实体
let transition = CameraTransition::new(0.5, EasingType::SmoothStep);
// 切换模式前,捕获当前状态
transition.start(current_pos, current_rot, current_fov);
ctrl.mode = CameraMode::ThirdPerson;
// 系统自动在 0.5 秒内平滑混合可用缓动类型:Linear、SmoothStep、SmootherStep、EaseInOutCubic、EaseOutQuart。
轨道相机
使用 Catmull-Rom 样条的推轨相机:
use anvilkit_camera::prelude::*;
let rail = CameraRail::new(vec![
Vec3::new(0.0, 5.0, -10.0),
Vec3::new(10.0, 3.0, 0.0),
Vec3::new(0.0, 5.0, 10.0),
Vec3::new(-10.0, 3.0, 0.0),
])
.with_speed(0.1)
.with_looping(true)
.with_interpolation(RailInterpolation::CatmullRom { tension: 0.5 });输入曲线
死区和响应曲线,实现精确相机控制:
use anvilkit_camera::input_curve::InputCurve;
InputCurve::linear() // 1:1 线性响应(默认)
InputCurve::quadratic(0.05) // 抑制小幅输入,5% 死区
InputCurve::cubic(0.1) // 强抑制,10% 死区
InputCurve::new(0.08, 1.5) // 自定义:8% 死区,1.5 次幂万向节锁保护
第三人称和注视系统自动处理万向节锁——当摄像机接近目标正上方或正下方时,使用替代的上方向向量防止翻转。