Version: 2017.1
空間マッピングのベストプラクティス
ウェブカメラ

Spatial Mapping コンポーネント

Unity エディターには、プロジェクト環境のサーフェスの情報を集める低レベルの API スクリプトリファレンスがあります。この低レベルの API スクリプトリファレンスによって、いつデバイスにサーフェスの変化に関するクエリを送るかや、いつ関連するサーフェスのゲームオブジェクトを作成、または、更新を行うかに関して、最大限の制御が可能です。Spatial Mapping コンポーネントを使うと、低レベルの API スクリプトリファレンスを直接使うことなしに、複合現実感を素早く立ち上げ実行することができます。

空間マッピング機能を現実世界の空間に適用した例
空間マッピング機能を現実世界の空間に適用した例

Spatial Mapping コンポーネント

2 つの Spatial Mapping コンポーネントがあります。Spatial Mapping RendererSpatial Mapping Collider です。 Component > Add… (もしくは、インスペクターウィンドウの Add Component をクリックします ) と選択し、Add Component メニューを表示します。Spatial Mapping コンポーネントは、Add Component メニューの AR カテゴリーにあります。

Spatial Mapping コンポーネントにアクセスするには、 Component メニューで AR を選択します
Spatial Mapping コンポーネントにアクセスするには、 Component メニューで AR を選択します

それらのコンポーネントは一緒でも個別でも使用できます。それぞれの Spatial Mapping コンポーネントはそれぞれのサーフェスオブザーバーを使って現実世界の変化を察知します。そのコンポーネントの設定の仕方により、各 Spatial Mapping コンポーネントは周期的にシステムにクエリを送り、現実空間に発生した変化を把握します。システムがそのコンポーネントに関連する変更を知らせると、コンポーネントは変更されたさまざまなサーフェスのベイクの順序付けをします。ベイクの処理には、現実のサーフェスに対応するメッシュでメッシュフィルターを生成することが含まれています。 Spatial Mapping RendererSpatial Mapping Collider コンポーネントは、それぞれ特定の方法でこのメッシュフィルターを使用します。

Spatial Mapping Renderer (Script)

Spatial Mapping Renderer コンポーネントによって空間マッピングしたサーフェスを視覚的に表現します。これは視覚的にサーフェスをデバッグしたり、環境に視覚的なエフェクトを加えるのに利用できます。

Spatial Mapping Renderer コンポーネントは定期的にシステムに現実世界の変化を問い合わせます。コンポーネントが変化を検知するたびに、そこで取得したサーフェスのデータをゲームオブジェクトにベイクします。ゲームオブジェクトは Mesh Filter と Mesh Renderer を含んでいます。Renderer コンポーネントはサーフェスの情報をもつゲームオブジェクトの生存期間を管理します。つまり、Spatial Mapping Renderer コンポーネントはそのゲームオブジェクトの作成、更新、削除を処理します。

このコンポーネントを使うと、生成されたすべてのサーフェスで簡単に動的にマテリアルを変更することができます。 2 つのマテリアルタイプがあります。

  • オクルージョンマテリアルは見た目は透明ですが、ホログラムを隠します。例えば、現実世界の机の下に、ゲーム世界にあるホログラフィックオブジェクトを隠したい場合に利用できます。

  • すべてのコンポーネントのサーフェスに適用できるワイヤーフレームシェーダー。ワイヤーフレームの色は距離を表しています。以下は距離と色をマッピングしたものです。

    • 0 ~ 1 メートル = 黒

    • 1 ~ 2 メートル = 赤

    • 2 ~ 3 メートル = 緑

    • 3 ~ 4 メートル = 青

    • 4 ~ 5 メートル = 黄

    • 5 ~ 6 メートル = シアン

    • 6 ~ 7 メートル = マジェンタ

    • 7 ~ 8 メートル = くり色

    • 8 ~ 9 メートル = 青緑

    • 9 ~ 10 メートル = オレンジ

    • 10 メートル以上 = 白

