欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 游戏 > CinemachineBrain的属性简介

CinemachineBrain的属性简介

2024/10/24 15:22:11 来源:https://blog.csdn.net/weixin_45776473/article/details/140337226  浏览:    关键词:CinemachineBrain的属性简介

CinemachineBrain的属性简介

CinemachineBrain是Unity Cinemachine的核心组件,它和Camera组件挂载在一起,监控场景中所有的virtual camera。CinemachineBrain在inspector中暴露的属性如下:

CinemachineBrain的属性简介1

Live Camera和Live Blend分别表示当前active的virtual camera以及blend的进度(如果有的话)。相关的代码可以在CinemachineBrainEditor找到:

[CustomEditor(typeof(CinemachineBrain))]
[CanEditMultipleObjects]
class CinemachineBrainEditor : UnityEditor.Editor
{CinemachineBrain Target => target as CinemachineBrain;public override VisualElement CreateInspectorGUI(){var ux = new VisualElement();ux.ContinuousUpdate(() =>{if (target == null || liveCamera == null)return;liveCamera.value = Target.ActiveVirtualCamera as CinemachineVirtualCameraBase;liveBlend.value = Target.ActiveBlend != null ? Target.ActiveBlend.Description : string.Empty;});return ux;}
}

可以看到引用的是CinemachineBrain的ActiveVirtualCamera和ActiveBlend字段。

public class CinemachineBrain : MonoBehaviour, ICameraOverrideStack, ICinemachineMixer
{/// <summary>/// Get the current active virtual camera./// </summary>public ICinemachineCamera ActiveVirtualCamera => CinemachineCore.SoloCamera ?? m_BlendManager.ActiveVirtualCamera;/// <summary>/// Get the current blend in progress.  Returns null if none./// It is also possible to set the current blend, but this is not a recommended usage/// unless it is to set the active blend to null, which will force completion of the blend./// </summary>public CinemachineBlend ActiveBlend {get => m_BlendManager.ActiveBlend;set => m_BlendManager.ActiveBlend = value;}
}

ActiveBlend.Description描述了从当前virtual camera切换到下一个virtual camera的进度。

CinemachineBrain的属性简介2

Show Debug Text字段,如果勾上,就会在Game窗口中显示当前live的virtual camera信息。

CinemachineBrain的属性简介3

Show Camera Frustum字段,如果勾上,就会在Scene窗口显示当前live的virtual camera视锥体,不用选中任何GameObject。

CinemachineBrain的属性简介4

Ignore Time Scale字段,勾上的话会使Cinemachine实时响应用户输入和阻尼,说白了就是不受time scale的影响。这里同样可以查看相关代码:

float GetEffectiveDeltaTime(bool fixedDelta)
{if (CinemachineCore.UniformDeltaTimeOverride >= 0)return CinemachineCore.UniformDeltaTimeOverride;if (CinemachineCore.SoloCamera != null)return Time.unscaledDeltaTime;if (!Application.isPlaying)return m_BlendManager.GetDeltaTimeOverride();if (IgnoreTimeScale)return fixedDelta ? Time.fixedDeltaTime : Time.unscaledDeltaTime;return fixedDelta ? Time.fixedDeltaTime : Time.deltaTime;
}

fixedDelta参数表示是否要使用Time.fixedDeltaTime,如果为false,在勾选的情况下,就会选择Time.unscaledDeltaTime,而不是Time.deltaTime

World Up Override字段,指定的transform的Y轴定义了Cinemachine在世界空间的up向量。如果为空,则默认为(0,1,0)。这点在代码中同样有体现:

/// <summary>Get the default world up for the virtual cameras.</summary>
public Vector3 DefaultWorldUp => (WorldUpOverride != null) ? WorldUpOverride.transform.up : Vector3.up;

Channel Mask字段主要用于分屏效果的实现。这种情况下,场景中会有多个camera,也就会有多个CinemachineBrain组件的存在。为了确定某一个virtual camera是属于哪个CinemachineBrain管理,就需要用到Channel Mask字段。相关的判断代码如下:

/// <summary>Returns true if camera is on a channel that is handles by this Brain.</summary>
/// <param name="vcam">The camera to check</param>
/// <returns></returns>
public bool IsValidChannel(CinemachineVirtualCameraBase vcam) => vcam != null && ((uint)vcam.OutputChannel & (uint)ChannelMask) != 0;

