Share via


永続化のテクニック

永続化は、基になるプラットフォームでサポートされている場合に使用できます。 現在、これは、Unity の組み込 VR サポート (レガシ XR) を使用している、HoloLens ファミリのデバイスに限定されています。

基本的な永続化

ワールド ロック ツールの基本的な永続化は、既定で有効になっています。 この有効化には 2 つの部分があります。

永続化のインスペクター設定

ここでの関連するチェック ボックスは、[Auto Load]\(自動読み込み\) と [Auto Save]\(自動保存\) であり、これらはオンになっています。 淡色表示されている場合がありますが、これは、[Use Defaults] \(既定値を使用\) 選択肢の一部だからです。 [Use Defaults] \(既定値を使用\) を無効にすると、自動化オプションの任意の組み合わせを選択できます。

これらの設定スクリプトからの操作については、さらに詳しい説明を参照してください。

AutoSave

AutoSave オプションは、アプリケーションの実行中に頻繁に通常の状態を保存するように WLT に指示します。 アプリケーションは、いつでも状態の損失を最小限に抑えながら終了できます。

AutoLoad

AutoLoad オプションは、起動時に以前に保存された状態を読み込むように WLT に指示します。 これにより、アプリケーションは、最後のセッションで (WLT に関して) 中断した状態から新しいセッション を再開できます。

完全な永続化

AutoSave と AutoLoad の両方を有効にすると、WLT はセッション間でシームレスに動作します。 最初の実行ではグローバル空間の位置と方向は任意ですが (保存された以前の状態がないので、起動時の頭部のポーズが基点として使用されます)、後続の実行では同じ座標フレームが共有されます。

このため、アプリケーションが前のセッションの空間から切断されている空間で新しいセッションを開始すると、興味深い動作が発生します。 詳細については、以下の「場所による永続化」セクションを参照してください。

Note

AutoSave と AutoLoad の設定は、グローバル SpacePins にも適用されます。 詳細については以下を参照してください。

アプリケーションでの永続化のコントロール

既定の完全な永続化は、広範囲のアプリケーションに適しています。

ただし、一部のアプリケーションでは、プロセスを細かく制御する必要がある場合があります。

WLT の自動永続化を有効にすることが、AutoSave と AutoLoad の 2 つのプロパティに分割されているのは、奇妙に思われるかもしれません。 この 2 つが個別に使用されるケースを調べることで、永続化システム全体に関する分析情報が得られる可能性があります。

AutoSave を使用し、AutoLoad を使用しない

自動保存の設定が、アプリケーションによって制御される読み込み

この構成では、WLT は定期的に状態を保存するように設定されます。 ただし、起動時に永続化された状態が自動的に読み込まれることはありません。

代わりに、システムは、このデバイスで初めて実行される場合と同様に、新しい状態で起動します。 Load() を明示的に要求した後にのみ、前のセッションの状態が復元されます。

このようにすることで、アプリケーションが、以前のセッション状態の復元が適切かどうかを判断し、必要に応じて復元するデータを変更することができます。

一般的な WLT 保存状態は、ファイル "LocalState/frozenWorldState.hkfw" に含まれています。 WLT によって作成された後に、そのファイルを別の場所にコピーし、アプリケーションの判断で復元できます。

配置 (SpacePin) データの保存ファイルは、既定で "LocalState/Persistence/Alignment.fwb" になります。 ただし、これは、配置マネージャーの SaveFileName を使用してアプリケーションでオーバーライドできます。

この構成で前のセッションの状態を読み込むかどうかは、起動時に決定する必要があります。 前のセッションの保存された状態を実行すると、このセッションの状態で上書きされます。 より柔軟なセットアップについては、以下の「手動で保存して AutoLoad を実行する」を参照 してください。

手動で保存して AutoLoad を実行する

自動読み込みのための設定が、アプリケーションによって制御される保存

この構成では、WLT は起動時に以前のセッションから使用可能な状態を読み込みます。 ただし、状態は自動的に保存されません。 これにより、アプリケーションは、Save() を呼び出して、状態を保存する価値がある状況とそのタイミングを判断できます。

