raycasterコンポーネントは、レイキャスター (opens new window)によるラインベースの交差テストを提供します。レイキャスティングとは、原点からある方向に向かって線を伸ばし、その線が他のエンティティと交差しているかどうかをチェックする方法です。

raycasterコンポーネントはthree.jsのレイキャスター (opens new window)を使用します。レイキャスターは、オブジェクトのリストに対して一定の間隔で交差をチェックし、交差を検出したとき、または交差が解消されたとき(つまり、レイキャスターがエンティティと交差しなくなったとき)、エンティティにイベントを発します。

レイキャスターが交差をテストするオブジェクトのセットは、以下に説明するオブジェクトセレクタプロパティを介して明示的に定義されることを規定します。レイキャスティングは高価な操作であり、任意の時点で対話可能である必要があるターゲットのみに対してレイキャスティングする必要があります。

カーソルコンポーネントレーザーコントロールコンポーネントは、いずれもレイキャスターコンポーネントの上に構築されています。

#

<a-entity id="player" collider-check>
  <a-entity raycaster="objects: .collidable" position="0 -0.9 0" rotation="90 0 0"></a-entity>
</a-entity>
<a-entity class="collidable" geometry="primitive: box" position="1 0 0"></a-entity>

エンティティが collidable クラスを追加または削除するたびに、レイキャスターは、レイキャスターが当たっているオブジェクトのリストを更新します。

AFRAME.registerComponent('collider-check', {
  dependencies: ['raycaster'],

  init: function () {
    this.el.addEventListener('raycaster-intersection', function () {
      console.log('Player hit something!');
    });
  }
});

# Properties

Property Description Default Value
autoRefresh 追加または削除されたエンティティやコンポーネントを検出するための変異オブザーバ使用に際して、交差状態をテストするためにレイキャスターのオブジェクトのリストを自動的にリフレッシュするかどうかを指定します。 true
direction エンティティの原点を基準として、レイがどの方向を指すかを示すベクトル3の座標です。 0, 0, -1
enabled レイキャスターがアクティブに交差をチェックするかどうか。 true
far 結果のエンティティが返される最大距離。nearより小さくすることはできません。 Infinity
interval 各交差点テストの間に待機するミリ秒の数。更新を速くするためには、低い数値にします。数値が高いほどパフォーマンスが向上しまする。交差テストは1フレームにつき最大1回実行されます。 0
lineColor showLineが有効の場合に表示されるレイキャスターの線色 white
lineOpacity showLineが有効の場合に表示されるレイキャスターの透明度 white
near 結果のエンティティが返される最小距離。0より小さくすることはできません。 0
objects 交差をテストするためのオブジェクトを選択する際に使用するクエリセレクタ。指定しない場合は、すべてのエンティティがテストされます。 注 .setObject3Dでアタッチされたオブジェクトとその再帰的な子オブジェクトのみがテストされます。 null
origin エンティティの原点を基準として、レイを発生させる位置のベクトル3の座標です。 0, 0, 0
showLine レイキャスターをラインコンポーネントとして視覚的に表示するかどうか。 false
useWorldCoordinates レイキャスターの原点と方向のプロパティをワールド座標で指定するかどうか。 false

# イベント

レイキャスターコンポーネントは、エンティティにイベントを発行するため便利です。レイキャスティングエンティティと交差しているエンティティの両方でイベントを発行します。

Event Name 概要
raycaster-intersected 交差しているエンティティに発行されます。エンティティはレイキャスターと交差しています。イベントの詳細には、レイキャストのエンティティであるelと、交差点、および現在の交差点データを取得するために使用できる.getIntersection (el)関数が含まれます。
raycaster-intersected-cleared 交差しているエンティティに発行されます。エンティティは、もはやレイキャスターと交差していません。イベントの詳細には、レイキャストのエンティティであるelが含まれます。
raycaster-intersection レイキャスティングされたエンティティに発行されます。レイキャスターは1つ以上のエンティティと交差している状態です。イベント詳細には、新たに交差したエンティティ、交差点、および現在の交差点データを取得するために使用できる .getIntersection (el) 関数を含む配列、els が含まれます。交差点(既存および新規)の完全なリストへのアクセスは、Members intersectedElsを参照してください。
raycaster-intersection-cleared レイキャスティングエンティティで発行されます。レイキャスターは、1つ以上のエンティティとの交差がなくなりました。イベントの詳細には、以前交差していたエンティティを含む配列であるclearElsが含まれます。
raycaster-closest-entity-changed 最も近い交差しているエンティティが変更されました。

# 交差オブジェクト

イベント詳細には、交差点オブジェクトが含まれる。それらはthree.js Raycaster.intersectObjects (opens new window)から直接返されます。

Property 概要
distance 光線の原点から交差点までの距離
point ワールド座標系での光線の交差点
face 交差する面
faceIndex 交差する面のインデックス
indices 交差する面を構成する頂点のインデックス
object 交差したオブジェクト
uv 交点におけるU,V座標

# メンバー

Member 概要
intersectedEls 現在レイキャスターと交差しているエンティティ。
objects 交差をテストするための three.js オブジェクト。objects プロパティが指定されていない場合、scene.children になります。
raycaster three.jsのレイキャスターオブジェクト。

