5.4 Cinemachine 5.4 Cinemachine:Unity 动态相机系统的艺术 在现代游戏和互动体验中,相机扮演着至关重要的角色。它不仅是玩家观察世界的窗口,更是叙事、情感表达和游戏节奏控制的关键工具。手动控制复杂的相机行为既耗时又容易出错,尤其是在动态的游戏场景中。Unity Cinemachine 的出现,彻底改变了游戏开发者处理相机问题的方式。它提供了一套强大的工具,以程序化的、直观的方式创建复杂的相机行为,让开发者能够专注于游戏的创意和核心玩法,而不是繁琐的相机控制细节。 本章节将深入探讨 Unity Cinemachine,从基础概念到高级技巧,结合代码实践和详细解释,帮助你掌握这一强大的相机系统,为你的 Unity 项目注入电影级的镜头语言。 5.4.
在现代游戏和互动体验中,相机扮演着至关重要的角色。它不仅是玩家观察世界的窗口,更是叙事、情感表达和游戏节奏控制的关键工具。手动控制复杂的相机行为既耗时又容易出错,尤其是在动态的游戏场景中。Unity Cinemachine 的出现,彻底改变了游戏开发者处理相机问题的方式。它提供了一套强大的工具,以程序化的、直观的方式创建复杂的相机行为,让开发者能够专注于游戏的创意和核心玩法,而不是繁琐的相机控制细节。
本章节将深入探讨 Unity Cinemachine,从基础概念到高级技巧,结合代码实践和详细解释,帮助你掌握这一强大的相机系统,为你的 Unity 项目注入电影级的镜头语言。
Cinemachine 的核心在于两个关键组件:Virtual Camera (虚拟相机) 和 Cinemachine Brain (大脑)。理解这两个组件是掌握 Cinemachine 的基石。
1. Virtual Camera (虚拟相机 - VCam)
Virtual Camera 是 Cinemachine 的灵魂,它并非实际场景中的物理相机,而是一个逻辑实体,定义了 期望的相机行为。你可以将其理解为一个指令集,告诉 Cinemachine Brain 你希望相机如何运动、朝向哪里、以及如何与场景互动。
VCam 的职责:
定义相机视角: VCam 决定了相机的视野 (Field of View)、正交投影 (Orthographic) 或透视投影 (Perspective) 等基础属性。
控制相机运动: VCam 通过各种组件 (Component) 驱动相机的运动,例如跟随目标 (Follow Target)、注视目标 (Look At Target)、轨道移动 (Dolly Track) 等。
添加相机效果: VCam 可以通过扩展 (Extension) 组件添加各种后期处理效果,例如噪声 (Noise)、抖动 (Jitter) 等,增强镜头的动感和表现力。
定义相机行为优先级: 在场景中可以存在多个 VCam,通过优先级 (Priority) 属性,Cinemachine Brain 可以决定在特定时刻激活哪个 VCam。
VCam 的优势:
程序化控制: VCam 的行为是程序化的,可以通过脚本动态调整,实现复杂的相机逻辑。
易于配置: 通过 Inspector 面板,可以直观地配置 VCam 的各种属性和组件,无需编写大量代码。
可重用性: VCam 可以作为预制体 (Prefab) 重复使用,快速构建复杂的相机系统。
解耦相机逻辑: VCam 将相机行为与实际场景相机分离,使得相机控制更加灵活和模块化。
2. Cinemachine Brain (大脑)
Cinemachine Brain 组件必须添加到场景中的 主相机 (Main Camera) 上。它是 Cinemachine 系统的中枢,负责:
管理场景中的所有 VCam: Brain 扫描场景中所有可用的 VCam。
选择激活的 VCam: Brain 根据 VCam 的优先级 (Priority) 和其他条件 (例如脚本控制) 决定当前激活哪个 VCam。
混合 (Blend) 相机视角: 当激活的 VCam 切换时,Brain 会平滑地混合 (Blend) 前后两个 VCam 的视角,避免生硬的镜头切换,提供更流畅的观影体验。
应用 VCam 的指令: Brain 将当前激活的 VCam 的指令应用到主相机,驱动主相机的运动和行为。
混合 (Blending) 是 Cinemachine Brain 最重要的功能之一。它确保了在不同 VCam 之间切换时,相机视角的过渡是平滑自然的。Brain 提供了多种混合模式 (Blend Mode),例如:
* **Cut (剪切):** 立即切换到新的 VCam,没有混合效果,通常用于快速镜头切换或硬切。 * **Ease In Out (缓入缓出):** 默认的混合模式,平滑地加速进入和减速退出混合过程,提供自然的过渡效果。 * **Ease In (缓入):** 混合过程开始时加速,结束时保持恒速。 * **Ease Out (缓出):** 混合过程开始时恒速,结束时减速。 * **Linear (线性):** 匀速混合,提供机械感的过渡效果。 * **Custom (自定义):** 允许开发者自定义混合曲线,实现更精细的控制。
你可以通过调整 Cinemachine Brain 组件中的 Default Blend 属性来设置默认的混合模式和持续时间。
在 Unity 中创建和配置 Virtual Camera 非常简单:
创建 VCam: 在 Unity 编辑器菜单栏中,选择 Cinemachine -> Create Virtual Camera。这将在场景中创建一个新的 GameObject,并添加 Cinemachine Virtual Camera 组件。
配置 VCam 属性: 在 Inspector 面板中,你可以配置 VCam 的各种属性,例如:
Priority (优先级): 数值越高,优先级越高。Brain 会优先激活优先级最高的 VCam。
Follow (跟随目标): 指定一个 Transform 作为跟随目标,VCam 会尝试保持与目标的相对位置。
Look At (注视目标): 指定一个 Transform 作为注视目标,VCam 会始终朝向该目标。
Lens (镜头): 配置相机的镜头属性,例如 Field of View (视野)、Near Clip Plane (近裁剪面)、Far Clip Plane (远裁剪面) 等。
Body (身体): 控制 VCam 的运动方式,例如 Transposer (平移器)、Orbital Transposer (轨道平移器)、Framing Transposer (构图平移器) 等。
Aim (瞄准): 控制 VCam 的朝向方式,例如 Composer (构图器)、POV (视角)、Group Composer (组构图器) 等。
Extensions (扩展): 添加各种扩展组件,增强 VCam 的功能,例如 Cinemachine Noise (相机噪声)、Cinemachine Impulse Listener (冲量监听器) 等。
代码实践 1:创建一个基本的跟随相机
以下代码演示了如何创建一个跟随玩家的 Virtual Camera。
using UnityEngine; using Cinemachine; public class FollowPlayerCamera : MonoBehaviour { public Transform playerTransform; // 玩家的 Transform 组件 public float followOffset = 5f; // 相机与玩家的偏移距离 private CinemachineVirtualCamera vcam; void Start() { // 创建 Virtual Camera GameObject GameObject vcamGameObject = new GameObject("PlayerFollowCamera"); vcam = vcamGameObject.AddComponent<CinemachineVirtualCamera>(); // 设置跟随目标 vcam.Follow = playerTransform; // 配置 Body 组件为 Transposer,并设置偏移 CinemachineTransposer transposer = vcam.AddCinemachineComponent<CinemachineTransposer>(); transposer.m_FollowOffset = new Vector3(0, followOffset, -followOffset); // 设置优先级,确保它是激活的相机 vcam.Priority = 10; } }
代码解释:
创建 VCam GameObject 和组件: 使用 new GameObject() 创建一个新的 GameObject,并添加 CinemachineVirtualCamera 组件。
设置 Follow 属性: 将 vcam.Follow 设置为玩家的 Transform 组件,使 VCam 跟随玩家移动。
添加 CinemachineTransposer 组件: Transposer 是 Cinemachine Body 组件的一种,用于实现平移跟随。
配置 m_FollowOffset: 设置 Transposer 的 m_FollowOffset 属性,定义相机与玩家的相对偏移距离。
设置 Priority: 将 VCam 的优先级设置为较高的值 (例如 10),确保它在场景中被激活。
将此脚本添加到场景中的一个空 GameObject 上,并将玩家的 Transform 组件拖拽到 Player Transform 字段,运行游戏,你将看到相机跟随玩家移动。
Cinemachine Body 组件负责控制 Virtual Camera 的运动方式。它提供了多种 Body 组件,用于实现不同的相机运动效果。
1. Transposer (平移器)
Transposer 组件是最常用的 Body 组件之一,它使 VCam 保持与跟随目标的相对位置。
关键属性:
Follow Offset (跟随偏移): 定义 VCam 与跟随目标的相对偏移距离。
Binding Mode (绑定模式): 控制 VCam 如何绑定到跟随目标的旋转。
Lock To Target On Assign: VCam 初始旋转与目标一致。
Lock To Target With World Up: VCam 保持世界坐标系 Y 轴向上。
Lock To Target No Roll: VCam 锁定 Roll 轴旋转。
Orbital: 允许 VCam 围绕目标旋转。
Custom: 自定义绑定行为。
Damping (阻尼): 平滑相机运动,减少抖动。
XDamping, YDamping, ZDamping: 分别控制 X、Y、Z 轴的阻尼系数。代码实践 2:调整 Transposer 的阻尼效果
using UnityEngine; using Cinemachine; public class AdjustDamping : MonoBehaviour { public CinemachineVirtualCamera vcam; public float dampingValue = 0.5f; void Update() { if (vcam != null) { CinemachineTransposer transposer = vcam.GetCinemachineComponent<CinemachineTransposer>(); if (transposer != null) { transposer.m_XDamping = dampingValue; transposer.m_YDamping = dampingValue; transposer.m_ZDamping = dampingValue; } } } }
代码解释:
获取 CinemachineTransposer 组件: 使用 vcam.GetCinemachineComponent<CinemachineTransposer>() 获取 VCam 的 Transposer 组件。
修改 Damping 属性: 将 transposer.m_XDamping, transposer.m_YDamping, transposer.m_ZDamping 设置为 dampingValue,调整阻尼系数。
运行游戏,调整 dampingValue 的值,观察相机运动的平滑程度变化。阻尼值越高,相机运动越平滑,但响应速度也会降低。
2. Orbital Transposer (轨道平移器)
Orbital Transposer 组件允许 VCam 围绕跟随目标旋转,常用于第三人称视角相机。
关键属性:
Follow Offset (跟随偏移): 定义 VCam 与跟随目标的相对偏移距离。
X Axis (X 轴): 控制水平旋转。
Value: 当前水平旋转角度。
Input Axis Name: 绑定输入轴,例如 "Mouse X" 或 "Horizontal"。
Input Value Provider: 使用自定义输入值提供器。
Wrap Around Bounds: 限制旋转角度范围。
Recentering: 自动回中功能。
Y Axis (Y 轴): 控制垂直旋转,属性与 X 轴类似。
Damping (阻尼): 平滑旋转运动。
XDamping, YDamping: 分别控制 X、Y 轴的阻尼系数。代码实践 3:创建一个可旋转的第三人称相机
创建 VCam,设置 Follow 目标。
将 Body 组件设置为 Orbital Transposer。
配置 X Axis 和 Y Axis 属性:
Input Axis Name 设置为 "Mouse X" 和 "Mouse Y"。
调整 X Axis 和 Y Axis 的 Speed 属性,控制旋转速度。
运行游戏,移动鼠标,你将看到相机围绕跟随目标旋转。
3. Framing Transposer (构图平移器)
Framing Transposer 组件旨在保持跟随目标在画面中的特定位置,并自动调整相机距离和角度,以确保目标始终可见。常用于动作游戏和平台跳跃游戏。
关键属性:
Follow Offset (跟随偏移): 初始偏移距离。
Screen X/Y (屏幕 X/Y): 定义目标在屏幕上的理想位置 (0-1 范围)。
Dead Zone Width/Height (死区宽度/高度): 目标在死区范围内移动时,相机不移动。
Soft Zone Width/Height (软区宽度/高度): 目标进入软区后,相机开始平滑移动。
Damping (阻尼): 平滑相机运动。
XDamping, YDamping, ZDamping: 分别控制 X、Y、Z 轴的阻尼系数。代码实践 4:使用 Framing Transposer 保持目标在画面中心
创建 VCam,设置 Follow 目标。
将 Body 组件设置为 Framing Transposer。
配置 Screen X 和 Screen Y 属性: 设置为 0.5,使目标保持在画面中心。
调整 Dead Zone 和 Soft Zone 属性,根据需要调整相机响应灵敏度。
运行游戏,移动跟随目标,观察 Framing Transposer 如何自动调整相机位置,保持目标在画面中心。
4. Dolly Track (轨道)
Dolly Track 组件允许 VCam 沿着预先定义的路径 (Cinemachine Track) 运动。常用于过场动画、场景漫游等。
关键组件:
Cinemachine Track: 使用 Cinemachine Tracked Dolly 组件创建轨道。轨道由多个路径点 (Waypoint) 组成,可以使用贝塞尔曲线平滑路径。
Path Position (路径位置): 控制 VCam 在轨道上的位置 (0-1 范围)。
代码实践 5:创建一个 Dolly Track 相机
创建 Cinemachine Track: 在场景中创建一个空 GameObject,添加 Cinemachine Tracked Dolly 组件。在 Scene 视图中编辑轨道路径,添加和调整路径点。
创建 VCam,将 Body 组件设置为 Dolly Track。
将 Cinemachine Track 拖拽到 VCam 的 Path 属性。
使用脚本控制 VCam 的 Path Position 属性,使其沿轨道移动。
using UnityEngine; using Cinemachine; public class DollyTrackController : MonoBehaviour { public CinemachineVirtualCamera vcam; public float speed = 1f; private CinemachineTrackedDolly dollyTrack; private float pathPosition = 0f; void Start() { dollyTrack = vcam.GetCinemachineComponent<CinemachineTrackedDolly>(); } void Update() { pathPosition += speed * Time.deltaTime; pathPosition = Mathf.Repeat(pathPosition, 1f); // 循环路径 dollyTrack.m_PathPosition = pathPosition; } }
代码解释:
获取 CinemachineTrackedDolly 组件: 使用 vcam.GetCinemachineComponent<CinemachineTrackedDolly>() 获取 VCam 的 Dolly Track 组件。
更新 m_PathPosition 属性: 在 Update() 函数中,不断增加 pathPosition 的值,并使用 Mathf.Repeat() 函数使其在 0-1 范围内循环,实现相机沿轨道循环运动。
Cinemachine Aim 组件负责控制 Virtual Camera 的朝向。它提供了多种 Aim 组件,用于实现不同的相机注视效果。
1. Composer (构图器)
Composer 组件使 VCam 注视目标,并允许调整构图,例如偏移目标在画面中的位置,设置软区和死区等。
关键属性:
Look At Target (注视目标): 指定 VCam 注视的 Transform。
Screen X/Y (屏幕 X/Y): 定义目标在屏幕上的理想位置 (0-1 范围)。
Dead Zone Width/Height (死区宽度/高度): 目标在死区范围内移动时,相机不调整朝向。
Soft Zone Width/Height (软区宽度/高度): 目标进入软区后,相机开始平滑调整朝向。
Damping (阻尼): 平滑相机朝向变化。
XDamping, YDamping: 分别控制水平和垂直方向的阻尼系数。2. POV (视角)
POV 组件允许开发者直接控制 VCam 的旋转角度 (Pitch, Yaw, Roll),常用于第一人称视角相机或需要手动控制相机角度的场景。
关键属性:
Vertical Axis (垂直轴): 控制垂直旋转 (Pitch)。
Value: 当前垂直旋转角度。
Input Axis Name: 绑定输入轴,例如 "Mouse Y" 或 "Vertical"。
Horizontal Axis (水平轴): 控制水平旋转 (Yaw)。
Value: 当前水平旋转角度。
Input Axis Name: 绑定输入轴,例如 "Mouse X" 或 "Horizontal"。
代码实践 6:创建一个第一人称视角相机
创建 VCam,取消 Follow 和 Look At 目标。
将 Aim 组件设置为 POV。
配置 Vertical Axis 和 Horizontal Axis 属性:
Input Axis Name 设置为 "Mouse Y" 和 "Mouse X"。
调整 Vertical Axis 和 Horizontal Axis 的 Speed 属性,控制旋转速度。
运行游戏,移动鼠标,你将看到相机以第一人称视角旋转。
3. Group Composer (组构图器)
Group Composer 组件使 VCam 同时注视多个目标 (Target Group),并自动调整相机位置和角度,以确保所有目标都可见。常用于多人游戏或需要同时关注多个角色的场景。
关键组件:
关键属性:
Group (目标组): 指定 Cinemachine Target Group 组件。
Framing Size (构图大小): 定义画面中目标组的大小。
Composition Distance (构图距离): 相机与目标组的距离。
Cinemachine Extensions 组件允许开发者为 Virtual Camera 添加额外的功能和效果。
1. Cinemachine Noise (相机噪声)
Cinemachine Noise 组件为相机添加噪声运动,模拟手持相机抖动、车辆震动等效果。
关键属性:
Profile (噪声配置文件): 选择预定义的噪声配置文件,或自定义噪声曲线。
Amplitude Gain (振幅增益): 控制噪声的强度。
Frequency Gain (频率增益): 控制噪声的频率。
2. Cinemachine Impulse Listener (冲量监听器)
Cinemachine Impulse Listener 组件监听 Cinemachine Impulse Source 发出的冲量事件,并根据冲量事件驱动相机震动效果。常用于爆炸、碰撞等场景的相机反馈。
关键组件:
关键属性:
Channel (通道): 指定监听的冲量通道。
Reaction Settings (反应设置): 配置冲量事件对相机的震动效果,例如震动方向、强度、持续时间等。
3. 自定义 Extensions
Cinemachine 允许开发者编写自定义 Extensions 组件,扩展 VCam 的功能,例如:
限制相机运动范围。
根据游戏状态动态调整相机属性。
实现更复杂的相机行为逻辑。
Cinemachine State-Driven Camera 组件允许根据 Animator 的状态自动切换不同的 Virtual Camera。常用于角色动画驱动相机行为,例如在不同的角色动画状态下使用不同的相机视角。
关键组件:
Animator: 角色动画控制器。
State Driven Camera: 状态驱动相机组件。
配置流程:
创建 State-Driven Camera: 在 Unity 编辑器菜单栏中,选择 Cinemachine -> Create State-Driven Camera。
将 Animator 拖拽到 State-Driven Camera 的 Animated Target 属性。
在 State-Driven Camera 组件中,为每个 Animator 状态添加对应的 Virtual Camera。
配置每个状态的 VCam Blend 属性,定义状态切换时的混合方式。
代码实践 7:使用 State-Driven Camera 实现不同动画状态下的相机切换
创建一个包含不同动画状态的 Animator Controller (例如 Idle, Run, Jump)。
创建 State-Driven Camera,并将 Animator Controller 拖拽到 Animated Target 属性。
创建三个 Virtual Camera (VCam_Idle, VCam_Run, VCam_Jump),分别配置不同的相机视角。
在 State-Driven Camera 组件中,添加三个状态绑定:
State Name: Idle, Virtual Camera: VCam_Idle
State Name: Run, Virtual Camera: VCam_Run
State Name: Jump, Virtual Camera: VCam_Jump
运行游戏,切换角色动画状态,你将看到 State-Driven Camera 根据动画状态自动切换不同的 Virtual Camera。
Cinemachine Blend List Camera 组件允许创建一个 VCam 列表,并按照顺序或循环激活列表中的 VCam,并进行混合。常用于创建预定义的镜头序列,例如过场动画、场景展示等。
关键属性:
合理使用 VCam 数量: 避免在场景中创建过多的 VCam,只创建必要的 VCam,并及时禁用或销毁不再需要的 VCam。
优化 Blend 时间: 适当调整 VCam 切换时的 Blend 时间,避免过长的 Blend 时间影响游戏节奏,也避免过短的 Blend 时间造成镜头突兀。
使用 Collider Extension 避免穿墙: Cinemachine Collider Extension 可以检测相机与场景物体之间的碰撞,并自动调整相机位置,避免相机穿墙。
利用 Profiler 分析相机性能: 使用 Unity Profiler 分析相机系统的性能瓶颈,例如 CPU 占用、GC Alloc 等,并进行针对性优化。
Cinemachine 是 Unity 引擎中一个强大而灵活的相机系统,它极大地简化了复杂相机行为的创建和管理。通过理解 Virtual Camera 和 Cinemachine Brain 的核心概念,掌握各种 Body 和 Aim 组件的使用,以及利用 Extensions 和高级功能,开发者可以轻松地为游戏打造出电影级的镜头语言,提升游戏的视觉表现力和沉浸感。
本章节只是 Cinemachine 的入门指南,Cinemachine 还有许多高级功能和技巧等待你去探索。建议你深入研究官方文档和示例,并在实际项目中不断实践,才能真正掌握 Cinemachine 的精髓,将其应用到你的游戏开发中。
希望这篇文章能够帮助你入门 Cinemachine,开启你的动态相机系统探索之旅!