AutoLoad は、起動時に使用可能な状態を読み込むように WLT に指示するだけです。 アプリケーションは、Load() の明示的な呼び出しを使用して、保存された状態をいつでも自由に復元できます。

手動で保存して読み込む

永続化またはアプリケーション制御の永続化がない場合の設定

アプリケーションでは、保存と読み込みのプロセスを完全に制御することを選択できます。

その後は、状態はアプリケーションから Save() への明示的な呼び出しでのみ保存され、Load() の明示的な呼び出しでのみ読み込まれます。

Load() の呼び出しによって読み込まれる状態は、このセッションの早い段階または前のセッションで保存されている場合があります。

永続化を無効にする

上で説明したように、永続化は常にアプリケーションでスクリプトから使用できます。 自動永続化は、インスペクターの WorldLockingContext またはスクリプトを介して有効または無効にすることができます。 自動永続化が無効になっている場合、WLT は、アプリケーションからの明示的な要求なしに状態の保存または読み込みを試行しません。

当然ながら、AutoLoad ディレクティブは起動時に読み込むかどうかにのみ影響するので、起動時にスクリプトから値を変更しても効果はありません。

開発中の注意

前に説明したように、グローバル WLT と配置の保存ファイルの場所は、アプリケーションに対してグローバルです。 特に、SpacePins とも呼ばれる配置ノードは、名前で保持されます (下記を参照)。 アプリケーションが 1 つのシーンからの一連の SpacePins を使用して状態を保存し、別のシーンからの SpacePins のセットを使用して状態を読み込み、両方の SpacePins セットの名前が同じである場合、動作は未定義になります。

この問題には複数の回避方法があります。 可能な場合は、プロジェクト内で SpacePin 名を再利用しないようにするのが最善の方法です。 再デプロイ後に予期しないシーン スライディング動作が発生する場合は、WLT 保存状態を削除してみてください。 同様に、アプリケーションを根本的に変更する場合は、WLT 保存ファイルをデバイスから削除するか、新しいバージョンをインストールする前に単にアプリケーションをアンインストールすることを真剣に検討する必要があります。

場所別の永続化

シナリオ

複数の物理的な場所で実行されるアプリケーションの興味深いクラスがあります。 アプリケーションを Room A で実行し、デバイスを閉じて、再び移動し、その後、アプリケーションを Room B で再起動する場合があります。Room B は Room A から廊下を歩いたところあることもあれば、別の大陸にある可能性もあります。 アプリケーションとデバイスには、これを知る方法はありません。

わかりやすくするために、アプリケーションが手動による WLT 永続化用に構成されているとします。

チュートリアル

これらの接続されていない Room A と Room B を考えてください。

異なる大陸の空き部屋

アプリケーションは Room A で起動されます。部屋内で連続した固定座標空間を確立すると、部屋全体がフラグメント 1 にマップされます。 永続的なホログラムの Object X が部屋に配置されます。 その後、アプリケーションは状態を保存し、終了します。

ワールドロックルームA.

デバイスの電源をオフにして、ルーム B に持ち込み、もう一度起動します。

デバイスはこれを Room A ではないと認識します。そのため、WLT は、ID == 29 など、新しいフラグメント ID をそのコンテンツに割り当てます。 どうして 29 でしょうか。 1 ではないからです。 フラグメント ID は、任意の値であり、1 つのフラグメント以外の ID は、FragmentId.Invalid、FragmentId.Unknown、または他の既知のフラグメントと同じにはなりません。

ルームAが追跡されていないワールドロックルームB

現在、フラグメントが 2 つありますが、それらをマージする方法はありません (相対的な位置に関する情報が利用できないためです)。

関心を持ったアプリケーション開発者から次のように質問される場合があります。Room A に永続的な Object X を配置しました。アプリケーションが Room B で起動されたときに、Object X が読み込まれるとどうなるでしょうか?

その答えは、動作はアプリケーション開発者が決定する必要があるということです。 Object X が Room A に配置されている場合の現在のフラグメント ID は使用可能であり、永続化できます。 その後、アプリケーションは、起動時に、現在のフラグメントが作成された時点と同じかどうかに基づいて、Object X を表示するかどうかを決定できます。

