MRが楽しい

MRやVRについて学習したことを書き残す

MRTK v2のドキュメントを少しずつ読み解く Mixed Reality Toolkitのコンポーネント化

本日は MRTKv2 の調査枠です。
MRTKv2 の Guides ドキュメントを少しずつ読み進めていきます。

MRTKv2のGuidesドキュメント

以下のドキュメントを読み進めていきます。
microsoft.github.io

以下のページでは有志による本ドキュメントの日本語翻訳が行われています。
投稿時点でこちらで未翻訳、または著者が興味のある部分について記事にしていきます。
hololabinc.github.io

本記事では以下のページを読み進めます。
microsoft.github.io
f:id:bluebirdofoz:20200322185746j:plain

Mixed Reality Toolkitのコンポーネント

Mixed Reality Toolkit v2の優れた新機能の1つはコンポーネント化の改善です。
個々のコンポーネントは可能な限り、基盤のコア層を除く全てから隔離されています。

最小化された依存関係

MRTK v2はモジュール化され、システムサービス間の依存関係を最小化する意図で開発されました。
一部のシステムサービスの性質(入力とテレポーテーションなど)により、少数の依存関係が存在します。

サービスには1つ以上のデータプロバイダーコンポーネントが必要になることが予想されます。
しかし、それらの間には直接的なリンクはありません。
SDK機能にも同じことが言えます(例:ユーザーインターフェイスコンポーネント)。

コンポーネント通信

MRTK v2はインターフェイスを利用して、サービス、データプロバイダー、およびアプリケーションコード間で通信します。
これはコンポーネント間に直接リンクがないことを保証するためです。
全ての通信はMixed Reality Toolkitコアコンポーネントを介してルーティングされます。
f:id:bluebirdofoz:20200322185757j:plain

MRTKインポートフットプリントの最小化

MRTKは単一の基盤パッケージとしてインポートされます。
インポートされたファイルを手動で削減することにより、このフットプリントを小さくすることができます。
これは明確に定義されたガイドがない手動のプロセスとなります。

Foundation パッケージのインポート中に、任意のアイテムのチェックを外すことができます。
ただし、機能を損なう可能性があるため、開発の初期段階でこれを行うことはお勧めしません。
アプリの最終的な機能セットを把握したら、次のフォルダーで不要なプロバイダーとサービスを整理できます。
・MixedRealityToolkit.Services
・MixedRealityToolkit.Providers
・MixedRealityToolkit.SDK\Features

注意

MRTK v2には Assets\MixedRealityToolkit フォルダーのコンテンツが必要です。

今後の機能

アプリケーションアーキテクチャ

MRTKは次のような様々なアーキテクチャでアプリケーションを構築できるサポートを提供します。
・MixedRealityToolkit service locator
・Individual services
・Custom service locator
・Hybrid architecture

アプリケーションアーキテクチャを選択するときは、設計の柔軟性とアプリケーションのパフォーマンスを考慮します。
ここで説明するアーキテクチャは、全てのアプリケーションに適しているとは限りません。

MixedRealityToolkit service locator

MRTK はアプリケーションシーンがデフォルトの MixedRealityToolkit サービスロケーターコンポーネントを使用できるようにします。
このコンポーネントには、構成インスペクターを介した MRTK システムとデータプロバイダーの構成のサポートが含まれます。
これらはコンポーネントライフスパンとコア動作を管理します。(例:更新するタイミング)

プロジェクトにシステムが存在するかどうかに関係なく、すべてのシステムがコア構成インスペクターに表示されます。
詳細については、Mixed Reality Configuration Guide を参照してください。
microsoft.github.io

Individual services

一部の開発者は、個々のサービスコンポーネントをアプリケーションシーン階層に含めることを望んでいます。
この利用法を有効にするには、サービスをカスタムレジストラーにカプセル化するか、自己登録/自己管理する必要があります。

