近い対話機能を追加する方法 - MRTK2
近接対話は、タッチとグラブの形で行われます。 タッチとグラブの各イベントは、それぞれ Pokepointer と SpherePointer によってポインター イベントとして発生します。
特定の GameObject に対するタッチやグラブの入力イベントをリッスンするには、3 つの重要なステップが必要です。
- 関連するポインターがメインの MRTK 構成プロファイルに登録されていることを確認します。
- 目的の GameObject に、適切なグラブまたはタッチ スクリプト コンポーネントと
Unity Collider
があることを確認します。 - 目的の GameObject にアタッチされたスクリプトに、グラブまたはタッチの各イベントをリッスンするための入力ハンドラー インターフェイスを実装します。
グラブ操作の追加
MRTK ポインター プロファイルに SpherePointer が登録されていることを確認します。
既定の MRTK プロファイルと既定の HoloLens 2 プロファイルには、既に SpherePointer が含まれています。 SpherePointer が作成されることを確認するには、MRTK 構成プロファイルを選択し、[入力]>[ポインター]>[ポインターのオプション] に移動します。 既定
GrabPointer
のプレハブ (Assets/MRTK/SDK/Features/UX/Prefabs/Pointers) は 、コントローラーの種類 の 多関節ハンドと共に一覧表示する必要があります。 カスタム プレハブは、SpherePointer
クラスが実装されている限り利用できます。既定のグラブ ポインターは、既定のHoloLens 2 インターフェイスに一致するように、グラブ ポイントの周りの円錐形の近くのオブジェクトに対してクエリを実行します。
つかめるようにする必要のある GameObject で、
NearInteractionGrabbable
と、コライダーを追加します。GameObject のレイヤーが、つかめるレイヤー上にあるようにしてください。 既定では、"空間認識" と "レイキャストを無視" を除くすべてのレイヤーがつかめるようになっています。 どのレイヤーがつかめるかは、GrabPointer プレハブの "グラブ レイヤー マスク" を調べるとわかります。
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
クラスが実装されている限り利用できます。
3D GameObject
3D GameObject にタッチ操作を追加するには、3D オブジェクトにタッチ可能な平面を 1 つだけにする場合と、コライダー全体に基づきタッチ可能にする場合とで、2 つの異なる方法があります。 最初の方法は、通常、BoxCollider を使用したオブジェクトです。ここでは、コライダーの 1 つの面だけがタッチ イベントに反応するようにする必要があります。 もう 1 つは、コライダーに基づいて任意の方向からタッチできるようにする必要があるオブジェクトです。
単一面のタッチ
これは、1 つの面だけをタッチ可能にする必要がある場合に役立ちます。 このオプションは、ゲーム オブジェクトに BoxCollider があることを前提としています。 これを BoxCollider がないオブジェクトに使用することもできます。その場合は、[境界] と [ローカル センター] の各プロパティを手動で設定して、タッチ可能な平面を構成します (つまり、境界は 0 - 0 以外の値に設定する必要があります)。
タッチ可能にする必要がある GameObject に BoxCollider とコンポーネントを
NearInteractionTouchable
追加します。下のコンポーネント スクリプトで
IMixedRealityTouchHandler
インターフェイスを使用する場合は、[受け取るイベント] を [タッチ] に設定します。[境界を修正する] と [センターを修正する] をクリックします。
そのオブジェクトまたはその先祖の 1 つに、以下を実装するスクリプト コンポーネントを追加します。
IMixedRealityTouchHandler
インターフェイス。NearInteractionTouchable
を持つオブジェクトの先祖はすべて、ポインター イベントも受け取ることができます。
Note
NearInteractionTouchable の GameObject が選択されているエディターのシーン ビューで、白いアウトラインの正方形と矢印を確認します。 矢印は、タッチ可能な "面" を指しています。 接触可能なものは、その方向からのみタッチ可能になります。 コライダーを全方向からタッチ可能にするには、「任意のコライダーのタッチ」のセクションを参照してください。
任意のコライダーのタッチ
これは、ゲーム オブジェクトをコライダーの面全体に沿ってタッチ可能にする必要がある場合に役立ちます。 たとえば、これを使用して、コライダー全体をタッチ可能にする必要のある、SphereCollider を持つオブジェクトのタッチ操作を有効にすることができます。
タッチ可能にする必要がある GameObject に、コライダーとコンポーネントを
NearInteractionTouchableVolume
追加します。- 下のコンポーネント スクリプトで
IMixedRealityTouchHandler
インターフェイスを使用する場合は、[受け取るイベント] を [タッチ] に設定します。
- 下のコンポーネント スクリプトで
そのオブジェクトまたはその先祖の 1 つに、以下を実装するスクリプト コンポーネントを追加します。
IMixedRealityTouchHandler
インターフェイス。NearInteractionTouchable
を持つオブジェクトの先祖はすべて、ポインター イベントも受け取ることができます。
Unity UI
シーンに UnityUI キャンバスがあることを確認、あるいは追加します。
タッチ可能にする必要がある GameObject に、
NearInteractionTouchableUnityUI
コンポーネントを追加します。- 下のコンポーネント スクリプトで
IMixedRealityTouchHandler
インターフェイスを使用する場合は、[受け取るイベント] を [タッチ] に設定します。
- 下のコンポーネント スクリプトで
そのオブジェクトまたはその先祖の 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
NearInteractionGrabbable
NearInteractionTouchable
NearInteractionTouchableUnityUI
NearInteractionTouchableVolume
IMixedRealityTouchHandler
IMixedRealityPointerHandler