XR Interaction Toolkit の拡張
継承 や合成により、XR Interaction Toolkit システムを拡張することができます。Interactor (能動側、インタラクター) と Interactable (受動側、インタラクタブル) はどちらも、抽象基本クラスから派生します。派生元のクラスをインタラクションマネージャーに接続して、独自の機能を実装することができます。加えて、イベントコールバックを使用して既存のコンポーネントに機能を追加することもできます。下図は既存の Interactor クラスと Interactable クラスがどのように基本クラスを継承するかを示しています。
このドキュメントでは、XR Interaction Toolkit の拡張を行う方法を詳しく説明します。
インタラクターとインタラクタブルのイベントコールバック
インタラクターとインタラクタブルはどちらも各種のイベントコールバックを備えており、それらを活用してインタラクションステートの変化に対応します。これらのイベントを使用すると、コードを追加せずに、ホバー、選択、アクティベートというステート変化に対する独自の動作を定義することができます。
インタラクターの拡張
XRBaseInteractor
または XRBaseControllerInteractor
抽象基本クラスから派生させることで、ゲーム世界とのインタラクションを独自に定義できます。Unity には現在、Direct (衝突) Interactor と Ray Interactor がありますが、ユーザーが世界内のオブジェクトをどのように選択するかや、オブジェクトを操作して何ができるかを定義することができます (通常は Base Interactable クラスを派生させて後者を実施します)。
標準の Unity コールバックに加えて、以下のメソッドやプロパティをオーバーライドすることができます。
メソッド/プロパティ | 説明 |
---|---|
GetValidTargets |
このインタラクターがこのフレームで操作できるインタラクタブルのリストを取得します。 |
isHoverActive |
このインタラクターがホバーを実行できるステートである場合は true を返し、そうでない場合は false を返します。 |
isSelectActive |
このインタラクターが選択を実行できるステートであるかどうかを取得します。 |
CanHover |
このインタラクターが選択を実行できるステートである場合は true を返し、そうでない場合は false を返します。 |
CanSelect |
このフレームでインタラクタブルが選択対象として有効である場合は true を返し、そうでない場合は false を返します。 |
selectedInteractableMovementTypeOverride |
選択されているインタラクタブルの動きをオーバーライドする際に使用する動きの種類を取得します。 |
OnRegistered と OnUnregistered |
インタラクターの登録時や登録解除時にインタラクションマネージャーがこれらのメソッドを呼び出します。 |
OnHoverEntering と OnHoverEntered |
インタラクターがインタラクタブルのホバーを最初に開始するときに、インタラクションマネージャーがこれらのメソッドを呼び出します。 |
OnHoverExiting と OnHoverExited |
インタラクターがインタラクタブルのホバーを終了するときに、インタラクションマネージャーがこれらのメソッドを呼び出します。イベント引数は、無効であるか除去されていて登録されていないなどの原因で、ホバーがキャンセルされたかどうかを示します。 |
OnSelectEntering と OnSelectEntered |
インタラクターがインタラクタブルの選択を最初に開始するときに、インタラクションマネージャーがこれらのメソッドを呼び出します。 |
OnSelectExiting と OnSelectExited |
インタラクターがインタラクタブルの選択を終了するときに、インタラクションマネージャーがこれらのメソッドを呼び出します。イベント引数は、無効であるか除去されていて登録されていないなどの原因で、選択がキャンセルされたかどうかを示します。 |
インタラクタブルの拡張
XRBaseInteractable
抽象基本クラスから派生させることで、ゲーム世界とのインタラクションを独自に定義できます。現行の Unity には Grab Interactable しかありませんが、掴む動作を取り入れる必要がある場合に、基本クラスから独自のインタラクタブルを作成したり、Grab Interactable を派生させたりすることができます。
標準の Unity コールバックに加えて、以下のメソッドをオーバーライドすることができます。
メソッド | 説明 |
---|---|
IsHoverableBy |
指定のインタラクターがこのインタラクタブルをホバーできるかどうかを判別します。 |
IsSelectableBy |
指定のインタラクターがこのインタラクタブルを選択できるかどうかを判別します。 |
OnRegistered と OnUnregistered |
インタラクタブルの登録時や登録解除時にインタラクションマネージャーがこれらのメソッドを呼び出します。 |
OnHoverEntering と OnHoverEntered |
インタラクターがインタラクタブルのホバーを最初に開始するときに、インタラクションマネージャーがこれらのメソッドを呼び出します。 |
OnHoverExiting と OnHoverExited |
インタラクターがインタラクタブルのホバーを終了するときに、インタラクションマネージャーがこれらのメソッドを呼び出します。イベント引数は、無効であるか除去されていて登録されていないなどの原因で、ホバーがキャンセルされたかどうかを示します。 |
OnSelectEntering と OnSelectEntered |
インタラクターがインタラクタブルの選択を最初に開始するときに、インタラクションマネージャーがこれらのメソッドを呼び出します。 |
OnSelectExiting と OnSelectExited |
インタラクターがインタラクタブルの選択を終了するときに、インタラクションマネージャーがこれらのメソッドを呼び出します。イベント引数は、無効であるか除去されていて登録されていないなどの原因で、選択がキャンセルされたかどうかを示します。 |
OnActivated と OnDeactivated |
選択されたインタラクタブルでインタラクターがアクティベーションイベントを開始するときやアクティベーションを終了するときに、Controller Interactor がこれらのメソッドを呼び出します。 |
複数のインタラクターが 1 つのインタラクタブルを同時にホバーすることができます。firstHoverEntered
イベントと lastHoverExited
イベントを使用して、最初のホバーが開始されたときにハイライトし、すべてのホバーが中止された後にハイライトを解除するよう、オブジェクトのハイライト状態を制御することができます。同様に firstSelectEntered
イベントと lastSelectExited
イベントを使用して、インタラクタブルの複数選択をサポートすることができます。
インタラクタブルの選択モード
インタラクタブルの selectMode
は選択ポリシーを設定するために使用します。この値は選択の試行時にインタラクションマネージャーに読み取られるだけであるため、この値を Multiple (複数) から Single (単一) に変更しても、選択は中止されません。
選択モード | 説明 |
---|---|
Single | 一度に 1 つのインタラクターだけが選択を実行することができ、他のインタラクターが選択を行うと、それまでの選択は自動で解除されます。 |
Multiple | 複数のインタラクターが同時に選択を行うことができます。 |
Multiple オプションは、コンポーネントスクリプトで CanSelectMultiple
属性を使用することにより、Inspector ウィンドウで無効化できます。
using UnityEngine.XR.Interaction.Toolkit;
[CanSelectMultiple(false)]
public class ExampleInteractable : XRBaseInteractable
{
}
Inspector
カスタムの Editor クラスは、Inspector での見た目やプロパティの表示順を変更するために使用し、特にインタラクターやインタラクタブルに関してよく使用されます。派生した動作でシリアライズされたフィールド (public
か SerializeField
属性のフィールド) を追加すると、Inspector に自動で表示されます。Editor クラスを拡張して Inspector をさらにカスタマイズすることができます。その場合、SerializedProperty
として宣言され割り当てられたフィールドは、DrawDerivedProperties
で自動的に描画されません。これらの派生した Editor クラス内では、通常は OnInspectorGUI
全体ではなく、XRBaseInteractorEditor
や XRBaseInteractableEditor
の DrawProperties
などのメソッドをオーバーライドするだけで対応できます。
// アセット内の ExampleInteractable.cs
public class ExampleInteractable : XRBaseInteractable
{
[SerializeField]
bool m_AdditionalField;
}
// アセット内の Editor フォルダーに含まれる ExampleInteractableEditor.cs は
// SerializedProperty を明示的に定義して
// デフォルトの場所でなく、Inspector のどこに表示するかを
// 指定します。
[CustomEditor(typeof(ExampleInteractable), true), CanEditMultipleObjects]
public class ExampleInteractableEditor : XRBaseInteractableEditor
{
protected SerializedProperty m_AdditionalField;
protected override void OnEnable()
{
base.OnEnable();
m_AdditionalField = serializedObject.FindProperty("m_AdditionalField");
}
protected override void DrawProperties()
{
base.DrawProperties();
EditorGUILayout.PropertyField(m_AdditionalField);
}
}
また、Editor.DrawDefaultInspector
メソッドを使用して、ビルトインの Inspector を描画することができます。カスタムの Editor
クラスを作成する代わりに、PropertyDrawer
クラスも利用できます。