自己登録サービスは IMixedRealityServiceRegistrar を実装し、レジストリを介してアプリケーションコードがサービスインスタンスを検出できるように自身を登録します。

自己管理サービスはシーン階層内のシングルトンオブジェクトとして実装できます。
このオブジェクトは、アプリケーションコードがサービス機能に直接アクセスするために使用できるインスタンスプロパティを提供します。

Custom service locator

一部の開発者は、カスタムサービスロケーターコンポーネントを作成する機能を要求します。
カスタムサービスロケーターは IMixedRealityServiceRegistrar インターフェイスを実装し、アクティブなサービスのライフサイクルとコア動作を管理します。

Hybrid architecture

MRTKは、開発者が必要に応じてアプローチを組み合わせることができるハイブリッドアーキテクチャをサポートします。
例えば MixedRealityToolkit サービスロケーターから開始し、自己登録サービスを追加できます。

ハイブリッドアーキテクチャを選択する場合、作業の重複に注意します。
(例:複数のコンポーネントからコントローラーデータを取得する)

MRTK v2のドキュメントを少しずつ読み解く 照明シーンの操作

本日は MRTKv2 の調査枠です。
MRTKv2 の Guides ドキュメントを少しずつ読み進めていきます。

MRTKv2のGuidesドキュメント

以下のドキュメントを読み進めていきます。
microsoft.github.io

以下のページでは有志による本ドキュメントの日本語翻訳が行われています。
投稿時点でこちらで未翻訳、または著者が興味のある部分について記事にしていきます。
hololabinc.github.io

本記事では以下のページを読み進めます。
microsoft.github.io
f:id:bluebirdofoz:20200321094924j:plain

照明シーンの操作

プロファイルで定義されたデフォルトの照明シーンは、起動時にロードされます。
その照明シーンは SetLightingScene が呼び出されるまでロードされたままです。

IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();

sceneSystem.SetLightingScene("MorningLighting");

f:id:bluebirdofoz:20200321094934j:plain

照明設定の移行

transitionType は新しい照明シーンへの遷移のスタイルを制御します。

IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();

sceneSystem.SetLightingScene("MiddayLighting", LightingSceneTransitionType.CrossFade);

f:id:bluebirdofoz:20200321094944j:plain

利用可能なスタイルは次のとおりです。

タイプ説明Duration値
None 前の照明シーンがアンロードされ、新しい照明シーンがロードされます。
移行の処理は利用しません。
利用しない
FadeToBlack 前の照明シーンは黒にフェードアウトします。
新しい照明シーンが読み込まれ、黒からフェードアップします。
ロケーション間のスムーズな移行に役立ちます。
利用する
CrossFade 以前の照明シーンは新しい照明シーンがフェードインするにつれてフェードアウトします。
同じ場所での照明セットアップ間のスムーズな移行に役立ちます。
利用する


一部の照明設定は遷移中に補間できないことに注意してください。
スムーズに視覚的に移行したい場合、これらの設定は照明シーン間で一貫性を保つ必要があります。

設定スムーズな FadeToBlack 遷移スムーズな CrossFade 遷移
スカイボックス NoNo
カスタム反射 NoNo
太陽光のリアルタイム陰影 YesNo

MRTK v2のドキュメントを少しずつ読み解く コンテンツ読み込みの監視

本日は MRTKv2 の調査枠です。
MRTKv2 の Guides ドキュメントを少しずつ読み進めていきます。

MRTKv2のGuidesドキュメント

以下のドキュメントを読み進めていきます。
microsoft.github.io

以下のページでは有志による本ドキュメントの日本語翻訳が行われています。
投稿時点でこちらで未翻訳、または著者が興味のある部分について記事にしていきます。
hololabinc.github.io

本記事では以下のページを読み進めます。
microsoft.github.io
f:id:bluebirdofoz:20200320092118j:plain

コンテンツ読み込みの監視

シーン操作の進捗

コンテンツがロードまたはアンロードされると 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);

