近い対話機能を追加する方法 - MRTK2

近接対話は、タッチとグラブの形で行われます。 タッチとグラブの各イベントは、それぞれ PokepointerSpherePointer によってポインター イベントとして発生します。

特定の GameObject に対するタッチやグラブの入力イベントをリッスンするには、3 つの重要なステップが必要です。

  1. 関連するポインターがメインの MRTK 構成プロファイルに登録されていることを確認します。
  2. 目的の GameObject に、適切なグラブまたはタッチ スクリプト コンポーネントと Unity Collider があることを確認します。
  3. 目的の GameObject にアタッチされたスクリプトに、グラブまたはタッチの各イベントをリッスンするための入力ハンドラー インターフェイスを実装します。

グラブ操作の追加

  1. MRTK ポインター プロファイルSpherePointer が登録されていることを確認します。

    既定の MRTK プロファイルと既定の HoloLens 2 プロファイルには、既に SpherePointer が含まれています。 SpherePointer が作成されることを確認するには、MRTK 構成プロファイルを選択し、[入力]>[ポインター]>[ポインターのオプション] に移動します。 既定 GrabPointer のプレハブ (Assets/MRTK/SDK/Features/UX/Prefabs/Pointers) は 、コントローラーの種類多関節ハンドと共に一覧表示する必要があります。 カスタム プレハブは、SpherePointer クラスが実装されている限り利用できます。

    グラブ ポインター プロファイルの例

    既定のグラブ ポインターは、既定のHoloLens 2 インターフェイスに一致するように、グラブ ポイントの周りの円錐形の近くのオブジェクトに対してクエリを実行します。

    円錐グラブ ポインター

  2. つかめるようにする必要のある GameObject で、NearInteractionGrabbable と、コライダーを追加します。

    GameObject のレイヤーが、つかめるレイヤー上にあるようにしてください。 既定では、"空間認識" と "レイキャストを無視" を除くすべてのレイヤーがつかめるようになっています。 どのレイヤーがつかめるかは、GrabPointer プレハブの "グラブ レイヤー マスク" を調べるとわかります。

  3. GameObject またはその先祖の 1 つで、IMixedRealityPointerHandler インターフェイスを実装するスクリプト コンポーネントを追加します。 NearInteractionGrabbable を持つオブジェクトの先祖はすべて、ポインター イベントも受け取ることができます。

グラブ コードの例

イベントがタッチまたはグラブの場合に出力されるスクリプトを以下に示します。 関連する IMixedRealityPointerHandler インターフェイス関数では、MixedRealityPointerEventData を介してイベントをトリガーするポインターの型を確認できます。 ポインターが SpherePointer の場合、操作はグラブです。

public class PrintPointerEvents : MonoBehaviour, IMixedRealityPointerHandler
{
    public void OnPointerDown(MixedRealityPointerEventData eventData)
    {
        if (eventData.Pointer is SpherePointer)
        {
            Debug.Log($"Grab start from {eventData.Pointer.PointerName}");
        }
        if (eventData.Pointer is PokePointer)
        {
            Debug.Log($"Touch start from {eventData.Pointer.PointerName}");
        }
    }

    public void OnPointerClicked(MixedRealityPointerEventData eventData) {}
    public void OnPointerDragged(MixedRealityPointerEventData eventData) {}
    public void OnPointerUp(MixedRealityPointerEventData eventData) {}
}

タッチ操作を追加する

UnityUI 要素にタッチ操作を追加するプロセスは、バニラ 3D GameObject の場合とは異なります。 Unity UI コンポーネントの有効化に関しては、この後の「Unity UI」のセクションに進んでください。

ただし、両方の種類の UX 要素について、PokePointer が "MRTK ポインター プロファイル" に登録されていることを確認してください。

既定の MRTK プロファイルと既定の HoloLens 2 プロファイルには、既に PokePointer が含まれています。 PokePointer が作成されることを確認するには、MRTK 構成プロファイルを選択し、[入力]>[ポインター]>[ポインターのオプション] に移動します。 既定 PokePointer の (Assets/MRTK/SDK/Features/UX/Prefabs/Pointers) プレハブは、 コントローラーの種類多関節ハンドと共に一覧表示する必要があります。 カスタム プレハブは、PokePointer クラスが実装されている限り利用できます。

Poke ポインター プロファイルの例

3D GameObject

3D GameObject にタッチ操作を追加するには、3D オブジェクトにタッチ可能な平面を 1 つだけにする場合と、コライダー全体に基づきタッチ可能にする場合とで、2 つの異なる方法があります。 最初の方法は、通常、BoxCollider を使用したオブジェクトです。ここでは、コライダーの 1 つの面だけがタッチ イベントに反応するようにする必要があります。 もう 1 つは、コライダーに基づいて任意の方向からタッチできるようにする必要があるオブジェクトです。

単一面のタッチ

これは、1 つの面だけをタッチ可能にする必要がある場合に役立ちます。 このオプションは、ゲーム オブジェクトに BoxCollider があることを前提としています。 これを BoxCollider がないオブジェクトに使用することもできます。その場合は、[境界] と [ローカル センター] の各プロパティを手動で設定して、タッチ可能な平面を構成します (つまり、境界は 0 - 0 以外の値に設定する必要があります)。

  1. タッチ可能にする必要がある GameObject に BoxCollider とコンポーネントを NearInteractionTouchable 追加します。

    1. 下のコンポーネント スクリプトで IMixedRealityTouchHandler インターフェイスを使用する場合は、[受け取るイベント][タッチ] に設定します。

    2. [境界を修正する][センターを修正する] をクリックします。

    NearInteractionTouchable セットアップ

  2. そのオブジェクトまたはその先祖の 1 つに、以下を実装するスクリプト コンポーネントを追加します。IMixedRealityTouchHandler インターフェイス。 NearInteractionTouchable を持つオブジェクトの先祖はすべて、ポインター イベントも受け取ることができます。

