多目标追踪效果演示:
![](https://www.fantsida.com/assets/files/2024-01-11/1704981344-259614-c52a9ae1be03442a9165c8a73f566d43.gif)
内容很长,分成两帖:
【推荐unity插件】最详细的Cinemachine(虚拟相机系统)案例讲解01
【推荐 unity 插件】最详细的 Cinemachine (虚拟相机系统)案例讲解 02
五、案例3:简单追踪,FollowCam Simple Follow场景
1、场景演示
双击打开FollowCam Simple Follow场景,
![](https://www.fantsida.com/assets/files/2024-01-11/1704977228-454472-e04f62857f3c42b196f887e06eef4100.png)
这是一个追踪一架飞机飞行的摄像机效果,效果如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704977258-647371-ff1b16a6f76f491fbf60d9eb9f3d5016.gif)
画个图
![](https://www.fantsida.com/assets/files/2024-01-11/1704977291-955381-a56cdf382f184bddbefe828ae9350e58.png)
2、组件参数
2.1、CinemachineVirtualCamera:虚拟相机
与CinemachineFreeLook一样,CinemachineVirtualCamera也是继承CinemachineVirtualCameraBase,相对来说,CinemachineVirtualCamera功能更简单一些。
![](https://www.fantsida.com/assets/files/2024-01-11/1704977327-265598-3cd3d6eda2cc40a1a68edf4215bfbaf3.png)
2.1.1、Follow与LookAt:追踪目标
同样也是设置Follow和LookAt参数,设置追踪的目标和朝向的目标。
![](https://www.fantsida.com/assets/files/2024-01-11/1704977359-735487-d896b882b6df45a5a2d2ea24ae6ed0d2.png)
2.1.2、Binding Mode:Body绑定模式
需要重点讲一下Body的绑定模式,
![](https://www.fantsida.com/assets/files/2024-01-11/1704977380-510951-bf322b5a83ff45baa1a0ee664c98ebc3.png)
大家可以打开Transposer场景,
![](https://www.fantsida.com/assets/files/2024-01-11/1704977401-682177-b45925111cc54279b1a646384e00308b.png)
这个场景里帮我们创建了多个Binding Mode的虚拟相机,方便我们进行测试,
![](https://www.fantsida.com/assets/files/2024-01-11/1704977417-116554-c7186f13f3bf4d40ba83835d440df317.png)
下文,我将使用一个更直观的案例进行演示~
1、Lock To Target On Assign 模式(常用)
当相机跟踪目标被设置的时候,把相机设置到目标物体的局部坐标系中,但不跟随目标物体的旋转而移动。
简单讲就是:你动我动,你转我不动
![](https://www.fantsida.com/assets/files/2024-01-11/1704977453-344600-884df1d090ec483c9d15de9f9ae31bcf.gif)
这种适用于视角固定的追踪,为了方便演示应用效果,我导入另外一个Package资源包,该资源包可以在AssetStore免费下载使用,地址:https://assetstore.unity.com/packages/3d/characters/humanoids/character-pack-free-sample-79870
![](https://www.fantsida.com/assets/files/2024-01-11/1704977474-708810-90f6556a7ff0406f8f5d82fbd77bfda8.png)
稍微整一下场景,如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704977494-538671-edee3a8191ab4a09b6f62bdc36b08170.png)
虚拟相机参数设置如下,
![](https://www.fantsida.com/assets/files/2024-01-11/1704977523-638460-dcf4298ee6f146fcb102375b232b4857.png)
我们运行,效果如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704977900-174187-153626b821414108a969f54fefa80d15.gif)
2、Lock To Target With World Up 模式
相机被设置到目标物体的局部坐标系中,但不会跟随目标物体在z轴旋转, 也不会跟随目标物体在x轴倾斜。
简单讲就是:你动我动,你x/z轴转我不动,你y轴转我动。
![](https://www.fantsida.com/assets/files/2024-01-11/1704977934-701644-6991ce527ff24e689b85d4b55846738e.gif)
同样,我们使用小男孩演示下镜头效果,注意主角身上的SimpleSampleCharacterControl组件的移动模式切换成Tank模式,
![](https://www.fantsida.com/assets/files/2024-01-11/1704977654-965731-56746ac2a745437cb19af5cb28d7293f.png)
运行效果如下,适合这种视角始终朝着角色背后的情景,
![](https://www.fantsida.com/assets/files/2024-01-11/1704977995-743379-b7cdf826b3c04501ae5430569cb33cb3.gif)
并且主角x轴旋转时,相机不会因为主角的旋转而移动,
![](https://www.fantsida.com/assets/files/2024-01-11/1704978006-147259-582bff6ca2704f4d98f652fc80bed1ac.gif)
3、Lock To Target No Roll 模式
相机被设置到目标物体的局部坐标系中,但不会跟随目标物体在```z``轴的旋转。
简单讲就是:你动我动,你x/y旋转我动,你z轴转我不动。
![](https://www.fantsida.com/assets/files/2024-01-11/1704978022-680873-60856e6c25194a378548598c48edcca8.gif)
小男孩效果如下,
![](https://www.fantsida.com/assets/files/2024-01-11/1704978161-750001-fa667967892942599d88668c2b9044d5.gif)
这个情景看起来效果与Lock To Target With World Up一样,但如果主角在绕着x轴旋转,相机会跟着移动,如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704978175-248644-f19051375d27495ea0193aec917f4fdd.gif)
4、Lock To Target 模式
这是最容易理解的类型,相机被设置到目标物体的局部坐标系中,将一直跟随目标物体旋转和移动。
简单讲就是:你动我动,你转我动。
![](https://www.fantsida.com/assets/files/2024-01-11/1704978189-966031-c6bc5d8860c14ec7b7bb2349c2aaef33.gif)
小男孩效果如下,
![](https://www.fantsida.com/assets/files/2024-01-11/1704978239-115246-734ddab8d6fc4043bbbe9e03de0cf94e.gif)
跟上面的Lock To Target No Roll 和Lock To Target With World Up 运行效果一样,但如果主角在沿着x、y轴旋转,摄像机会跟着移动,
![](https://www.fantsida.com/assets/files/2024-01-11/1704978248-757630-7a7175fbd5c64d3c92279d59cdecfc65.gif)
其实对于小男孩的这个情景,你使用Lock To Target、Lock To Target No Roll 、Lock To Target With World Up 的运行效果一样,因为这个情景下,小男孩并不会发生x、y轴的旋转。
5、World Space 模式
相机跟目标的偏移以世界坐标来进行计算,并始终保持在初始设置的状态。
简单讲就是:你动我动,你转我不动
诶,听起来跟 Lock To Target On Assign 模式一样,其实不一样,区别就在于Follow Offset参数,Lock To Target On Assign 模式是把 Follow Offset当做目标物体的局部坐标系来计算偏移的,而 World Space 模式,则是以世界坐标系来计算偏移的,
![](https://www.fantsida.com/assets/files/2024-01-11/1704978273-731265-9ab2a30789a04ef784d899fbf501c5e4.png)
![](https://www.fantsida.com/assets/files/2024-01-11/1704978286-514020-8fe77e0b85334fe59a998fa3a1db31f9.gif)
小男孩运行效果如下,
![](https://www.fantsida.com/assets/files/2024-01-11/1704978334-323936-401004d544e04fdd9088de3a34214bd0.gif)
表现效果与Lock To Target On Assign一样,如果在这种应用情景下,我建议使用World Space,因为少了一步转局部坐标的过程。
6、Simple Follow With World Up 模式
使用相机坐标系来计算与目标物体的偏移,不会跟随物体旋转而改变朝向,相机方向始终向上。
比如这个时候的相机坐标系是这样的
![](https://www.fantsida.com/assets/files/2024-01-11/1704978355-547302-313577d0cecc44af857ec9556b6e4a56.png)
把这个坐标系移动到目标物体的中心位置,然后基于这个坐标系做一次Follow Offset偏移,即可得到相机的位置,
![](https://www.fantsida.com/assets/files/2024-01-11/1704978370-916808-fe1b0a49f9c54a199b3c34f18c1d6707.png)
效果如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704978388-835905-313577d0cecc44af857ec9556b6e4a56.png)
小男孩运行效果如下,
![](https://www.fantsida.com/assets/files/2024-01-11/1704978431-114264-a7a8bd75e70a4dd589c10021945309d9.gif)
这一看好像与World Space模式的表现是一样的,其实不一样,我们换个视角观察,我让小男孩一直往左走,先看下World Space的效果,
![](https://www.fantsida.com/assets/files/2024-01-11/1704978441-213482-abeb5d3bbb5447e38f4948aee90d435c.gif)
现在我们看下Simple Follow With World Up 模式下,小男孩一直往左跑是什么效果,如下,小男孩是绕着圈圈走的。之前就有一个策划拿着某款游戏过来问我,为什么主角一直往右跑的时候看起来好像是在转圈圈,我猜那款游戏用的就是Simple Follow With World Up模式,
![](https://www.fantsida.com/assets/files/2024-01-11/1704978458-548802-b3a42e4eb0ab463fbb8bae2eac9949ee.gif)
六、案例4:动画状态驱动自由视角,StateDrivenCamera场景
1、场景演示
双击打开StateDrivenCamera场景,
![](https://www.fantsida.com/assets/files/2024-01-11/1704979783-168230-4f006057a09546018918c56929313729.png)
这是一个根据主角动画状态切换摄像机机位效果,默认情况下是一个第三人称自由视角,当主角跑起来的时候,会切换到一个固定视角的虚拟相机机位,我们运行,在Scene窗口看下这个切换过程,
![](https://www.fantsida.com/assets/files/2024-01-11/1704979809-907957-158dca6122ae4253b5489ac6866e1bfc.gif)
画个图
![](https://www.fantsida.com/assets/files/2024-01-11/1704979894-695062-ecd7d1c3cb624f88a19d90d36dadcf01.png)
2、组件参数
这个案例我们只需要讲一下CinemachineStateDrivenCamera组件,其它的上文已经讲过了。
2.1、CinemachineStateDrivenCamera:状态驱动虚拟相机
2.1.1、父节点:CinemachineStateDrivenCamera
在父节点上挂CinemachineStateDrivenCamera组件,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980136-335207-aa9d14ed7dd742e5b1afbe7d23c5851d.png)
2.1.2、子节点:多个虚拟相机
子节点可以放多个虚拟相机,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980152-464365-b59824c67ad646d985b909326472ebf4.png)
2.1.3、设置Animated Target
因为我们需要根据动画状态来切换不同的虚拟相机,所以需要给CinemachineStateDrivenCamera组件指定Animated Target,把主角的Animator对象赋值给它,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980169-846548-c97e95997f074f83872ee81a7d210ed4.png)
2.1.4、设置State
我们先看下主角的动画状态机,很简单,只有Locomotion和Sprint两个动画状态,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980180-300772-8add5406fcf440e687498a6fca31971a.png)
我们在CinemachineStateDrivenCamera组件上分别给这两个动画状态添加要激活的虚拟相机,如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704980204-69419-c1c657d0685c4c8ea79a8c49349f49ee.png)
七、案例5:分镜/切镜,ClearShot场景
ClearShot翻译过来是清晰的镜头的意思,就是从多个相机镜头中选择一个画面质量最好的镜头,切换过去,表现上就像分镜的效果。
啥是分镜呢?首先看下百科的概念,
分镜(Storyboard) 又叫故事板。是指电影、动画、电视剧、广告、音乐录像带等各种影像媒体,在实际拍摄或绘制之前,以图表的方式来说明影像的构成,将连续画面以一次运镜为单位作分解,并且标注运镜方式、时间长度、对白、特效等。根据媒体不同划分成不同分镜。常见的有影片分镜,漫画分镜。影片分镜用以解说一个场景将如何构成,人物以多大的比例收入镜头成为构图、做出什么动作,摄影机要从哪个角度切入或带出、摄影机本身怎么移动、录映多少时间等。
喜欢看漫画的同学应该不陌生,一个场景中我们架设多个虚拟相机机位,为了做出最好的画面表现,我们需要进行镜头切换,比如下面的漫画,一个格子就像是一个机位拍摄的画面,镜头角度、位置等,什么时候去切换镜头,这些对应到Cinemachine中,就是ClearShot要做的事情,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980218-524703-603814a8acf249478102a8b8c7d48776.png)
Cinemachine给我们做了三个场景,我们先运行看下效果。
![](https://www.fantsida.com/assets/files/2024-01-11/1704980235-278519-d1569c1de9eb40c68e4a0bdfc05b8fb8.png)
1、场景演示
1.1、ClearShot场景
先双击打开ClearShot场景,运行效果如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704980265-624413-ac7f812e5d18490a9fe8ca70a6da85eb.gif)
场景中架了三个虚拟相机,如下,根据主角是否被遮挡进行最优切换,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980299-797095-c5e53a80604f4a1f83f65561b2b853bf.png)
![](https://www.fantsida.com/assets/files/2024-01-11/1704980299-938033-d64ac240078340eab603cea043f0659a.png)
虚拟相机父节点是一个CinemachineClearShot,下文会介绍这个组件的参数,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980326-438266-4eca04609474447795c0be67026bbd83.png)
画个图
![](https://www.fantsida.com/assets/files/2024-01-11/1704980351-571612-778f6ee3b0e1420280979fa8aa9c00d7.png)
1.2、ClearShot closest场景
先双击打开ClearShot closest场景,运行效果如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704980380-236370-76c95194a1d4442b87a07482ef6a64b9.gif)
场景中架了六个虚拟相机,如下,根据与主角的距离进行最优切换,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980398-747951-6d5c3a3bf75544d08331278f8a11adde.png)
其中CinemachineClearShot子节点虚拟相机中嵌了一个CinemachineBlendListCamera,下文会介绍这个组件的参数,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980414-429758-95a569ddf09247eb8a6a9e7365e3a5c2.png)
按照惯例画个图
![](https://www.fantsida.com/assets/files/2024-01-11/1704980429-227272-4b938c9fdc0142d4907304118fb31cd1.png)
1.2、ClearShot character场景
双击打开ClearShot character场景,运行效果如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704980441-343173-35f91ac5c1ed4379b61d28895db98c2e.gif)
场景中架设了5个虚拟相机
![](https://www.fantsida.com/assets/files/2024-01-11/1704980476-858763-0f2d3f319dd1442c9c01ef6e3e1479ff.png)
其中用到了虚拟相机触发器:CinemachineTriggerAction,用于检测主角是否进入触发器区域,然后进行虚拟相机的切换,下文会介绍这个组件的参数,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980502-21961-341c9aa79ed24cc6a52f402b985080cc.png)
画个图
![](https://www.fantsida.com/assets/files/2024-01-11/1704980511-63337-2caa41a5721440368b32d146e8797b9c.png)
2、组件参数
2.1、CinemachineClearShot:自动选择/切换最适合的摄像头
CinemachineClearShot会根据被观察目标的最好画面质量,从子节点中选择一个最合适的虚拟相机。
至于它是根据什么做出最优选择的,大家可以查看CinemachineClearShot.cs源码的ChooseCurrentCamera方法,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980557-692574-5b8f8226869848999fe919bfcfbfe710.png)
主要是根据虚拟相机的ShowQuality和Priority两个参数进行评估的,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980571-935169-9df3d41b9cfd41fe8ae004e78af6eb19.png)
![](https://www.fantsida.com/assets/files/2024-01-11/1704980571-960617-49cb80221ec9456c802f2f6e057e8340.png)
而ShowQuality又是根据相机是否被遮挡、与目标的距离等参数进行评估的。
如果我们想手动触发虚拟相机的切换,可以通过代码设置虚拟相机的Priority参数提高优先级。
这里我们主要讲一下如何设置CinemachineClearShot组件的参数。
我们只需要在子节点中添加虚拟相机,就会自动在下面的列表中显示出来,我们设置一下Priority优先级参数即可,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980592-496403-c1c657d0685c4c8ea79a8c49349f49ee.png)
另外,CinemachineClearShot本身也有Follow和LookAt参数,如果子节点的虚拟相机没有设置Follow和LookAt,则会以CinemachineClearShot的为准,否则以子节点虚拟相机的Follow和LookAt为准,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980659-184972-f365494cd5924649961624a1d1bff3ed.png)
2.2、CinemachineBlendListCamera:虚拟相机过渡/混合器
在ClearShot closest场景中用到了CinemachineBlendListCamera,我使用另一个专门的场景来讲解,
双击打开BlendListCamera,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980833-81296-d0068a4d4aec4290937176692564c61f.png)
场景中放了两个CinemachineBlendListCamera,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980843-106296-2f901ef341a64d0ba24bada64736f0df.png)
我们把默认的虚拟相机禁用,把第一个CinemachineBlendListCamera激活,可以看到它底下有两个虚拟相机,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980852-34952-0e28e840cd7b43618f45ac14404d811f.png)
CinemachineBlendListCamera做的事情就是按照我们设定的顺序进行虚拟相机的过渡,注意,这里会按照我们排的顺序进行过渡,而不会进行像ClearShot那样进行画面质量评估,下面这个设置的意思就是先在CM vcam A虚拟相机状态停留0.5秒,然后用2秒时间过渡到CM vcam B,过渡的缓动曲线使用Ease In Out,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980869-655509-ef9e8aa2c24a45a3a59a680cd0bd60f4.png)
常用的缓动曲线如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704980879-421749-0594b6af92f34732a451e244409d79c7.png)
我们调整一下两个虚拟相机的位置,如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704980892-427698-7853b473439c490896132c39118721b5.png)
现在我们运行看看效果,可以看到相机从CM vcam A过渡到了CM vcam B,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980906-444973-95afe34994214b05859f4df2ae4e039a.gif)
我们还可以让它从CM vcam B回到CM vcam A,我们添加过渡设置,如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704980922-379391-99507637db7f451fbd730cac899966ab.png)
重新运行,效果如下,可以看到,相机最后又过渡回到了CM vcam A,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980937-906035-dc49d5b33a18488ca0fca3fbce2fa4d7.gif)
如果我们想要让这个顺序循环执行,可以勾选Loop
![](https://www.fantsida.com/assets/files/2024-01-11/1704980956-983285-f091c755534b4a97b5a835503303f93e.png)
2.3、CinemachineTriggerAction:虚拟相机触发器
插件中的Trigger volumes场景可以针对触发器进行测试,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980969-973869-de35796129cf411888b6f441bd9866f6.png)
可以用它来实现虚拟相机的镜头切换,
![](https://www.fantsida.com/assets/files/2024-01-11/1704980979-744145-df8015f6fd6942f1816f72e4f3a8b51b.gif)
也可以用来实现机关触发(比如执行TimeLine)
![](https://www.fantsida.com/assets/files/2024-01-11/1704980988-305900-bb5d5f84202f4d3d8d9433554cacc2e3.gif)
插件中还有一个Anywhere Door(任意门)场景,用的就是CinemachineTriggerAction触发器来实现两个世界的无缝穿越的,挺有意思的,效果如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704981004-570223-17cd61c132014b20828ad453a79eb1ea.gif)
下面讲一下CinemachineTriggerAction组件的参数设置。
2.3.1、碰撞体勾选Is Trigger
我们可以打开CinemachineTriggerAction.cs查看源码,里面其实就是使用OnTriggerXXX来检测碰撞,然后执行对应的响应方法,
![](https://www.fantsida.com/assets/files/2024-01-11/1704981112-836685-4da10b3b07d647aa87b4d9d8299a49e5.png)
注意使用CinemachineTriggerAction的物体上,需要带Collider,并且勾选Is Trigger,如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704981128-391622-ef42ad2886ee48f6ae1587c112dc2e7d.png)
2.3.2、设置过滤
我们可以设定Layer Mask、With Tag和Without Tag进行过滤,
![](https://www.fantsida.com/assets/files/2024-01-11/1704981145-61649-0f5f7add4d6b48fe9c1f104f6b3006a3.png)
只有通过过滤器的检测才能触发逻辑,
![](https://www.fantsida.com/assets/files/2024-01-11/1704981154-780901-65a96a8b2c074419ae0a6801f19da7e5.png)
2.3.3、设置Skip First
Skip First可以用来跳过前面N此的触发,比如第一次进入时不想触发逻辑,则可以把Skip First设置为1,如果想要每次都触发,则把Skip First设置为0,并勾选Repeating,
![](https://www.fantsida.com/assets/files/2024-01-11/1704981166-885648-e016420cd314492bb1792ac1c17ad8a0.png)
Skip First逻辑如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704981178-860446-3e18c1cb9c244a8bba6d4d53d29628d0.png)
2.3.4、设置On Object Enter响应
进入触发器,触发响应逻辑,我们可以设置要执行的行为,
![](https://www.fantsida.com/assets/files/2024-01-11/1704981211-552820-67b0e82cb3ed494f9de551351d566af4.png)
支持的行为如下
![](https://www.fantsida.com/assets/files/2024-01-11/1704981222-302914-f54c955ae47341d88c46d3700cd3eb53.png)
同理,物体离开触发器会触发On Object Exit,我们也可以设置对应的响应行为,
![](https://www.fantsida.com/assets/files/2024-01-11/1704981243-721381-efebf80218ee4d2195f613e98042b6fd.png)
响应行为 | 说明 |
Custom | 自定义,使用组件里的Event()自定义触发函数 |
Priority Boost | 增加目标虚拟相机的优先级,并把虚拟相机推入优先队列顶部 |
Activate | 激活虚拟相机,并把虚拟相机推入优先队列顶部 |
Deactive | 禁用目标物体,即执行SetActive(false) |
Enable | 激活目标组件,即设置组件的 enabled 为 true |
Disable | 禁用目标组件,即设置组件的 enabled 为 false |
Play | 播放Timeline |
Stop | 停止Timeline |
作者:向宇
来源:https://xiangyu.blog.csdn.net/article/details/134374639