f:id:bluebirdofoz:20200320092132j:plain

進捗例

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
        // ...
    }
    // ...
}

f:id:bluebirdofoz:20200320092144j:plain

SceneOperationProgress を使用して、進行状況ダイアログを表示できます。

public class ProgressDialog : MonoBehaviour
{
    private void Update()
    {
        IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();

        if (sceneSystem.SceneOperationInProgress)
        {
            DisplayProgressIndicator(sceneSystem.SceneOperationProgress);
        }
        else
        {
            HideProgressIndicator();
        }
    }
    // ...
}

f:id:bluebirdofoz:20200320092155j:plain

アクションによる監視

シーンシステムにはシーンがロードまたはアンロードされるタイミングを知らせるいくつかのアクションが用意されています。
各アクションは、影響を受けるシーンの名前を伝えます。

ロードまたはアンロード操作に複数のシーンが含まれる場合、関連するアクションは影響を受けるシーンごとに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;
    }

    // ...
}

f:id:bluebirdofoz:20200320092214j:plain

シーンのアクティブ化を制御する

デフォルトでは、コンテンツシーンはロード時にアクティブになるように設定されています。
シーンのアクティブ化を手動で制御する場合、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

f:id:bluebirdofoz:20200320092224j:plain

ロードされているコンテンツの確認

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

f:id:bluebirdofoz:20200320092235j:plain

MRTK v2のドキュメントを少しずつ読み解く コンテンツシーンの読み込み

本日は MRTKv2 の調査枠です。
MRTKv2 の Guides ドキュメントを少しずつ読み進めていきます。

MRTKv2のGuidesドキュメント

以下のドキュメントを読み進めていきます。
microsoft.github.io

以下のページでは有志による本ドキュメントの日本語翻訳が行われています。
投稿時点でこちらで未翻訳、または著者が興味のある部分について記事にしていきます。
hololabinc.github.io

本記事では以下のページを読み進めます。
microsoft.github.io
f:id:bluebirdofoz:20200319092600j:plain

コンテンツシーンの読み込み

デフォルトでは全てのコンテンツの読み込み操作は非同期であり、加算的です。
マネージャーおよび照明シーンは、コンテンツの読み込み操作の影響を受けません

ロードの進行状況とシーンのアクティブ化の監視については、コンテンツのロードの監視を参照してください。
microsoft.github.io

コンテンツの読み込み

コンテンツシーンを読み込むには LoadContent メソッドを使用します。

IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();

// Additively load a single content scene
// 単一のコンテンツシーンを追加的にロードする
await sceneSystem.LoadContent("MyContentScene");

// Additively load a set of content scenes
// コンテンツシーンのセットを追加的にロードする
await sceneSystem.LoadContent(new string[] { "MyContentScene1", "MyContentScene2", "MyContentScene3" });

f:id:bluebirdofoz:20200319092622j:plain

シングルシーンの読み込み

単一のシーンのロードに相当するものは、オプションの[mode]引数を使用して実現できます。
LoadSceneMode.Single は、ロードを続行する前に、ロードされた全てのコンテンツシーンをアンロードします。

IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();

// ContentScene1, ContentScene2 and ContentScene3 will be loaded additively
// ContentScene1、ContentScene2、ContentScene3 は追加的にロードされます
await sceneSystem.LoadContent("ContentScene1");
await sceneSystem.LoadContent("ContentScene2");
await sceneSystem.LoadContent("ContentScene3");

// ContentScene1, ContentScene2 and ContentScene3 will be unloaded
// SingleContentScene will be loaded additively
// ContentScene1、ContentScene2、ContentScene3 がアンロードされます
// その後、SingleContentScene が追加的にロードされます
await sceneSystem.LoadContent("SingleContentScene", LoadSceneMode.Single);

f:id:bluebirdofoz:20200319092632j:plain

次/前のシーンの読み込み

