本日は MRTKv2 の調査枠です。
MRTKv2 の Guides ドキュメントを少しずつ読み進めていきます。
MRTKv2のGuidesドキュメント
以下のドキュメントを読み進めていきます。
microsoft.github.io
以下のページでは有志による本ドキュメントの日本語翻訳が行われています。
投稿時点でこちらで未翻訳、または著者が興味のある部分について記事にしていきます。
hololabinc.github.io
本記事では以下のページを読み進めます。
microsoft.github.io
コンテンツ読み込みの監視
シーン操作の進捗
コンテンツがロードまたはアンロードされると SceneOperationInProgress プロパティは true を返します。
この SceneOperationProgress プロパティを使用して、この操作の進行状況を監視できます。
SceneOperationProgress の値は現在の非同期シーン操作の平均値です。
コンテンツの読み込みの開始時に SceneOperationProgress は 0 になります。
読み込みが完全に完了すると 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 // 最初に追加のシーンロードを実行します // SceneOperationInProgress はこの操作中は true になります // SceneOperationProgress は完了するまでの間に 0-1 を表示します 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 // 単一のシーンのロードを行います // これにより、以下の2つのアクションが連続して行われます // 1.最初の「ContentScene1」がアンロードされます // 2.次に、「ContentScene2」がロードされます // SceneOperationInProgress はこの操作中は true になります // SceneOperationProgress は完了するまでの間に 0-1 を表示します await 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(); } } // ... }
アクションによる監視
シーンシステムにはシーンがロードまたはアンロードされるタイミングを知らせるいくつかのアクションが用意されています。
各アクションは、影響を受けるシーンの名前を伝えます。
ロードまたはアンロード操作に複数のシーンが含まれる場合、関連するアクションは影響を受けるシーンごとに1回呼び出されます。
また、これらはロードまたはアンロード操作が完全に完了すると同時に呼び出されます。
このため、OnUnloaded アクションを使用して事後に破棄されたコンテンツを検出するのではなく OnWillUnload アクションを使用して破棄されるコンテンツを検出することをお勧めします。
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 (IEnumerable<string> sceneName) { // This may be invoked multiple times per frame - once per scene being loaded or unloaded. // So filter the events appropriately. // これは、フレームごとに複数回呼び出すことができます。 // シーンのロードまたはアンロードごとに1回。 // このため、イベントを適切にフィルタリングする必要があります。 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 を任意のコンテンツロードメソッドに渡すことができます。
1回の操作で複数のコンテンツシーンがロードされている場合、このアクティベーショントークンはすべてのシーンに適用されます。
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 System.Threading.Tasks.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 System.Threading.Tasks.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]); }