mcpField
U
unity-cinemachine

unity-cinemachine

github.com/nice-wolf-studio开发4071 次安装6 周前更新
代码仓库

关于 unity-cinemachine

unity-cinemachine 是基于 Unity 6.3 LTS 和 Cinemachine 3.1 的相机系统技能,介绍可组合的虚拟相机组件与设置模式。适用于需要配置跟随、轨道、镜头切换、震动或状态驱动相机的 Unity 开发者。

主要功能

  1. 01配置跟随、第三人称与轨道相机
  2. 02使用组合器设置画面构图与瞄准
  3. 03通过优先级和混合切换相机
  4. 04按 Animator 状态驱动相机
  5. 05设置镜头震动、目标组和输入

适用场景

  1. 01为玩家角色设置跟随或第三人称镜头
  2. 02在游戏状态变化时切换镜头
  3. 03沿样条路径制作过场镜头
  4. 04为爆炸事件添加相机震动

MCP 相关

README 未说明其与 MCP 的关系。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/nice-wolf-studio/unity-claude-skills --skill unity-cinemachine

安装后在 Claude Code 中输入/unity-cinemachine确认已加载。

附带文件references/cinemachine-api.md

详细介绍

Unity Cinemachine(摄像机系统)

基于 Unity 6.3 LTS——Cinemachine 3.1 包 重要提示:Cinemachine 3.x 将 CinemachineVirtualCamera 重命名为 CinemachineCamera

核心概念

Cinemachine 会在运行时以程序化方式控制 Unity 摄像机。你可以通过组合可复用组件来构建摄像机行为,而不必编写自定义摄像机脚本。

架构
  1. CinemachineBrain——添加到 Main Camera;根据优先级最高的活动 CinemachineCamera 驱动 Unity Camera
  2. CinemachineCamera——轻量级虚拟摄像机,用于描述所需的位置、旋转和镜头(取代 v2 中的 CinemachineVirtualCamera)
  3. 优先级系统——启用状态的 CinemachineCamera 中,优先级最高者生效
  4. 管线阶段——Body(位置)、Aim(旋转)和 Noise 阶段共同计算最终摄像机状态
命名空间
using Unity.Cinemachine;  // Cinemachine 3.x (NOT "using Cinemachine;")
最简设置
  1. 将 CinemachineBrain 添加到 Main Camera
  2. 创建包含 CinemachineCamera 的 GameObject
  3. 设置 Follow 目标,并可选择设置 LookAt 目标
  4. 根据需要添加 Body/Aim 组件
using UnityEngine;
using Unity.Cinemachine;

public class CameraSetup : MonoBehaviour
{
    [SerializeField] Transform playerTransform;

    void Start()
    {
        var vcam = gameObject.AddComponent<CinemachineCamera>();
        vcam.Follow = playerTransform;
        vcam.LookAt = playerTransform;
        vcam.Priority.Value = 10;
    }
}

摄像机设置模式

基础跟随摄像机

使用 CinemachineCamera 和 CinemachineFollow。将 Follow 目标设置为玩家。

// CinemachineFollow provides a simple offset-based follow
var follow = gameObject.AddComponent<CinemachineFollow>();
follow.FollowOffset = new Vector3(0f, 5f, -10f);
follow.Damping = new Vector3(1f, 1f, 1f);
第三人称摄像机

使用 CinemachineThirdPersonFollow 创建支持碰撞检测的第三人称摄像机。

属性描述
ShoulderOffset跟随目标在局部空间中的偏移量
CameraDistance与肩部位置的距离
CameraSide0=左侧,0.5=中间,1=右侧
CameraRadius碰撞检测半径
DampingIntoCollision因碰撞而靠近时的阻尼
DampingFromCollision碰撞后返回时的阻尼
环绕 / 自由视角摄像机

使用 CinemachineOrbitalFollow 创建由玩家输入控制、围绕目标旋转的摄像机。在 Cinemachine 3.x 中,FreeLook 不再是独立组件——请使用 CinemachineCamera + CinemachineOrbitalFollow + CinemachineInputAxisController。