Spatial Mapping Renderer のワイヤーフレームシェーダー。ワイヤーフレームの色は距離を表します。
Spatial Mapping Renderer のワイヤーフレームシェーダー。ワイヤーフレームの色は距離を表します。

Render Settings

設定 プロパティー
Custom Render Setting サーフェスをレンダリングする 3 つのオプションのいずれかを選択します。Occlusion Material - 現実世界のサーフェスの背後にあるゲームオブジェクトを隠す透明なマテリアルです。これを選択するとサーフェスのメッシュレンダラーがすべて有効になり、他の設定は無効になります。Custom Material - サーフェスを視覚化するための独自のマテリアル。デバッグ、ビジュアルエフェクト、独自のオクルージョンマテリアルに使用します。これを選択するとサーフェスのメッシュレンダラーがすべて有効になり、他の設定はオーバーライドされます。 None (Game Object) - サーフェスに割り当てられているすべてのメッシュレンダラーを無効になります。
Custom Material レンダリングに使いたいマテリアルを選択します。デフォルトはビルトインの SpatialMappingWireframe マテリアルです。ここで選択したオプションは、 Custom Render Settings に適用されるレンダリングマテリアルです。 Custom Render Settings をアクティブにするオプション ( Occlusion MaterialCustom Material ) には、ここを__Custom Material__ に設定することが必要です。

General Settings に関しては、後述の General Settings を参照してください。

注意

  • サーフェスの情報を持つゲームオブジェクトはすべて、 Custom Render Setting からマテリアルを取得します。Custom Render Setting を変更すると、該当するゲームオブジェクトのレンダリングマテリアルは Custom Render Setting のものに変わります。これによりドローコールの数が減り、レンダリングパフォーマンスが向上します。共有マテリアルの使用もまた、レンダリングに使用されるメモリーの量を削減します。

  • 新しいマテリアルを Custom Material 設定に指定するとき、該当するゲームオブジェクトのサーフェスマテリアルは自動的に変更されるわけではありません。新しいマテリアルをすべてのサーフェスに適用するためには、Custom Render SettingCustom MaterialOcclusion Material に設定する必要があります。

  • Custom Render SettingOcclusion Material または Custom Material のプロパティーがランタイムに指定されていない場合、それらは Renderer コンポーネントで破棄されます。ただし、ランタイムに指定された Occlusion Material または Custom Material は、コンポーネントで破棄されないため、個別に破棄する必要があります。

スクリプト例 - ランタイムにサーフェスマテリアルを変更する

以下のスクリプト例は、サーフェスの情報を持つゲームオブジェクトすべてに適用されているマテリアルをランタイムに動的に変更する方法を示しています。

SpatialMappingRenderer renderer = spatialMappingGameObject.AddComponent<SpatialMappingRenderer>();
renderer.customMaterial = new Material(Shader.Find("VR/SpatialMapping/Wireframe"));
renderer.currentRenderSetting = SpatialMappingRenderer.RenderSetting.CustomMaterial;

Spatial Mapping Collider (Script)

Spatial Mapping Collider コンポーネントによってホログラフィックコンテンツと現実のサーフェスの相互作用が可能になります。このコンポーネントは、サーフェスの情報を持つゲームオブジェクトの作成、更新、破棄を処理します。

コンポーネントは定期的にシステムへクエリを送り、現実世界で発生した変化を把握します。システムがサーフェスの変化を検知すると、Spatial Mapping Collider コンポーネントは変更されたさまざまなサーフェスのベイクの順序付けをします。サーフェスがベイクされるとき、Mesh Filter と Mesh Collider コンポーネントをもつゲームオブジェクトが生成されます。サーフェスに Mesh Collider ができると、サーフェスに光線を当て、衝突させることができます。

Collider Settings