# メソッド

Method 概要
getIntersection (el) エンティティを指定し、現在の交差点データがあれば返します。このメソッドは、便宜上、交差点イベントの詳細にも渡されます。
refreshObjects objectsプロパティに基づいてオブジェクトのリストをリフレッシュし、交差をテストします。

# 交差をテストするエンティティを選択する

レイキャスティングは比較的高価な操作です。私たちはレイキャスターが交差のためにリッスンしているエンティティをフィルタリングするobjectsプロパティを設定しておくことを強く推奨しています。交差点テストは1秒間に何度も行われる操作なので、交差点をテストするエンティティの数を制限するために、テストする交差点を選択しておくことはパフォーマンスにとって良いものです。

交差をテストしたいエンティティを選択するには、objects プロパティを使用します。このプロパティが定義されていない場合、レイキャスターはシーン内のすべてのオブジェクトの交差をテストします。

<a-entity raycaster="objects: .clickable" cursor></a-entity>
<a-entity class="clickable" geometry="primitive: box" position="1 0 0"></a-entity>
<a-entity class="not-clickable" geometry="primitive: sphere" position="-1 0 0"></a-entity>

その例では、clickable クラス (el.classList.toggle('clickable'))を設定または削除することで、レイキャストリストにエンティティを削除または追加できます。もう1つの良いフィルタリング方法は、クラスの代わりにデータ属性を使うことです([data-raycastable]el.setAttribute('data-raycastable', ''))

# Raycasterの交差点データ変更をリスニングする

交差点データの変化をリスニングしたい場合(例えば、実際の交差点の変化をリスニングする)、.getIntersection (el) メソッドを使用します。これはエンティティを取得し、レイキャスターが現在エンティティと交差している場合は交差点データを返します。下記は、ティックハンドラでこれを行うためのコンポーネント例です。

AFRAME.registerComponent('raycaster-listen', {
	init: function () {
    // Use events to figure out what raycaster is listening so we don't have to
    // hardcode the raycaster.
    this.el.addEventListener('raycaster-intersected', evt => {
      this.raycaster = evt.detail.el;
    });
    this.el.addEventListener('raycaster-intersected-cleared', evt => {
      this.raycaster = null;
    });
  },

  tick: function () {
    if (!this.raycaster) { return; }  // Not intersecting.

    let intersection = this.raycaster.components.raycaster.getIntersection(this.el);
    if (!intersection) { return; }
    console.log(intersection.point);
  }
});

// <a-entity id="raycaster" raycaster></a-entity>
// <a-entity geometry material raycaster-listen></a-entity>

これで、毎フレームごとにエンティティはその交差点データをチェックし、それを使って何かをします(例えば、交差点に球を描くなど)。

# レイキャスターのターゲット・エンティティを手動でリフレッシュする

レイキャスターコンポーネントは、レイキャスターが交差をテストするオブジェクトとエンティティのローカル配列を保持します。この配列のデフォルトは three.jsのシーン内にある全ての 3D オブジェクトです。objects プロパティが指定された場合、この配列を構築するために、クエリセレクタと追加のフィルタリングを実行する必要があります。

デフォルトで autoRefreshtrue に設定されている場合、レイキャスターコンポーネントはエンティティまたはコンポーネントが追加および削除されたことを検出すると、このリストを自動的にリフレッシュします。自動更新の方が親切ですが、より高度な開発者は、パフォーマンスのために autoRefresh を無効にして、レイキャスターが更新されるタイミングを制御したいと思うかもしれません。

レイキャスターコンポーネントがテストするオブジェクトのリストを手動でリフレッシュするには、 .refreshObjects() メソッドを呼び出します。

var raycasterEl = AFRAME.scenes[0].querySelector('[raycaster]');
raycasterEl.components.raycaster.refreshObjects();

A-Frameは、エンティティがシーンに追加されたり、シーンから切り離されたりすると、自動的に.refreshObjects()を呼び出しますが、通常のDOM変異時(例えば、あるエンティティがそのクラスを変更する時)には呼び出されません。

# 線をカスタマイズする

showLinetrueに設定された場合、レイキャスターはレイキャスターの原点 origin、 方向 directionfarプロパティを与えられたラインを構成します。showLine: true プロパティで提供される線の外観をカスタマイズするには、lineColor と lineOpacity を使用します。

<a-entity raycaster="showLine: true; far: 100; lineColor: red; lineOpacity: 0.5"></a-entity>

The line length is the raycaster's far property when the raycaster is not intersecting any entity. By default, the far property defaults to 1000 meters meaning the line drawn will be 1000 meters long. When the raycaster intersects an object, the line will get truncated to the intersection point so it doesn't shoot straight through.

線の長さは、レイキャスターがどのエンティティとも交差していないときのレイキャスターのfarプロパティの値になります。デフォルトでは、farプロパティは1000メートルに設定されており、描かれる線の長さは1000メートルになります。レイキャスターがオブジェクトと交差するとき、線は交差点で切り捨てられ、突き抜けません。