AnvilKitAnvilKit

相机系统

生产级相机系统 — 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 秒内平滑混合

可用缓动类型:LinearSmoothStepSmootherStepEaseInOutCubicEaseOutQuart

轨道相机

使用 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 次幂

万向节锁保护

第三人称和注视系统自动处理万向节锁——当摄像机接近目标正上方或正下方时,使用替代的上方向向量防止翻转。

目录