​HoloLens2开发指南- 多场景管理(4)

监听内容加载

场景加载进度

加载或卸载内容时,该 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操作来检测事实之后的内容。

在另一面,因为装载的使用时,所有的场景被激活的操作,那么仅调用和满载,装载的行动,检测和使用新的内容,保证安全。

动作| 何时调用| 内容场景| 照明场景| Scene Manager

— | — | — | — | — | —

OnWillLoadContent| 在内容场景加载之前| •| |

OnContentLoaded| 加载操作中的所有内容场景均已完全加载并激活后| •| |

OnWillUnloadContent| 在内容场景卸载操作之前| •| | 

OnContentUnloaded| 卸载操作中的所有内容场景都完全卸载后| •| | 

OnWillLoadLighting| 就在照明场景加载之前| | •| 

OnLightingLoaded| 照明场景完全加载并激活后| | •| 

OnWillUnloadLighting| 就在照明场景卸载之前| | •| 

OnLightingUnloaded| 完全卸载照明场景后| | •| 

OnWillLoadScene| 就在场景加载之前| •| •| •

 OnSceneLoaded| 完全加载并激活操作中的所有场景后| •| •| • 

OnWillUnloadScene| 就在场景卸载之前| •| •| • 

OnSceneUnloaded| 场景完全卸载后| •| •| •

动作范例

另一个使用操作和协程而不是Update的进度对话框示例:

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;
    }

    ...
}

控制场景激活

默认情况下,将内容场景设置为在加载时激活。如果要手动控制场景激活,则可以将a传递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]);
}

原创文章,作者:游戏开发极客,如若转载,请注明出处:https://hololens2.cn/2020/09/30/%e2%80%8bhololens2%e5%bc%80%e5%8f%91%e6%8c%87%e5%8d%97-%e5%a4%9a%e5%9c%ba%e6%99%af%e7%ae%a1%e7%90%864/

发表评论

电子邮件地址不会被公开。 必填项已用*标注