var orbital = gameObject.AddComponent<CinemachineOrbitalFollow>();
orbital.OrbitStyle = CinemachineOrbitalFollow.OrbitStyles.ThreeRing;
orbital.Radius = 5f;
// Add CinemachineInputAxisController to wire Input System actions
gameObject.AddComponent<CinemachineInputAxisController>();
2D 摄像机

使用带有死区和阻尼的 CinemachinePositionComposer,实现平滑的 2D 跟踪。

var composer = gameObject.AddComponent<CinemachinePositionComposer>();
composer.Damping = new Vector3(1f, 0.5f, 0f);
composer.DeadZoneWidth = 0.1f;
composer.DeadZoneHeight = 0.1f;
composer.ScreenPosition = new Vector2(0.5f, 0.5f);
composer.CameraDistance = 10f;  // orthographic distance

Body 组件(位置跟踪)

Body 组件控制摄像机位置如何跟随目标。每个 CinemachineCamera 添加一个 Body 组件。

组件使用场景
CinemachineFollow带阻尼的简单偏移跟随
CinemachineThirdPersonFollow支持碰撞检测的第三人称视角
CinemachineOrbitalFollow围绕目标旋转(FreeLook 风格)
CinemachinePositionComposer使用死区进行屏幕空间构图
CinemachineHardLockToTarget将位置精确锁定到目标(无阻尼)
CinemachineTrackedDolly沿 SplineContainer 路径跟随
CinemachineTrackedDolly

使摄像机沿 SplineContainer 路径移动。适用于过场动画轨道、赛车游戏或横向卷轴游戏。

var dolly = gameObject.AddComponent<CinemachineTrackedDolly>();
dolly.SplinePath = splineContainer;
dolly.AutoDolly.Enabled = true;      // auto-position along spline
dolly.CameraPosition = 0.5f;        // 0..1 position on spline
dolly.Damping = new Vector3(1f, 1f, 1f);

Aim 组件(旋转)

Aim 组件控制摄像机如何朝向 LookAt 目标旋转。每个 CinemachineCamera 添加一个 Aim 组件。

组件使用场景
CinemachineRotationComposer使用死区和阻尼进行柔和区域瞄准
CinemachineHardLookAt始终精确面向目标(无阻尼)
CinemachinePanTilt通过输入轴手动控制水平转动/俯仰(第一人称)
CinemachineGroupFraming自动为 CinemachineTargetGroup 构图
CinemachinePanTilt

适用于第一人称或手动瞄准的摄像机:

var panTilt = gameObject.AddComponent<CinemachinePanTilt>();
panTilt.TiltAxis.Range = new Vector2(-70f, 70f); // clamp vertical look

摄像机混合

CinemachineBrain 会自动处理平滑过渡。

混合样式
样式描述
Cut立即切换
EaseInOut平滑加速/减速(最常用)
EaseIn / EaseOut单向缓动
HardIn / HardOut硬性起始或结束
Linear匀速
Custom用户定义的 AnimationCurve
切换摄像机
// Priority-based: Brain blends to highest priority
closeUpCamera.Priority.Value = 20;
wideCamera.Priority.Value = 10;

// Or enable/disable GameObjects -- Brain blends automatically
closeUpCamera.gameObject.SetActive(true);
wideCamera.gameObject.SetActive(false);

自定义每对摄像机之间的混合时,请创建 CinemachineBlenderSettings 资源并将其分配给 CinemachineBrain.CustomBlends。

状态驱动相机

CinemachineStateDrivenCamera 将 Animator 状态映射到子 CinemachineCamera。Animator 发生状态转换时,相应的相机会自动激活。

设置
  1. 创建一个带有 CinemachineStateDrivenCamera 的父 GameObject
  2. 添加子 GameObject,每个子对象都带有 CinemachineCamera
  3. 指定驱动状态转换的 Animator
  4. 在 Inspector 中将每个 Animator 状态映射到一个子相机
使用场景
  • 战斗——进入 Combat Animator 状态时切换到越肩视角相机
  • 载具——驾驶和倒车时使用不同的相机
  • 潜行——处于 Crouch 状态时使用更宽的 FOV
  • 对话——对话状态时使用特写相机