ここでは、開発者は、現在のフラグメント ID が 1 の場合にのみObject X が読み込まれ、現在のフラグメントが 29 の場合にのみ Room B の Object Y が読み込まれることを決定 (および実装) します。

空間に関連付けられたフラグメント ID の永続化は、ワールド ロック ツールの永続化の一部として保存されます。 ただし、オブジェクトに関連付けられているフラグメント ID の永続化と、それに基づいて実行するアクションは、アプリケーションに任されます。

オブジェクトに関連付けられているフラグメント ID と共に、グローバル空間内のポーズを保存できます。 その後、フラグメント ID が一致する場合は、オブジェクトが読み込まれた後に、そのポーズを復元して、最後のセッション中の物理世界内の位置に戻すことができます。 ワールド ロック ツールの永続化により、ポーズは、セッションが変わっても、物理的な世界のその周囲の特徴に対して相対的に固定されたままになります。

SpacePins の永続化

SpacePins は、AlignmentAnchors のアプリケーション側ラッパーと考えることができます。 SpacePins (および派生クラス) は Unity コンポーネントですが、AlignmentAnchors は純粋に概念的であり、AlignmentAnchor に対応するクラスまたは型はありません。 したがって、この説明では、SpacePins と AlignmentAnchors を同じ意味で使用し、全般的に SpacePins を優先します。

ただし、SpacePins の概念がない場合、AlignmentManager が SpacePins を永続化できることは混乱を招く可能性があります。 これは、AlignmentManager が概念的な AlignmentAnchor を管理し、AlignmentAnchor が SpacePin の本質を具体化し、そこから SpacePinを再構成できるためです。

通常の WLT 永続化システムと比べて、SpacePins の永続化に関しては、より多くのアプリケーション レベルのコントロールがあります。これは、SpacePins が本質的に、ワールド ロック ツールの残りの部分よりも、アプリケーションの入力によって駆動されることが多いためです。

SpacePins (および AlignmentAnchors) は名前で保持されることに注意してください。 これは、同じ IAlignmentManager 内の 2 つのアクティブな SpacePins が同じ名前を持たないという一般的な要件よりも若干強い要件です。 SpacePins を永続化する場合、同じデータベース内の 2 つの SpacePins がアクティブかどうかにかかわらず、同じ名前を持つことはできません。

配置マネージャー データベース

IAlignmentManager には、RestoreAlignmentAnchor(string uniqueName, Pose virtualPose) の実装によって暗黙的に示されているように、名前別の SpacePins のデータベースがあります。

グローバル配置データベース

WorldLockingManager.GetInstance() によって所有されている 1 つのグローバル IAlignmentManager があります。 前述のように、既定の保存ファイルの場所は、プロパティ SaveFileName によって決まります。 SaveFileName は、インターフェイス IAlignmentManager ではなく、クラスの AlignmentManager のプロパティであることに注意してください。 IAlignmentManager の実装では、ファイルやファイル名の概念を使用せずに永続化を実装する場合があります。 SaveFileName は、AlignmentManager が永続化を実装する方法の成果物であり、そのため AlignmentManager に制限されます。

ローカル配置データベース

AlignSubtree ごとに 1 つずつ、任意の数のサブスペース配置マネージャーを使用することができ、それらはフィールドAlignSubtree.alignmentManager として表示されます。 また、アプリケーションでは、独自の AlignmentManager インスタンスを作成することも、IAlignmentManager から派生した独自のクラスを作成することもできます。

各 AlignSubtree コンポーネントの AlignmentManager には、専用の保存ファイルの場所があります。既定では、GameObject の名前に "fwb" という拡張子を付けたものになります。 たとえば、AlignSubtree コンポーネントが "MyRoot" という名前の GameObject にある場合、保存ファイルの名前は "MyRoot.fwb" になります。 スラッシュ (/) を使用して、サブフォルダーに配置することができます。 2つの AlignSubtree コンポーネントで同じ保存ファイルの場所を使用することは、おそらく問題になります。

実際

長期的には、SpacePins/AlignmentAnchors にグローバルに一意の名前を付ける方が、ローカルで一意にするというより軽い要件を管理するよりも簡単で堅牢であるので、これが強く推奨されます。 しかし、自社で優先する方法を使用してください。

関連項目