レイキャスター
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
プロパティが指定された場合、この配列を構築するために、クエリセレクタと追加のフィルタリングを実行する必要があります。
デフォルトで autoRefresh
が true
に設定されている場合、レイキャスターコンポーネントはエンティティまたはコンポーネントが追加および削除されたことを検出すると、このリストを自動的にリフレッシュします。自動更新の方が親切ですが、より高度な開発者は、パフォーマンスのために autoRefresh
を無効にして、レイキャスターが更新されるタイミングを制御したいと思うかもしれません。
レイキャスターコンポーネントがテストするオブジェクトのリストを手動でリフレッシュするには、 .refreshObjects()
メソッドを呼び出します。
var raycasterEl = AFRAME.scenes[0].querySelector('[raycaster]');
raycasterEl.components.raycaster.refreshObjects();
A-Frame
は、エンティティがシーンに追加されたり、シーンから切り離されたりすると、自動的に.refreshObjects()
を呼び出しますが、通常のDOM変異時(例えば、あるエンティティがそのクラスを変更する時)には呼び出されません。
# 線をカスタマイズする
showLine
がtrue
に設定された場合、レイキャスターはレイキャスターの原点 origin
、 方向 direction
、far
プロパティを与えられたラインを構成します。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メートルになります。レイキャスターがオブジェクトと交差するとき、線は交差点で切り捨てられ、突き抜けません。