相机震动(Impulse 系统)

组件作用
CinemachineImpulseSource在某个位置生成冲击信号
CinemachineImpulseListener在 CinemachineCamera 上接收冲击信号
生成冲击信号
using UnityEngine;
using Unity.Cinemachine;

public class ExplosionShake : MonoBehaviour
{
    [SerializeField] CinemachineImpulseSource impulseSource;

    public void Explode()
    {
        impulseSource.GenerateImpulse();           // default velocity
        impulseSource.GenerateImpulse(3f);         // scaled intensity
        impulseSource.GenerateImpulse(Vector3.up); // directional
    }
}
Listener 属性
属性描述
Gain冲击信号倍率(0=忽略,1=完整)
Use2DDistance使用 2D 距离计算衰减
ChannelMask要接收的冲击通道

噪声(程序化震动)

CinemachineBasicMultiChannelPerlin 会添加持续的程序化噪声(手持拍摄感、待机呼吸效果)。

配置文件使用场景
6D Shake完整的位置和旋转震动
Handheld_normal_mild轻微手持拍摄效果
Handheld_normal_strong明显手持拍摄效果

CinemachineTargetGroup

使用单个相机将多个目标纳入画面。

var group = gameObject.AddComponent<CinemachineTargetGroup>();
group.Targets = new CinemachineTargetGroup.Target[]
{
    new() { Object = player.transform, Weight = 1f, Radius = 1f },
    new() { Object = enemy.transform, Weight = 0.5f, Radius = 1f }
};
// Add CinemachineGroupFraming to the camera for auto-framing

输入处理

Cinemachine 3.x 使用 InputAxis 接收相机控制输入,并与 Unity Input System 包集成。

CinemachineInputAxisController

将此组件与 CinemachineOrbitalFollow 或 CinemachinePanTilt 一同添加。它会自动发现同级组件上的轴,并连接 Input System 操作。

自定义输入提供程序
using UnityEngine;
using Unity.Cinemachine;
using System.Collections.Generic;

public class CustomCameraInput : MonoBehaviour, IInputAxisOwner
{
    [SerializeField] InputAxis horizontalAxis;
    [SerializeField] InputAxis verticalAxis;

    public void GetInputAxes(List<IInputAxisOwner.AxisDescriptor> axes)
    {
        axes.Add(new IInputAxisOwner.AxisDescriptor
        {
            DrivenAxis = () => ref horizontalAxis,
            Name = "Horizontal"
        });
        axes.Add(new IInputAxisOwner.AxisDescriptor
        {
            DrivenAxis = () => ref verticalAxis,
            Name = "Vertical"
        });
    }
}

常见模式

带碰撞规避的第三人称视角
var vcam = gameObject.AddComponent<CinemachineCamera>();
vcam.Follow = player; vcam.LookAt = player;

var tpFollow = gameObject.AddComponent<CinemachineThirdPersonFollow>();
tpFollow.ShoulderOffset = new Vector3(0.5f, 0f, 0f);
tpFollow.CameraDistance = 4f;
tpFollow.CameraSide = 1f;
tpFollow.CameraRadius = 0.2f;

var rotComposer = gameObject.AddComponent<CinemachineRotationComposer>();
rotComposer.Damping = new Vector2(0.5f, 0.5f);
在触发区域切换相机
using UnityEngine;
using Unity.Cinemachine;

public class CameraTriggerZone : MonoBehaviour
{
    [SerializeField] CinemachineCamera zoneCamera;
    [SerializeField] int activePriority = 20;
    [SerializeField] int inactivePriority = 0;

    void Start() => zoneCamera.Priority.Value = inactivePriority;

    void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
            zoneCamera.Priority.Value = activePriority;
    }

    void OnTriggerExit(Collider other)
    {
        if (other.CompareTag("Player"))
            zoneCamera.Priority.Value = inactivePriority;
    }
}
过场动画相机序列
using UnityEngine;
using Unity.Cinemachine;
using System.Collections;

