World Locking Tools Context 和 Manager 设置
World Locking Tools Context 允许在 Unity Inspector 中对 World Locking Tools Manager 进行参数化自定义。
虽然 WorldLockingContext 组件为 WorldLockingManager 提供了一个 UI,但必须要了解它们不是同一个东西,在某些情况下,了解它们的关系可能很重要。
Manager 是单一实例
WorldLockingManager 是一个按需创建并持久保存在应用程序生命周期中的单一实例。 如果没有调用 WorldLockingManager,它将永远不会被实例化。 对该实例进行实例化后,它将保持活动状态,直到应用程序关闭。 它永远不会销毁并重新实例化。
WorldLockingManager 不是 Unity 对象,而是泛型 C# 类。 其 Update 是由一个代理 Unity 组件(专用 WorldLockingManager.UpdateProxy 类的实例)驱动的。 否则,它将独立于 Unity 的创建/更新/销毁周期。
Context 是一个 Unity 组件
WorldLockingContext 是一个 Unity 组件,它以通常的方式添加到场景中的对象中。 该组件的字段与任何其他常规 Unity 组件的字段一样出现在 Unity Inspector 中。
虽然在一个场景中拥有多个活动 WorldLockingContext 并不会出错,但可能并不需要这样做,因为行为是未定义的,这取决于对象加载的未知顺序。
在加载 WorldLockingContext 时应用上下文设置。 具体来说,上下文在其 OnEnable 调用中会将其设置推送到 World Locking Tools Manager,并且按需使其场景成为活动场景。 当且仅当新的活动场景是上下文所属的场景时,后者作为 Unity.SceneManager.activeSceneChanged 回调的一部分应用。
所有设置都可以通过脚本应用
在运行时的任何时候,应用程序均可通过脚本将自定义设置应用于 WorldLockingManager。 如果需要拆分并重新生成资源以影响设置的更改,则该重构将在设置更改时立即进行。
虽然有一些方便的成员可以从 WorldLockingManager 获取单个属性值,例如 AutoSave,但参数的设置总是以聚合方式进行。 例如,切换 AutoMerge 和 AutoRefreeze 功能的代码可能如下所示:
/// Get a copy of the current settings
var settings = WorldLockingManager.GetInstance().Settings;
/// Modify the copy
settings.AutoMerge = !settings.AutoMerge;
settings.AutoRefreeze = !settings.AutoRefreeze;
/// Update the current settings to the values in the copy.
WorldLockingManager.GetInstance().Settings = settings;
诊断设置也是如此。
请注意,以这种方式一次更改多个设置只会产生一次重新生成的成本(如果需要)。
设置优先级
当前应用于 WorldLockingManager 的设置规则非常简单:
如果没有加载包含上下文的场景,也没有通过脚本显式设置任何设置,则 WorldLockingManager 具有默认设置。
设置将保留其值,直到包含场景的 WorldLockingContext 加载或在脚本中从应用程序调用的显式更改替代它。
混合来自上下文的 World Locking Tools Manager 设置和来自脚本的设置时,应谨慎使用。 由于上下文总是在加载时应用其设置,因此在加载过程中手动应用设置的脚本(特别是从其 OnEnable 回调)很可能会遇到争用条件和不确定的行为。
可用设置
用于控制 World Locking Tools 行为的可用设置分为以下几组。
“自动化”设置
“自动化”设置控制 World Locking Tools Manager 的运行时行为。 可用于修改的字段及其含义记录在 ManagerSettings 类中。 他们专注于启用或禁用由管理员执行的定期自动操作。 任何已禁用的自动操作均可手动执行。
“链接”设置
“链接”设置用于显式定义场景 GameObjects
,其转换将用于应用 World Locking Tools 的校正。
“使用现有值”字段允许在场景中使用相机装备设置链接对象一次(当“使用现有值”为 false 时),并且不会被加载后续内容场景替代(当“使用现有值”为 true 时)。
相反,如果将“使用现有值”设置为 false,则允许多个场景,其中每个场景都将不同的相机设备绑定到相机层次结构中的相应位置。
通过脚本创建和管理相机层次结构时,应在所有 Context 中将“使用现有值”字段设置为 true,并且通过相机管理脚本显式更新链接。
如果未提供所需的转换,要么为 null,要么所有 Context 都有“使用现有值”,系统随后发出警告并尝试推断出正确的选择。 建议显式地设置相应的转换而不是让系统猜测,但这不是必需的。
此处提供两个其他选项,可用于控制如何应用相机转换校正。
第一个复选框“应用调整”默认已启用。 这告知系统将每一帧计算的相机校正应用到“调整帧”GameObject
。 禁用此功能是一项非常高级的功能,仅在解决所有其他问题并且对 World Locking Tools 有了深入了解后,才应尝试此功能。 简而言之,它告诉系统相机校正不应用于相机,而是通过其他方式应用。 通常,这是通过 AlignSubtree
组件实现的,但并非必须如此。
第二个复选框“无间距和滚动”告诉系统在从 Playspace
到锁定空间的转换中计算的任何间距和滚动都归零。 (请参阅此关于 WLT 坐标空间的讨论)。 这对 SpacePin
系统应用的旋转没有影响,但只会影响由 Frozen World Engine 计算的世界锁定相机校正转换。
“定位点管理”设置
“定位点管理”设置,定位点跟踪系统的所有显式选择。 此选择目前仅在启动时完成,选择后就无法更改。
此处的其他设置允许控制底层内部定位点图的密度。 这些设置可随时更改,但其效果可能需要一些时间才能通过内部图传播。
当覆盖非常大的区域时,人们可能需要降低内部定位点图的密度,以牺牲性能准确性。 增加 MinNewAnchorDistance 就是这样做的。 通过在添加新的内部定位点之前增加所需的最小距离,定位点之间的间距将增大,因此定位点的密度会降低。
需要注意的是,为了通过边缘创建测试,MaxAnchorEdgeLength 必须大于 MinNewAnchorDistance。 在实践中,如果 MaxAnchorEdgeLength 比 MinNewAnchorDistance 大 10 - 20%,效果就会很好。
MaxLocalAnchors 参数(而不是修改密度)会直接限制内部定位点的数量。 目前,当定位点数量超过限制时,将回收距离相机最远的定位点以减少数量。 不过,其他算法也很有趣,而且正在研究中,因此应用程序不应该依赖于此特定的实现。
有关更多详细信息,请参阅 AnchorSettings 结构。
诊断设置
“诊断”设置控制用于分析行为和调试的诊断集合。 它们通常应保留“使用默认值”设置,除其他设置外,其中包括禁用诊断集合。 诊断集合是一个巨大的性能阻力,因此除非需要,否则应避免使用。
在开发过程中,当出现意外和不良行为时,通过禁用使用默认值和启用 DiagnosticsSettings.Enabled 收集的诊断数据将启用有助于了解和修复该行为的数据收集。
DiagnosticsSettings 类中描述了可用于修改的字段。
默认设置
管理器和“诊断”设置都在设置中包含一个“使用默认值”复选框。 “使用默认值”属性也可从脚本中获得。
如果“使用默认值”属性为 true,则使用当前默认设置。 如果新版本中属性的默认值发生更改,则“使用默认值”属性会指示系统使用新的属性值。
按需将“使用默认值”属性设置为 true 后,会将所有值重置为其当前默认值。 要在给定时间锁定默认值快照中的值,请启用“使用默认值”属性以将所有字段重置为当前默认值,然后取消设置复选框以防止其通过更新而更改。
建议将“使用默认值”设置为 true,但试验和调试的开发期间除外。