監視內容載入 — 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 完全卸載場景之後

動作範例

另一個使用動作和協同程式而非 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;
    }

    ...
}

控制場景啟用

根據預設,內容場景會在載入時設定為啟動。 如果您想要手動控制場景啟用,您可以將 傳遞 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]);
}