监视内容加载 – MRTK2
场景操作进度
加载或卸载内容时,SceneOperationInProgress
属性将返回 true。 可以通过 SceneOperationProgress
属性监视此操作的进度。
SceneOperationProgress
值是当前所有异步场景操作的平均值。 当内容加载开始时,SceneOperationProgress
将为零。 完全完成后,SceneOperationProgress
将设置为 1,并保持在 1,直到下一个操作发生。 请注意,只有内容场景操作会影响这些属性。
这些属性反映从开始到结束的整个操作的状态,即使该操作包含多个步骤:
IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();
// First do an additive scene load
// SceneOperationInProgress will be true for the duration of this operation
// SceneOperationProgress will show 0-1 as it completes
await sceneSystem.LoadContent("ContentScene1");
// Now do a single scene load
// This will result in two actions back-to-back
// First "ContentScene1" will be unloaded
// Then "ContentScene2" will be loaded
// SceneOperationInProgress will be true for the duration of this operation
// SceneOperationProgress will show 0-1 as it completes
sceneSystem.LoadContent("ContentScene2", LoadSceneMode.Single)
进度示例
如果在加载内容时应挂起活动,SceneOperationInProgress
会非常有用:
public class FooManager : MonoBehaviour
{
private void Update()
{
IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();
// Don't update foos while a scene operation is in progress
if (sceneSystem.SceneOperationInProgress)
{
return;
}
// Update foos
...
}
...
}
SceneOperationProgress
可用于显示进度对话框:
public class ProgressDialog : MonoBehaviour
{
private void Update()
{
IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();
if (sceneSystem.SceneOperationInProgress)
{
DisplayProgressIndicator(sceneSystem.SceneOperationProgress);
}
else
{
HideProgressIndicator();
}
}
...
}
使用操作进行监视
场景系统提供了若干操作,让你能了解场景的加载和卸载情况。 每个操作都中继受影响场景的名称。
如果加载或卸载操作涉及多个场景,则会针对每个受影响的场景调用一次相关操作。 加载或卸载操作完成时,也会同时调用它们。出于此原因,建议使用 OnWillUnload 操作来检测即将销毁的内容,而不是使用 OnUnloaded 操作在事后检测销毁的内容。
另一方面,因为仅当激活并完全加载所有场景时才会调用 OnLoaded 操作,使用 OnLoaded 操作来检测和使用新内容是有安全保障的。
操作 | 调用时机 | 内容场景 | 照明场景 | 管理器场景 |
---|---|---|---|---|
OnWillLoadContent |
加载内容场景之前 | • | ||
OnContentLoaded |
加载操作中所有内容场景完全加载并激活后 | • | ||
OnWillUnloadContent |
内容场景卸载操作之前 | • | ||
OnContentUnloaded |
卸载操作中所有内容场景完全卸载后 | • | ||
OnWillLoadLighting |
照明场景加载之前 | • | ||
OnLightingLoaded |
照明场景完全加载并激活后 | • | ||
OnWillUnloadLighting |
照明场景卸载之前 | • | ||
OnLightingUnloaded |
照明场景完全卸载后 | • | ||
OnWillLoadScene |
场景加载之前 | • | • | • |
OnSceneLoaded |
操作中所有场景完全加载并激活后 | • | • | • |
OnWillUnloadScene |
场景卸载之前 | • | • | • |
OnSceneUnloaded |
场景完全卸载后 | • | • | • |
操作示例
另一个进度对话框示例使用操作和协同例程而非更新:
public class ProgressDialog : MonoBehaviour
{
private bool displayingProgress = false;
private void Start()
{
IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();
sceneSystem.OnWillLoadContent += HandleSceneOperation;
sceneSystem.OnWillUnloadContent += HandleSceneOperation;
}
private void HandleSceneOperation (string sceneName)
{
// This may be invoked multiple times per frame - once per scene being loaded or unloaded.
// So filter the events appropriately.
if (displayingProgress)
{
return;
}
displayingProgress = true;
StartCoroutine(DisplayProgress());
}
private IEnumerator DisplayProgress()
{
IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();
while (sceneSystem.SceneOperationInProgress)
{
DisplayProgressIndicator(sceneSystem.SceneOperationProgress);
yield return null;
}
HideProgressIndicator();
displayingProgress = false;
}
...
}
控制场景激活
默认情况下,内容场景设置为在加载时激活。 如果要手动控制场景激活,可以将 SceneActivationToken
传递到任何内容加载方法。 如果通过单个操作加载多个内容场景,则此激活令牌将应用于所有场景。
IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();
SceneActivationToken activationToken = new SceneActivationToken();
// Load the content and pass the activation token
sceneSystem.LoadContent(new string[] { "ContentScene1", "ContentScene2", "ContentScene3" }, LoadSceneMode.Additive, activationToken);
// Wait until all users have joined the experience
while (!AllUsersHaveJoinedExperience())
{
await Task.Yield();
}
// Let scene system know we're ready to activate all scenes
activationToken.AllowSceneActivation = true;
// Wait for all scenes to be fully loaded and activated
while (sceneSystem.SceneOperationInProgress)
{
await Task.Yield();
}
// Proceed with experience
检查已加载的内容
ContentSceneNames
属性按生成索引的顺序提供一批可用的内容场景。 可通过 IsContentLoaded(string contentName)
检查这些场景是否已加载。
IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();
string[] contentSceneNames = sceneSystem.ContentSceneNames;
bool[] loadStatus = new bool[contentSceneNames.Length];
for (int i = 0; i < contentSceneNames.Length; i++>)
{
loadStatus[i] = sceneSystem.IsContentLoaded(contentSceneNames[i]);
}