設定 プロパティー
Enable Collisions サーフェスの情報を持つ Mesh Colliders を有効にするにはこれをチェックします。
Mesh Layer すべてのサーフェスのメッシュコライダーの Layer プロパティーを設定します。レイキャストのレイヤーを設定する必要があることに注意してください。レイキャストを実行するときは、どのレイヤーに対してレイ交差をテストするのかを示す必要があります。デフォルトでは、すべてのゲームオブジェクトは Default のレイヤーに割り当てられています。 ただし、ゲームオブジェクトをある特定のレイヤーに割り当てることをお勧めします。後述の パフォーマンスの最適化 を参照してください。詳細は、マニュアルの レイヤーレイキャスト を参照してください。また、後述の「スクリプト例 - SpatialSurface レイキャスト」も参照してください。
Physic Material Mesh Collider に割り当てる Physic Material を指定します。デフォルトは None (Physic Material) です。Physic Material は他のリジッドボディコンポーネントがどのようにそれと相互作用するかを指示します。例えば、サーフェスで氷をシミュレートするときは、その上を動くオブジェクトにより小さな摩擦力を適用します。Spatial Mapping Collider コンポーネントは、その Physic Material を該当サーフェスゲームオブジェクトのすべての Mesh Colliders に適用します。詳しくは Physic Material を参照してください。

General Settings に関しては、後述の General Settings を参照してください。

スクリプト例 - SpatialSurface レイキャスト

以下の例は、SpatialSurface レイヤー上のゲームオブジェクトに対するレイキャストの使用法を紹介しています。

using UnityEngine;
using System.Collections; 

public class CustomLayerCollision : MonoBehaviour
{
    // フレームごとに Update が呼び出されます。
    void Update()
    {
        // ユーザーがマウスの左ボタンを押すと
        // 衝突のテストを行います。ジェスチャイベントに基づいて
        // DetectCollisions を発します。*

        if(Input.GetMouseButtonDown(0))
        {
            DetectCollisions();
        }
    } 

    void DetectCollisions()
    {
        // 空間サーフェスか UI レイヤーのいずれかにある
        // すべてのゲームオブジェクトに対しレイキャスト
        int layerMask = 1 << LayerMask.NameToLayer("SpatialSurface");
        // ScreenPointToRay を使い、元はメインカメラの位置で、
        // 方向がメインカメラから、ワールド空間内のマウスの
        // 移動位置に向いたレイを作成。
        RaycastHit[] hits = Physics.RaycastAll(Camera.main.ScreenPointToRay(Input.mousePosition), float.MaxValue, layerMask);

        if(hits.Length > 0)
        {
            foreach(RaycastHit hit in hits)
            {
                Debug.Log(string.Format("Hit Object **\"**{0}**\"** at position **\"**{1}**\"**", hit.collider.gameObject, hit.point));
            }
        }
        else
        {
            Debug.Log("Nothing was hit.");
        }
    }
}

設定

General Settings

General SettingsSpatial Mapping Renderer (Script)Spatial Mapping Collider (Script) コンポーネントと同様に機能します。

