7. 3D摄像机系统
2026/4/14大约 3 分钟
3D摄像机系统
摄像机是玩家"看"游戏世界的眼睛。这一章回答:透视相机和正交相机有什么区别?怎么让相机跟着角色走?
Camera3D 基础
在 3D 游戏中,没有摄像机就什么都看不到。Godot 使用 Camera3D 节点作为摄像机。
每个场景只能有一个"当前摄像机"(Current Camera)。如果有多个 Camera3D,只有设置了 Current = true 的那个会生效。
两种投影模式
透视投影(Perspective)
这是最常见的模式。近大远小——离摄像机近的东西看起来大,远的东西看起来小,和人眼看到的效果一样。
- 适用于:FPS、第三人称、大多数 3D 游戏
- 关键参数:
FOV(视野角度),默认 75 度 - FOV 越大,看到的范围越广(类似鱼眼效果)
- FOV 越小,看到的范围越窄(类似望远镜效果)
正交投影(Orthogonal)
没有近大远小——不管物体离摄像机多远,看起来都一样大。
- 适用于:城市模拟、策略游戏、2.5D 游戏
- 关键参数:
Size(视野大小),数值越大看到的范围越大 - 效果类似从高处往下看地图
摄像机跟随角色
方法一:直接作为子节点
最简单的方式:把 Camera3D 作为角色的子节点。摄像机会自动跟着角色移动。
缺点:摄像机跟着角色一起旋转,如果你不想要这个效果就需要其他方法。
方法二:用代码跟随
让摄像机成为独立节点,在代码里每帧更新它的位置:
C#
// C#: 摄像机平滑跟随
public override void _Process(double delta)
{
if (Target == null) return;
// 平滑跟随目标
Position = Position.Lerp(Target.Position + Offset, (float)(FollowSpeed * delta));
// 看向目标
LookAt(Target.Position, Vector3.Up);
}GDScript
# GDScript: 摄像机平滑跟随
func _process(delta):
if target == null:
return
# 平滑跟随目标
position = position.lerp(target.position + offset, follow_speed * delta)
# 看向目标
look_at(target.position, Vector3.UP)方法三:使用 RemoteTransform3D
一个更优雅的方式:在角色上放一个 RemoteTransform3D 节点,设置它同步到摄像机。这样角色移动时,摄像机的位置自动跟着更新,而且不需要写代码。
常见摄像机类型
| 类型 | 游戏示例 | 特点 |
|---|---|---|
| 第一人称 | FPS 游戏 | 摄像机在角色眼睛位置,跟着角色旋转 |
| 第三人称 | 原神、塞尔达 | 摄像机在角色身后上方,可以旋转 |
| 俯视角 | 城市天际线 | 从上往下看,可以缩放和平移 |
| 轨道摄像机 | 竞速游戏 | 摄像机在固定轨道上跟随目标 |
| 自由摄像机 | 编辑器/调试 | 不绑定任何目标,自由飞行 |
摄像机边界和限制
在实际项目中,通常需要限制摄像机的移动范围:
C#
// C#: 限制摄像机位置
Position = new Vector3(
Mathf.Clamp(Position.X, MinX, MaxX),
Mathf.Clamp(Position.Y, MinY, MaxY),
Mathf.Clamp(Position.Z, MinZ, MaxZ)
);GDScript
# GDScript: 限制摄像机位置
position = Vector3(
clampf(position.x, min_x, max_x),
clampf(position.y, min_y, max_y),
clampf(position.z, min_z, max_z)
)本章小结
- 透视投影:近大远小,适合大多数游戏
- 正交投影:没有透视,适合策略/模拟游戏
- 摄像机跟随有三种方式:子节点、代码、RemoteTransform3D
- 根据游戏类型选择合适的摄像机方案