コンテンツはインデックスの作成順に単独でロードできます。
これは一連のデモンストレーションシーンを1つずつユーザーに案内するショーケースアプリケーションに役立ちます。
f:id:bluebirdofoz:20200319092640j:plain

以下の次/前のコンテンツのロードでは LoadSceneMode.Single を使用して、前のコンテンツがアンロードされるようにしています。

IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();

if (nextSceneRequested && sceneSystem.NextContentExists)
{
    await sceneSystem.LoadNextContent();
}

if (prevSceneRequested && sceneSystem.PrevContentExists)
{
    await sceneSystem.LoadPrevContent();
}

f:id:bluebirdofoz:20200319092652j:plainf:id:bluebirdofoz:20200319092652j:plain

現在ロードされている最低のビルドインデックスよりも低いビルドインデックスを持つコンテンツシーンが少なくとも1つある場合、PrevContentExists は true を返します。
現在ロードされている最高のビルドインデックスよりも高いビルドインデックスを持つコンテンツシーンが少なくとも1つある場合、NextContentExists は true を返します。

wrap 引数が true の場合、コンテンツは最初/最後のビルドインデックスにループバックします。
これにより、次/前のコンテンツを確認する必要がなくなります。

IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();

if (nextSceneRequested)
{
    await sceneSystem.LoadNextContent(true);
}

if (prevSceneRequested)
{
    await sceneSystem.LoadPrevContent(true);
}

f:id:bluebirdofoz:20200319092706j:plain

タグによる読み込み

f:id:bluebirdofoz:20200319092715j:plain
コンテンツシーンをグループで読み込むことが望ましい場合があります。
例えば、エクスペリエンスのステージは複数のシーンで構成されている場合です。
この場合、全てを同時にロードして機能させる必要があります。
これを容易にするために、シーンにタグを付け、そのタグでロードまたはアンロードすることができます。

IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();

await sceneSystem.LoadContentByTag("Stage1");

// Wait until stage 1 is complete
// ステージ1が完了するまで待ちます

await sceneSystem.UnloadContentByTag("Stage1");
await sceneSystem.LoadContentByTag("Stage2");

f:id:bluebirdofoz:20200319092724j:plain

タグによるロードは、スクリプトを変更せずにエクスペリエンスに要素を組み込み/削除したい場合にも役立ちます。
例えば、次の2つのタグセットを使用してこのスクリプトを実行すると、異なる結果が生成されます。

IMixedRealitySceneSystem sceneSystem = MixedRealityToolkit.Instance.GetService<IMixedRealitySceneSystem>();

await sceneSystem.LoadContentByTag("Terrain");
await sceneSystem.LoadContentByTag("Structures");
await sceneSystem.LoadContentByTag("Vegetation");

f:id:bluebirdofoz:20200319092733j:plain

タグセット例:1

シーン名タグ名読み込み結果
DebugTerrainPhysicsTerrain
StructureTestingStructures
VegetationToolsVegetation
MountainTerrain
CabinStructures
TreesVegetation

タグセット例:2

シーン名タグ名読み込み結果
DebugTerrainPhysicsDoNotInclude
StructureTestingDoNotInclude
VegetationToolsDoNotInclude
MountainTerrain
CabinStructures
TreesVegetation

エディターの動作

Scene System のサービスインスペクターを使用して、これら全ての操作をエディターおよび再生モードで実行できます。
エディターモードではシーンのロードは瞬時に行われますが、再生モードではロードの進行状況を確認してアクティベーショントークンを使用できます。
f:id:bluebirdofoz:20200319092745j:plain

MRTK v2のドキュメントを少しずつ読み解く シーンタイプ

本日は MRTKv2 の調査枠です。
MRTKv2 の Guides ドキュメントを少しずつ読み進めていきます。

MRTKv2のGuidesドキュメント

以下のドキュメントを読み進めていきます。
microsoft.github.io