Note

NearInteractionTouchable の GameObject が選択されているエディターのシーン ビューで、白いアウトラインの正方形と矢印を確認します。 矢印は、タッチ可能な "面" を指しています。 接触可能なものは、その方向からのみタッチ可能になります。 コライダーを全方向からタッチ可能にするには、「任意のコライダーのタッチ」のセクションを参照してください。 NearInteractionTouchable Gizmos

任意のコライダーのタッチ

これは、ゲーム オブジェクトをコライダーの面全体に沿ってタッチ可能にする必要がある場合に役立ちます。 たとえば、これを使用して、コライダー全体をタッチ可能にする必要のある、SphereCollider を持つオブジェクトのタッチ操作を有効にすることができます。

  1. タッチ可能にする必要がある GameObject に、コライダーとコンポーネントを NearInteractionTouchableVolume 追加します。

    1. 下のコンポーネント スクリプトで IMixedRealityTouchHandler インターフェイスを使用する場合は、[受け取るイベント][タッチ] に設定します。
  2. そのオブジェクトまたはその先祖の 1 つに、以下を実装するスクリプト コンポーネントを追加します。IMixedRealityTouchHandler インターフェイス。 NearInteractionTouchable を持つオブジェクトの先祖はすべて、ポインター イベントも受け取ることができます。

Unity UI

  1. シーンに UnityUI キャンバスがあることを確認、あるいは追加します。

  2. タッチ可能にする必要がある GameObject に、NearInteractionTouchableUnityUI コンポーネントを追加します。

    1. 下のコンポーネント スクリプトで IMixedRealityTouchHandler インターフェイスを使用する場合は、[受け取るイベント][タッチ] に設定します。
  3. そのオブジェクトまたはその先祖の 1 つに、IMixedRealityTouchHandler インターフェイスを実装するスクリプト コンポーネントを追加します。 NearInteractionTouchableUnityUI を持つオブジェクトの先祖はすべて、ポインター イベントも受け取ることができるようになります。

重要

オブジェクトが、重なっているキャンバス オブジェクトに配置されている場合は、オブジェクトが予期したとおりに動作しないことがあります。 一貫した動作を確保するために、シーン内のキャンバス オブジェクトが重ならないようにしてください。

重要

NearInteractionTouchable スクリプト コンポーネントでは、プロパティ [受け取るイベント] 用に、"ポインター" と "タッチ" の 2 つのオプションがあります。 IMixedRealityPointerHandler インターフェイスを使用する場合は [受け取るイベント] を "ポインター" に設定し、入力イベントに応答または処理するコンポーネント スクリプトで IMixedRealityTouchHandler インターフェイスを使用する場合は "タッチ" に設定します。

タッチ コードの例

下のコードは、NearInteractionTouchable バリアント コンポーネントを持つ GameObject にアタッチされ、タッチ入力イベントに応答する MonoBehaviour を示しています。

public class TouchEventsExample : MonoBehaviour, IMixedRealityTouchHandler
{
    public void OnTouchStarted(HandTrackingInputEventData eventData)
    {
        string ptrName = eventData.Pointer.PointerName;
        Debug.Log($"Touch started from {ptrName}");
    }
    public void OnTouchCompleted(HandTrackingInputEventData eventData) {}
    public void OnTouchUpdated(HandTrackingInputEventData eventData) { }
}

近接対話スクリプトの例

タッチ イベント

この例では、キューブを作成し、それをタッチ可能にして、タッチすると色が変わるようにします。

public static void MakeChangeColorOnTouch(GameObject target)
{
    // Add and configure the touchable
    var touchable = target.AddComponent<NearInteractionTouchableVolume>();
    touchable.EventsToReceive = TouchableEventType.Pointer;

    var material = target.GetComponent<Renderer>().material;
    // Change color on pointer down and up
    var pointerHandler = target.AddComponent<PointerHandler>();
    pointerHandler.OnPointerDown.AddListener((e) => material.color = Color.green);
    pointerHandler.OnPointerUp.AddListener((e) => material.color = Color.magenta);
}

グラブ イベント

下の例は、GameObject をドラッグ可能にする方法を示しています。 ゲーム オブジェクトにコライダーがあることを前提としています。

public static void MakeNearDraggable(GameObject target)
{
    // Instantiate and add grabbable
    target.AddComponent<NearInteractionGrabbable>();

    // Add ability to drag by re-parenting to pointer object on pointer down
    var pointerHandler = target.AddComponent<PointerHandler>();
    pointerHandler.OnPointerDown.AddListener((e) =>
    {
        if (e.Pointer is SpherePointer)
        {
            target.transform.parent = ((SpherePointer)(e.Pointer)).transform;
        }
    });
    pointerHandler.OnPointerUp.AddListener((e) =>
    {
        if (e.Pointer is SpherePointer)
        {
            target.transform.parent = null;
        }
    });
}

便利な API

関連項目