設定 プロパティー
Surface Parent Surface Parent となるゲームオブジェクトを選択します。Spatial Mapping コンポーネントが作成するサーフェスの情報を持つゲームオブジェクトはこの Surface Parent オブジェクトを継承します。 None (Game Object) を選択すると、自動的に Surface Parent ゲームオブジェクトが作成されます。
Freeze Updates これをチェックすると、コンポーネントがシステムに対しサーフェスの変更をクエリすることを停止します。各 Spatial Mapping コンポーネントは定期的にシステムに対し現実世界のサーフェスの変更をクエリします。サーフェスに関するクエリとベイクはメモリ、パフォーマンス、パワーに負荷がかかります。ほとんどが静的な環境では、更新がない間、ユーザーが周囲の環境を見回せるようにします。
Time Between Updates 現実世界のサーフェス変化に関するクエリの間隔を 1/10 秒単位で指定します (例えば、3.7 や 4.6 など)。デフォルトは 2.5 秒です。間隔が短いほど、メモリ、パフォーマンス、パワーに対する負荷が高くなります。
Removal Update Count サーフェスのゲームオブジェクトが削除される前の更新の数を指定します。ここでは、更新はフレームと同じ意味です。デフォルトは 10 回の更新 (フレーム) です。ノート: 削除の更新のカウントダウンは、サーフェスのゲームオブジェクトがサーフェスオブザーバーの境界領域に存在しなくなったこと (つまり、システムがレポートする決められた領域から消えたこと) を、システムがコンポーネントに通知すると開始されます。ここでは、サーフェスのゲームオブジェクトを削除する前にこのイベントの後に続く更新 (フレーム) の数を指定します。
Level of Detail コンポーネントが生成するメッシュの品質を Low, Medium, High から選択します。デフォルトは Medium です。品質が高くなるとコライダーとレンダリングはより正確になり、品質が低くなるとパフォーマンスとパワーにかかる負担が軽減されます。Level Of Detail の 3 つのモードの例は、以下の画像を参照してください。
Bounding Volume Type バウンディングボリューム範囲の形状を SphereAxis Aligned Box から選択します。デフォルトは Axis Aligned Box です。バウンディングボリュームはシステムが現実世界のサーフェスの変化を報告する決められた範囲のことです。
Size In Meters バウンディングボリュームのサイズをメートルで設定します。Sphere は半径で設定します。デフォルトの半径は 2 メートルです。Axis Aligned Box は範囲で設定します。デフォルトは Vector3 (4,4,4) か 4 立方メートルです。オブザーバーのバウンディングボリュームはシステムが現実世界のサーフェスの変化を報告すると決まった範囲です。

Level Of Detail

3 つの Level Of Detail モード
3 つの Level Of Detail モード

パフォーマンスの最適化

  • 各 Spatial Mapping コンポーネントは、互いに他の Spatial Mapping コンポーネントから独立していることに注意してください。つまり、たとえ複数のコンポーネントが同じサーフェスを使用している場合でも、各コンポーネントで維持するサーフェスのリストは異なります。パフォーマンスを最適化するためには、使用する Spatial Mapping コンポーネント数を制限するようにします。

  • シミュレーションの環境がかなり静的で変更がない場合 (例えば、ボードゲーム)、事前にサーフェスのデータをできる限りスキャンしておき、Freeze Updates プロパティーを false に設定します。こうすると、パフォーマンスが若干よくなり、パワーの消費が抑えられます。

  • Spatial Mapping コンポーネントを作動させるためには、パフォーマンスに少し負担がかかります。Spatial Mapping コンポーネントを持つゲームオブジェクトを動かすことはなるべく避けるようにします。

  • Collider Settings > Level of Detail では、 Low を選択してください。これにより、衝突の交点を計算するときのパフォーマンスを向上し、パワー消費を抑えます。

  • Spatial Mapping Mesh Colliders の更新は Spatial Mapping Mesh Renderers より遅延が少ない。つまり、 Colliders は Renderers より素早く更新します。

  • Collider Settings > Mesh Layer では、すべてのゲームオブジェクトはデフォルトで Default レイヤーに指定されています。ただし、ゲームオブジェクトを特定のレイヤーに割り当てるとよい効果を得られます。レイキャストのための計算は負荷が高く、パフォーマンスを遅くする場合があります。レイヤーを使用することにより、レイキャストの計算を行っているゲームオブジェクトを絞ることができ、パフォーマンスを最適化できます。 Default レイヤーに複雑なメッシュがあまりない場合、衝突のためのレイキャストテストの実行に、あまり多くのパフォーマンスコストを必要としません。ただし、ゲームオブジェクトをレイヤーに整理して、衝突時のレイキャストテストの複雑さを軽減することが最も良いといえます。

詳しくは レイヤーレイキャスト を参照してください。

空間マッピングのベストプラクティス
ウェブカメラ