以下のページでは有志による本ドキュメントの日本語翻訳が行われています。
投稿時点でこちらで未翻訳、または著者が興味のある部分について記事にしていきます。
hololabinc.github.io

本記事では以下のページを読み進めます。
microsoft.github.io
f:id:bluebirdofoz:20200318094015j:plain

シーンタイプ

シーンは3つのタイプに分けられており、各タイプには異なる機能があります。
f:id:bluebirdofoz:20200318094025j:plain

コンテンツシーン

これは一般的なシーンです。
任意の種類のコンテンツを格納でき、任意の組み合わせでロードまたはアンロードできます。

コンテンツシーンはデフォルトで有効になっています。
プロファイルの Content Scenes 配列に含まれるシーンは全て、サービスによってロード/アンロードできます。

マネージャーシーン

必要な MixedRealityToolkit インスタンスを持つ単一のシーンです。
このシーンは起動時に最初にロードされ、アプリの有効期間中はロードされたままになります。
マネージャーシーンは破棄されるべきではない他のオブジェクトもホストできます。
これは DontDestroyOnLoad の推奨される代替手段です。

この機能を有効にするには、プロファイルの[Use Manager Scene]をオンにします。
そしてシーンオブジェクトを[Manager Scene]フィールドにドラッグします。

照明シーン

照明情報と照明オブジェクトを保存する一連のシーンです。
一度にロードできるのは1つだけで、ロード中にそれらの設定を組合せてスムーズな照明遷移を実現できます。

Unityの照明設定(アンビエントライト、スカイボックスなど)は、個々のシーンに関連付けられています。
このため、動作をオーバーライドするのは簡単ではないため、追加ロードを使用する場合は管理が難しい場合があります。
これは、実行時に取得できない照明条件でアセットが作成されたとき、混乱を引き起こす可能性があります。
f:id:bluebirdofoz:20200318094036j:plain

シーンシステムは、ライティングシーンを使用して、編集モードと再生モードの両方で照明の設定の一貫性を維持します。
これは読み込まれているシーンやアクティブなシーンに関係ありません。

この機能を有効にするには、プロファイルの[Use Lighting Scene]をオンにして、[Lighting Scenes]配列に入力します。

キャッシュされた照明設定

プロファイルには照明シーンに保持されている照明設定のキャッシュされたコピーが保存されます。
ライティングシーンでこれらの設定が変更された場合、プレイモードで期待通りにライティングが表示されるよう、キャッシュを更新する必要があります。
キャッシュの設定が古い可能性がある場合、プロファイルに警告が表示されます。
[Update Cached Lighting Settings]をクリックすると、各照明シーンが読み込まれ、設定が抽出され、プロファイルに保存されます。
f:id:bluebirdofoz:20200318094046j:plain

エディターの動作

照明シーンを使用する利点の1つは、編集中にコンテンツが正しく照明されると分かることです。
Scene Service は常に照明シーンをロードし続け、そのシーンの照明設定を現在のアクティブシーンにコピーします。

Scene System のサービスインスペクターを開いて、ロードする照明シーンを変更できます。
編集モードでは照明シーン間を瞬時に移行できます。プレイモードではトランジションをプレビューできます。
f:id:bluebirdofoz:20200318094101j:plain

注意

通常、アクティブシーンはエディターの照明設定を決定します。
ただし、照明設定を設定するためにこの機能を使用しないことを推奨します。
アクティブシーンは、新しく作成されたオブジェクトがデフォルトで配置される場所でもあるためです。
照明シーンには照明コンポーネントのみを含めることができます。

代わりに、現在の照明シーンの設定はアクティブシーンの設定に自動的にコピーされます。
これにより、コンテンツシーンの照明設定が上書きされることに注意してください。

MRTK v2のドキュメントを少しずつ読み解く シーンシステムの概要

本日は MRTKv2 の調査枠です。
MRTKv2 の Guides ドキュメントを少しずつ読み進めていきます。

MRTKv2のGuidesドキュメント