不过在大部分情况下,只需要一个屏幕,场景中也就只有一个CinemachineBrain,此时Channel Mask字段保持默认值即可,默认值为-1,这样转为uint就是0xffffffff了。

/// <summary>The CinemachineBrain will find the highest-priority CinemachineCamera that outputs 
/// to any of the channels selected.  CinemachineCameras that do not output to one of these 
/// channels will be ignored.  Use this in situations where multiple CinemachineBrains are 
/// needed (for example, Split-screen).</summary>
[Tooltip("The CinemachineBrain will find the highest-priority CinemachineCamera that outputs to "+ "any of the channels selected.  CinemachineCameras that do not output to one of these "+ "channels will be ignored.  Use this in situations where multiple CinemachineBrains are "+ "needed (for example, Split-screen).")]
public OutputChannels ChannelMask = (OutputChannels)(-1);  // default is Everything

Update Method字段表示virtual camera更新position和rotation的时机,有以下几种。

Update Method
Fixed Update和物理模块保持同步,在FixedUpdate时更新
Late Update在MonoBehaviour的LateUpdate时更新
Smart Update根据virtual camera当前的更新情况更新,推荐设置
Manual Updatevirtual camera不会自动更新,需要手动调用brain.ManualUpdate()

Smart Update具体是如何实现的呢?通过搜索UpdateMethods.SmartUpdate,可以查到相关的代码集中在ManualUpdateDoFixedUpdate这两个函数上。容易猜到,触发这两个函数的时机,一个是在LateUpdate,一个是在FixedUpdate期间:

void LateUpdate()
{if (UpdateMethod != UpdateMethods.ManualUpdate)ManualUpdate();
}
// Instead of FixedUpdate() we have this, to ensure that it happens
// after all physics updates have taken place
IEnumerator AfterPhysics()
{while (true){// FixedUpdate can be called multiple times per frameyield return m_WaitForFixedUpdate;DoFixedUpdate();}
}

由Unity的脚本执行顺序[3]可知,DoFixedUpdate会在Unity所有的FixedUpdate执行之后立刻执行。

决定在哪个Update阶段进行更新的逻辑,位于UpdateTracker.OnUpdate这个函数:

public void OnUpdate(int currentFrame, UpdateClock currentClock, Matrix4x4 pos)
{if (lastPos == pos)return;if (currentClock == UpdateClock.Late)++numWindowLateUpdateMoves;else if (lastFrameUpdated != currentFrame) // only count 1 per rendered frame++numWindowFixedUpdateMoves;lastPos = pos;UpdateClock choice;if (numWindowFixedUpdateMoves > 3 && numWindowLateUpdateMoves < numWindowFixedUpdateMoves / 3)choice = UpdateClock.Fixed;elsechoice =  UpdateClock.Late;if (numWindows == 0)PreferredUpdate = choice;if (windowStart + kWindowSize <= currentFrame){
#if DEBUG_LOG_NAMEDebug.Log(name + ": Window " + numWindows + ": Late=" + numWindowLateUpdateMoves + ", Fixed=" + numWindowFixedUpdateMoves);
#endifPreferredUpdate = choice;++numWindows;windowStart = currentFrame;numWindowLateUpdateMoves = (PreferredUpdate == UpdateClock.Late) ? 1 : 0;numWindowFixedUpdateMoves = (PreferredUpdate == UpdateClock.Fixed) ? 1 : 0;}
}

其主要逻辑,就是采样前一段时间kWindowSize = 30帧内,virtual camera的target position在LateUpdate和FixedUpdate时发生变化的次数,如果FixedUpdate次数是LateUpdate次数的三倍以上,那就选择在FixedUpdate更新virtual camera,否则选择LateUpdate。

Blend Update Method表示混合并更新主相机的时机,推荐使用Late Update。

Lens Mode Override表示是否允许virtual camera修改主相机的模式(透视,正交,物理)。如果不勾上,那么在virtual camera的设置里修改是不生效的:

CinemachineBrain的属性简介5

Default Blend表示两个virtual camera混合的方式,Unity默认提供了若干种,当然也可以自定义。

btw,在旧版本中CinemachineBrain监听的事件也在CinemachineBrain组件中,而新版本(3.1.0)这部分已经剥离出来,单独作为Cinemachine Brain Event组件存在了。现在支持六种事件:

CinemachineBrain的属性简介6

Reference

[1] Cinemachine Brain component

[2] Cinemachine(一)VirtualCamera和Brain的简单介绍

[3] Order of execution for event functions

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com