public class CutsceneSequence : MonoBehaviour
{
    [SerializeField] CinemachineCamera[] cameras;
    [SerializeField] float[] durations;

    public IEnumerator PlayCutscene()
    {
        for (int i = 0; i < cameras.Length; i++)
        {
            foreach (var cam in cameras) cam.Priority.Value = 0;
            cameras[i].Priority.Value = 100;
            yield return new WaitForSeconds(durations[i]);
        }
    }
}
分屏设置
// Each player: separate Camera + CinemachineBrain + CinemachineCamera
// Camera 1: Viewport Rect (0, 0, 0.5, 1) -- left half
// Camera 2: Viewport Rect (0.5, 0, 0.5, 1) -- right half
brain1.ChannelMask = OutputChannels.Channel01;
brain2.ChannelMask = OutputChannels.Channel02;
player1Cam.OutputChannel = OutputChannels.Channel01;
player2Cam.OutputChannel = OutputChannels.Channel02;
爆炸时的相机震动
[SerializeField] CinemachineImpulseSource impulseSource;
[SerializeField] float shakeForce = 5f;

public void Detonate()
{
    impulseSource.GenerateImpulse(shakeForce);
}

反模式

反模式应改为
使用 CinemachineVirtualCamera(v2)CinemachineCamera
使用 using Cinemachine; 命名空间using Unity.Cinemachine;
直接修改 Camera.main.transform修改 CinemachineCamera;Brain 会驱动 Camera
所有相机优先级相同设置不同的优先级
Main Camera 上没有 CinemachineBrain始终添加 CinemachineBrain
使用手动 Lerp 进行相机过渡使用优先级切换;Brain 会处理混合
使用 CinemachineTransposer(v2)CinemachineFollow
使用 CinemachineComposer(v2)CinemachineRotationComposer
使用 CinemachineFramingTransposer(v2)CinemachinePositionComposer

API 速查

类用途
CinemachineCamera虚拟摄像机(原为 CinemachineVirtualCamera)
CinemachineBrain根据当前激活的虚拟摄像机驱动 Unity Camera
CinemachineFollow带偏移的机身(原为 CinemachineTransposer)
CinemachineThirdPersonFollow支持碰撞检测的第三人称机身
CinemachineOrbitalFollow用于 FreeLook 的环绕机身
CinemachinePositionComposer屏幕空间取景(原为 FramingTransposer)
CinemachineTrackedDolly沿 Spline 路径跟随
CinemachineRotationComposer软区瞄准(原为 CinemachineComposer)
CinemachineHardLookAt将瞄准方向锁定到目标
CinemachinePanTilt手动平移/倾斜瞄准
CinemachineGroupFraming自动为目标组取景
CinemachineImpulseSource生成摄像机震动
CinemachineImpulseListener在摄像机上接收震动
CinemachineBasicMultiChannelPerlin连续程序化噪声
CinemachineStateDrivenCamera将 Animator 状态映射到摄像机
CinemachineTargetGroup将多个目标编为一组
CinemachineBlenderSettings自定义混合定义
CinemachineInputAxisController将 Input System 连接到轴
ICinemachineCamera虚拟摄像机接口

v2 到 v3 迁移参考

Cinemachine 2.xCinemachine 3.x
CinemachineVirtualCameraCinemachineCamera
CinemachineFreeLookCinemachineCamera + CinemachineOrbitalFollow
CinemachineTransposerCinemachineFollow
CinemachineComposerCinemachineRotationComposer
CinemachineFramingTransposerCinemachinePositionComposer
CinemachinePOVCinemachinePanTilt
CinemachineGroupComposerCinemachineGroupFraming
using Cinemachineusing Unity.Cinemachine
m_Follow / m_LookAtFollow / LookAt
m_PriorityPriority.Value

相关技能

  • 有关动画状态机,请参阅 unity-animation
  • 有关渲染/摄像机,请参阅 unity-graphics
  • 有关 Timeline,请参阅 unity-animation references/timeline.md
  • 有关输入系统集成,请参阅 unity-input

其他资源

评论

支持 Markdown