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 frame
        yield 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;
    else
        choice =  UpdateClock.Late;
    if (numWindows == 0)
        PreferredUpdate = choice;

    if (windowStart + kWindowSize <= currentFrame)
    {
#if DEBUG_LOG_NAME
        Debug.Log(name + ": Window " + numWindows + ": Late=" + numWindowLateUpdateMoves + ", Fixed=" + numWindowFixedUpdateMoves);
#endif
        PreferredUpdate = 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/791600.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

人工智能算法工程师(中级)课程6-sklearn机器学习之聚类问题与代码详解

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能算法工程师(中级)课程6-sklearn机器学习之聚类问题与代码详解。在机器学习领域&#xff0c;聚类是一种无监督学习方法&#xff0c;旨在将相似的数据点划分为同一类别。sklearn是一个广泛应用于机器学习的Py…

第十八章 Express multer 文件上传

本章将学习Express multer 文件上传 &#xff0c;因为Nest 的文件上传是基于 Express 的中间件 multer 实现的&#xff0c;所以在学习 Nest 文件上传之前&#xff0c;我们先学习下 multer 包 首先先创建 multer-test 文件夹执行下面代码 创建package.json npm init -y接着安装…

@RequiredArgsConstructor实现构造器注入

RequiredArgsConstructor实现构造器注入 1. Autowired 和 Resource 注解 Autowired Autowired 是 Spring 框架提供的注解&#xff0c;用于自动装配依赖。可以用于字段、构造函数和 setter 方法。 Autowired private ISysUserService userService;Resource Resource 是 Jav…

Java 中的 switch 语句:类型支持与限制

Java 中的 switch 语句&#xff1a;类型支持与限制 1、switch 语句支持的数据类型2、switch 语句不支持的数据类型3、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在 Java 中&#xff0c;switch 语句是一种用于多分支选择的控制结构…

物联网专业现代学徒制人才培养质量评价体系构建

一、 引 言 随着信息技术的飞速发展&#xff0c;物联网&#xff08;IoT&#xff09;技术已成为推动全球信息化、智能化发展的关键力量。物联网专业人才的培养质量直接关系到行业的创新能力和竞争力。现代学徒制作为一种创新的人才培养模式&#xff0c;已被广泛应用于职业教育中…

HCIP.ppp协议(点到点)认证阶段

ppp协议 ppp是点到点的协议 1.兼容性很好 2.可以进行认证和授权 3.可移植性强 三个阶段 1.链路协商阶段 LCP协商------去协商ppp链路会话 2.认证&#xff08;可选&#xff09; 3.NCP协商------网络层协商阶段&#xff08;根据网络层的不同NCP协议就会存在一个对应的NC…

查看尝试登服务器ssh 访问ip地址

不指定时间查看尝试登录服务器的SSH访问IP地址 # CentOS/RHEL系统 zgrep "sshd" /var/log/secure-* | grep "Failed password" | awk {print $(NF-3)} | sort | uniq -c | sort -nr | head -n 10检查过去7天的日志尝试登录服务器的SSH访问IP地址 # CentOS…

QT--SQLite

配置类相关的表&#xff0c;所以我使用sqlite,且QT自带该组件&#xff1b; 1.安装 sqlite-tools-win-x64-3460000、SQLiteExpert5.4.31.575 使用SQLiteExpert建好数据库.db文件&#xff0c;和对应的表后把db文件放在指定目录 ./db/program.db&#xff1b; 2.选择sql组件 3.新…

GaussDB关键技术原理:高性能(五)

GaussDB关键技术原理&#xff1a;高性能&#xff08;四&#xff09;从USTORE存储引擎、计划缓存计划技术、数据分区与分区剪枝、列式存储和向量化引擎、SMP并行执行等五方面对高性能关键技术进行解读&#xff0c;本篇将从LLVM动态查询编译执行、SQL-BYPASS执行优化、线程池化、…

【文档+源码+调试讲解】冷冻仓储管理系统

摘 要 随着互联网时代的到来&#xff0c;同时计算机网络技术高速发展&#xff0c;网络管理运用也变得越来越广泛。因此&#xff0c;建立一个B/S结构的冷冻仓储管理系统&#xff0c;会使冷冻仓储管理系统工作系统化、规范化&#xff0c;也会提高冷冻仓储管理系统平台形象&#x…

若依搭建 帝可得 售货机 笔记

一、搭建项目 1.后端gitee链接&#xff1a; 启动项目时记得修改mysql和redis的相关信息&#xff1b;创建项目相关数据库&#xff0c;并导入初始化的SQL脚本 dkd-parent: 帝可得后台管理系统 (gitee.com) 2.前端gitee链接&#xff1a; 启动项目时记得安装依赖&#xff1a;np…

IPv4与IPv6的定义和主要区别

IPv4与IPv6的定义 IPv4&#xff0c;即互联网协议版本4&#xff08;InternetProtocolversion4&#xff09;&#xff0c;是互联网使用最为广泛的协议之一。它采用32位地址&#xff0c;以点分十进制表示&#xff0c;如192.168.1.1。 IPv6&#xff0c;即互联网协议版本6&#xff…

自动驾驶革命:商汤科技突破性大模型UniAD震撼登场

自动驾驶革命&#xff1a;商汤科技突破性大模型UniAD震撼登场&#xff01; 在人工智能的浪潮中&#xff0c;自动驾驶技术一直是科技巨头们竞相追逐的圣杯。而今&#xff0c;商汤科技联合上海人工智能实验室与武汉大学&#xff0c;以一篇名为"Planning-oriented Autonomou…

Shader每日一练(2)护盾

Shader "Custom/Shield" {Properties{_Size("Size", Range(0 , 10)) 1 // 控制噪声纹理缩放大小的参数_colorPow("colorPow", Float) 1 // 控制颜色强度的指数_colorMul("colorMul", Float) 1 // 控制颜色乘法因子_mainColor("…

政安晨:【Keras机器学习示例演绎】(五十四)—— 使用神经决策森林进行分类

目录 导言 数据集 设置 准备数据 定义数据集元数据 为训练和验证创建 tf_data.Dataset 对象 创建模型输入 输入特征编码 深度神经决策树 深度神经决策森林 实验 1&#xff1a;训练决策树模型 实验 2&#xff1a;训练森林模型 政安晨的个人主页&#xff1a;政安晨 欢…

【机器学习】独立成分分析(ICA):解锁信号的隐秘面纱

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 独立成分分析&#xff08;ICA&#xff09;&#xff1a;解锁信号的隐秘面纱引言I…

人工智能算法工程师(中级)课程3-sklearn机器学习之数据处理与代码详解

大家好&#xff0c;我是微学AI,今天给大家分享一下人工智能算法工程师(中级)课程3-sklearn机器学习之数据处理与代码详解。 Sklearn&#xff08;Scikit-learn&#xff09;是一个基于Python的开源机器学习库&#xff0c;它提供了简单有效的数据挖掘和数据分析工具。Sklearn包含了…

webstorm问题解决:无法识别 @

问题解决tsconfig.json 问题 本地的 vite.config.ts 已经配置 路径 但是&#xff0c;我用webstorm 上识别不了 解决 新增文件tsconfig.json&#xff0c;添加 baseUrl 和 paths 的配置&#xff0c;以告诉 TypeScript 和 WebStorm 如何解析路径别名 tsconfig.json {&quo…

无需构建工具,快速上手Vue2 + ElementUI

无需构建工具&#xff0c;快速上手Vue2 ElementUI 在前端开发的世界中&#xff0c;Vue.js以其轻量级和易用性赢得了开发者的青睐。而Element UI&#xff0c;作为一个基于Vue 2.0的桌面端组件库&#xff0c;提供了丰富的界面组件&#xff0c;使得构建美观且功能丰富的应用变得…

禁止使用存储过程

优质博文&#xff1a;IT-BLOG-CN 灵感来源 什么是存储过程 存储过程Stored Procedure是指为了完成特定功能的SQL语句集&#xff0c;经编译后存储在数据库中&#xff0c;用户可通过指定存储过程的名字并给定参数&#xff08;如果该存储过程带有参数&#xff09;来调用执行。 …