以下のドキュメントを読み進めていきます。
microsoft.github.io

以下のページでは有志による本ドキュメントの日本語翻訳が行われています。
投稿時点でこちらで未翻訳、または著者が興味のある部分について記事にしていきます。
hololabinc.github.io

本記事では以下のページを読み進めます。
microsoft.github.io
f:id:bluebirdofoz:20200317223102j:plain

シーンシステムの概要

シーンシステムを使用する場合

プロジェクトが単一のシーンで構成されている場合、シーンシステムはおそらく必要ありません。
次の1つ以上が当てはまる場合に最も役立ちます。

・プロジェクトに複数のシーンがある場合。
・シングルシーンの読み込みに慣れていますが、MixedRealityToolkit インスタンスを破壊する方法を使いたくない場合。
・複数のシーンを追加的にロードして、エクスペリエンスを構築する簡単な方法が必要な場合。
・進行中のロード操作を追跡する簡単な方法、または一度にロードされる複数のシーンのシーンのアクティブ化を制御する簡単な方法が必要な場合。
・全てのシーンで照明の一貫性と予測可能性を維持する必要がある場合。

エディター設定

デフォルトでは Scene System は UnityEdito でいくつかの動作を強制します。
これらの動作が重い場合、Scene System プロファイルの Editor Settings セクションで機能を無効にすることができます。

Editor Manage Build Settings

true の場合、サービスはビルド設定を自動的に更新し、全てのマネージャー、照明、コンテンツシーンが追加されるようにします。
ビルド設定を完全に制御する場合はこれを false にします。

Editor Enforce Scene Order

true の場合、サービスはマネージャーシーンが最初にシーン階層で表示され、次に照明、次にコンテンツが表示されるようにします。
シーンの階層を完全に制御する場合は、これを false にします。

Editor Manage Loaded Scenes

true の場合、サービスは、マネージャー、コンテンツ、照明シーンが常にロードされるようにします。
エディターに読み込むシーンを完全に制御する場合は false にします。

Editor Enforce Lighting Scene Types

true の場合、サービスは PermittedLightingSceneComponentTypes で定義された照明関連コンポーネントのみが照明シーンで許可されるようにします。
照明シーンのコンテンツを完全に制御する場合は false にします。
f:id:bluebirdofoz:20200317223142j:plain

MRTK v2のドキュメントを少しずつ読み解く ポインター その4

本日は MRTKv2 の調査枠です。
MRTKv2 の Guides ドキュメントを少しずつ読み進めていきます。

MRTKv2のGuidesドキュメント

以下のドキュメントを読み進めていきます。
microsoft.github.io

以下のページでは有志による本ドキュメントの日本語翻訳が行われています。
投稿時点でこちらで未翻訳、または著者が興味のある部分について記事にしていきます。
hololabinc.github.io

本記事では以下のページを読み進めます。
microsoft.github.io
f:id:bluebirdofoz:20200316095037j:plain

クエリポインター

以下の例は利用可能な入力ソース(コントローラーと入力)をループして、どのポインターがアタッチされているかを検出します。
これにより、現在アクティブな全てのポインターを収集することができます。

var pointers = new HashSet<IMixedRealityPointer>();

// Find all valid pointers
// 全ての有効なポインターを見つける
foreach (var inputSource in CoreServices.InputSystem.DetectedInputSources)
{
    foreach (var pointer in inputSource.Pointers)
    {
        if (pointer.IsInteractionEnabled && !pointers.Contains(pointer))
        {
            pointers.Add(pointer);
        }
    }
}

f:id:bluebirdofoz:20200316095051j:plain

プライマリポインター

開発者は FocusProviders PrimaryPointerChanged イベントにサブスクライブして、フォーカスされているプライマリポインターが変更されたときに通知を受けることができます。
これは、ユーザーが現在、視線、ハンドレイ、または別の入力ソースを介してシーンと対話しているかどうかを識別するのに非常に役立ちます。

private void OnEnable()
{
    var focusProvider = CoreServices.InputSystem?.FocusProvider;
    focusProvider?.SubscribeToPrimaryPointerChanged(OnPrimaryPointerChanged, true);
}

private void OnPrimaryPointerChanged(IMixedRealityPointer oldPointer, IMixedRealityPointer newPointer)
{
    // ...
}

private void OnDisable()
{
    var focusProvider = CoreServices.InputSystem?.FocusProvider;
    focusProvider?.UnsubscribeFromPrimaryPointerChanged(OnPrimaryPointerChanged);

    // This flushes out the current primary pointer
    // これにより、現在のプライマリポインターが更新されます
    OnPrimaryPointerChanged(null, null);
}

f:id:bluebirdofoz:20200316095102j:plain

PrimaryPointerExample シーンはイベントに PrimaryPointerChangedHandler を使用して、新しいプライマリポインターに応答する方法を示します。
f:id:bluebirdofoz:20200316095115j:plain

ポインター結果

ポインターの Result プロパティにはフォーカスのあるオブジェクトを決定するシーンクエリの現在の結果が含まれています。
モーションコントローラー、視線入力、ハンドレイ用にデフォルトで作成されるレイキャストポインターの場合、レイキャストヒットの位置と法線が含まれます。

void IMixedRealityPointerHandler.OnPointerClicked(MixedRealityPointerEventData eventData)
{
    var result = eventData.Pointer.Result;
    var spawnPosition = result.Details.Point;
    var spawnRotation = Quaternion.LookRotation(result.Details.Normal);
    Instantiate(MyPrefab, spawnPosition, spawnRotation);
}

f:id:bluebirdofoz:20200316095126j:plain

PointerResultExample シーンはポインター Result を使用して、ヒット位置にオブジェクトをスポーンする方法を示しています。
f:id:bluebirdofoz:20200316095135j:plain

ポインターを無効にする

ポインターを有効または無効にするには(例えば、ハンドレイを無効にする)、PointerUtils を使用して特定のポインタータイプの PointerBehavior を設定します。

// Disable the hand rays
// 手の光線を無効にする
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff);

// Disable hand rays for the right hand only
// 右手のみ手の光線を無効する
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Right);

// Disable the gaze pointer
// 注視ポインタを無効にする
PointerUtils.SetGazePointerBehavior(PointerBehavior.AlwaysOff);

// Set the behavior to match HoloLens 1
// HoloLens 1に一致するように動作を設定します
// Note, if on HoloLens 2, you must configure your pointer profile to make the GGV pointer show up for articulated hands.
// HoloLens 2でGGVポインターが関節付きの手に表示されるようにポインタープロファイルを構成する必要があることに注意してください。

public void SetHoloLens1()
{
    PointerUtils.SetHandPokePointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetHandGrabPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetGazePointerBehavior(PointerBehavior.Default);
}

f:id:bluebirdofoz:20200316095144j:plain

その他の例については、PointerUtils および TurnPointersOnOff を参照してください。

エディターを介したポインターの相互作用

IMixedRealityPointerHandler によって処理されるポインターイベントの場合、MRTK は PointerHandler コンポーネントの形式でさらに便利になり、Unity イベントを介してポインターイベントを直接処理できます。
f:id:bluebirdofoz:20200316095156j:plain

ポインター範囲

Far Pointer にはシーン内の他のオブジェクトとレイキャストおよび相互作用する距離を制限する設定があります。
デフォルトでは、この値は10メートルに設定されています。
この値は HoloLens シェルの動作と一貫性を保つために選択されています。

これは DefaultControllerPointer プレハブの ShellHandRayPointer コンポーネントのフィールドを更新することで変更できます。

Pointer Extent

ポインターが相互作用する最大距離を制御します。

Default Pointer Extent

ポインターが何かと相互作用していないときにレンダリングされるポインター光線の長さを制御します。