Entity
A-Frame represents an entity via the <a-entity>
element. As defined in the
entity-component-system pattern, entities are placeholder objects to
which we plug in components to provide them appearance, behavior, and
functionality.
A-Frameは<a-entity>
要素でエンティティを表現します。エンティティコンポーネントシステムパターンで定義されているように、エンティティとは、外観、動作、機能を提供するためにコンポーネントを差し込むプレースホルダーオブジェクトのことです。
A-Frameでは、エンティティは、位置、回転、[スケール][sclae]の各コンポーネントと本質的に結びついています。
# 例
下のような実体だけだけでは、外観も動作も機能もありません。何もしないのです。
<a-entity>
これにコンポーネントを取り付けて、何かをレンダリングさせたり、何かをさせたりすることができるのです。形状や外観を与えるために、ジオメトリとマテリアルのコンポーネントをアタッチすることができます。
<a-entity geometry="primitive: box" material="color: red">
発光させるためには、lightコンポーネントをつけます。
<a-entity geometry="primitive: box" material="color: red"
light="type: point; intensity: 2.0">
# Retrieving an Entity
DOM APIを使えば簡単にエンティティを取り出すことができます。
<a-entity id="mario"></a-entity>
var el = document.querySelector('#mario');
エンティティを取得すると、そのプロパティと以下のメソッドにアクセスできるようになります。
# プロパティ
# components
<a-entity>.components
は、エンティティに付属するコンポーネントのオブジェクトです。これにより、各コンポーネントのデータ、状態、メソッドを含むエンティティのコンポーネントにアクセスすることができます。
例えば、あるエンティティのthree.js
カメラオブジェクトやマテリアルオブジェクトを取得したい場合、そのコンポーネントにアクセスすることができます。
var camera = document.querySelector('a-entity[camera]').components.camera.camera;
var material = document.querySelector('a-entity[material]').components.material.material;
あるいは、コンポーネントがAPIを公開している場合は、そのメソッドを呼び出すこともできる。
document.querySelector('a-entity[sound]').components.sound.pause();
# hasLoaded
エンティティがすべてのコンポーネントをアタッチし、初期化したかどうかを確認します。 もっとも、エンティティが準備できた後にコードを実行するようにするには、コンポーネントの中にコードを配置するのが一番です。
# isPlaying
エンティティがアクティブであるかどうか、再生中であるかどうか。もし実体を一時停止すれば,isPlaying
はfalse
になる.
# object3D
<a-entity>.object3D
は、エンティティの three.js Object3D
(opens new window) 表現への参照を行います。具体的には、object3D
はTHREE.Group
オブジェクトとなり、カメラ、メッシュ、ライト、サウンドなど、さまざまなタイプのTHREE.Object3D
が含まれる可能性があります。
// Gaining access to the internal three.js scene graph.
var groupObject3D = document.querySelector('a-entity').object3D;
console.log(groupObject3D.parent);
console.log(groupObject3D.children);
Object3DMap
を通じて、様々なタイプのObject3D
にアクセスすることができます。
# object3DMap
An entity's object3DMap
is an object that gives access to the different types
of THREE.Object3D
s (e.g., camera, meshes, lights, sounds) that components
have set.
エンティティのobject3DMap
は、コンポーネントが設定したさまざまな種類のTHREE.Object3D
(カメラ、メッシュ、ライト、サウンドなど)にアクセスするためのオブジェクトです。
ジオメトリと[ライト][light}のコンポーネントがアタッチされているエンティティの場合、object3DMapは次のようになります。
{
light: <THREE.Light Object>,
mesh: <THREE.Mesh Object>
}
setObject3D
、removeObject3D
を使用することで、エンティティのTHREE.Object3D
セットを管理することができます。
# sceneEl
エンティティがそのシーンエレメントへの参照を持つことができます。
var sceneEl = document.querySelector('a-scene');
var entity = sceneEl.querySelector('a-entity');
console.log(entity.sceneEl === sceneEl); // >> true.
# メソッド
# addState (stateName)
addState
will push a state onto the entity. This will emit the stateadded
event, and we can check the state can for existence using .is
:
エンティティに状態(ステート)をプッシュします。これによりstateadded
イベントが発生し、.is
を使ってstate can
が存在するかどうかを確認することができます。
entity.addEventListener('stateadded', function (evt) {
if (evt.detail === 'selected') {
console.log('Entity now selected!');
}
});
entity.addState('selected');
entity.is('selected'); // >> true
# destroy ()
すべてのコンポーネントとそのデータをクリアするなど、エンティティに関連するメモリを一掃します。
# emit (name, detail, bubbles)
emit` は、エンティティに対してカスタム DOM イベントを発行します。例えば、以下のようなアニメーションをトリガーするイベントを発行することができます。
// <a-entity animation="property: rotation; to: 0 360 0; startEvents: rotate">
entity.emit('rotate');
また、第2引数としてイベントの詳細やデータを渡すことができます。
entity.emit('collide', { target: collidingEntity });
このイベントはデフォルトでバブル化されますが、バブル化しないようにするにはbubble
にfalse
を渡します。
entity.emit('sink', null, false);
# flushToDOM (recursive)
flushToDOM
will manually serialize an entity's components' data and update the DOM.
Read more about component-to-DOM serialization.
# getAttribute (componentName)
getAttribute
は、パースされたコンポーネントデータ (ミックスインやデフォルトを含む) を取得します。
// <a-entity geometry="primitive: box; width: 3">
entity.getAttribute('geometry');
// >> {primitive: "box", depth: 2, height: 2, width: 3, ...}
entity.getAttribute('geometry').primitive;
// >> "box"
entity.getAttribute('geometry').height;
// >> 2
entity.getAttribute('position');
// >> {x: 0, y: 0, z: 0}
もし componentName
が登録されたコンポーネントの名前でない場合、 getAttribute
がそのように動作します。
// <a-entity data-position="0 1 1">
entity.getAttribute('data-position');
// >> "0 1 1"
# getDOMAttribute (componentName)
getDOMAttribute
retrieves only parsed component data that is explicitly
defined in the DOM or via setAttribute
. If componentName
is the name of a
registered component, getDOMAttribute
will return only the component data
defined in the HTML as a parsed object. getDOMAttribute
for components is
the partial form of getAttribute
since the returned component data does not
include applied mixins or default values:
getDOMAttribute
は、解析されたコンポーネントのうち、DOM で定義されているか、 setAttribute
によって定義されている明示的に指定されたデータのみを取得します。
もし、 componentName
が登録されたコンポーネントをである場合、getDOMAttribute
はHTMLの中でオブジェクトとしてパースされたコンポーネントデータのみを返します。
コンポーネント用の getDOMAttribute
はgetattribute
の部分的なフォームです。
なので、返されたコンポーネントデータには適用されたミキシンやデフォルト値は含まれません。
上記のgetAttribute
の例での出力結果を比べてみましょう。
// <a-entity geometry="primitive: box; width: 3">
entity.getDOMAttribute('geometry');
// >> { primitive: "box", width: 3 }
entity.getDOMAttribute('geometry').primitive;
// >> "box"
entity.getDOMAttribute('geometry').height;
// >> undefined
entity.getDOMAttribute('position');
// >> undefined
# getObject3D (type)
getObject3D
は object3DMap
上のtype
で参照される子オブジェクト THREE.Object3D
を検索します。
AFRAME.registerComponent('example-mesh', {
init: function () {
var el = this.el;
el.setObject3D('mesh', new THREE.Mesh());
el.getObject3D('mesh'); // Returns THREE.Mesh that was just created.
}
});
# pause ()
pause()
は、アニメーションやコンポーネントで定義された動的な動作を停止させます。エンティティを一時停止すると、そのアニメーションが停止し、各コンポーネントで Component.pause()
が呼び出されます。コンポーネントは、一時停止時に何が起こるかを実装しますが、それは多くの場合、イベントリスナーを削除することが多いです。エンティティを一時停止すると、エンティティはその子エンティティに対してpause()
を呼び出します。
// <a-entity id="spinning-jumping-ball">
entity.pause();
例えば、この停止中のlook-controls コンポーネントは、入力をリッスンするイベントハンドラを削除します。
# play ()
play()
は、アニメーションやコンポーネントで定義された動的な動作を開始させます。これは、DOM がエンティティをアタッチしたときに自動的に呼び出されます。エンティティが play()
を実行すると、そのエンティティは子エンティティに対して play() を呼び出します。
entity.pause();
entity.play();
例えば、playのsoundコンポーネントは、音の再生を開始します。
# setAttribute (componentName, value, [propertyValue | clobber])
componentName
が登録されたコンポーネント名でない場合、またはコンポーネントが単独のプロパティコンポーネントの場合、setAttribute
は通常と同様に動作します。
entity.setAttribute('visible', false);
ただし、componentName
が登録されたコンポーネントの名前である場合、その値に対して特別なパージングを処理することがあります。例えば、positionコンポーネントはシングルプロパティコンポーネントですが、そのプロパティタイプパーサはオブジェクトを取得することを許可します。
entity.setAttribute('position', { x: 1, y: 2, z: 3 });
# 復数のプロパティを持つコンポーネントデータを更新する
復数のプロパティコンポーネントを持つコンポーネントデータを更新するには、登録されているコンポーネントの名前をcomponentName
として渡し、プロパティのオブジェクトをvalue
として渡します。文字列でも構いませんが(例:type: spot; distance: 30
)、オブジェクトの方がA-Frameのパース作業が軽減されます。
// Only the properties passed in the object will be overwritten.
entity.setAttribute('light', {
type: 'spot',
distance: 30,
intensity: 2.0
});
また、復数のプロパティコンポーネントの個々のプロパティを更新するには、登録されたコンポーネントの名前をcomponentName
、プロパティ名を第2引数、設定するプロパティ値を第3引数として渡します。
// All previous properties for the material component (besides the color) will be unaffected.
entity.setAttribute('material', 'color', 'crimson');
配列のプロパティタイプは一意的に動作することに注意してください。
- 配列は変更可能です。配列は参照によって割り当てられるので、配列の変更はコンポーネントによって可視化されます。
- 配列のプロパティが更新されても、コンポーネントの
update
メソッドは起動しませんし、イベントも発生しません。
# 復数のプロパティを持つコンポーネントデータを配置する
.setAttribute
の第3引数にtrue
が渡されると、指定されていないプロパティはリセットされ、clobbered
されます。
// All previous properties for the light component will be removed and overwritten.
entity.setAttribute('light', {
type: 'spot',
distance: 30,
intensity: 2.0
}, true);
# setObject3D (type, obj)
setObject3D
は、渡されたTHREE.Object3D
であるobj
をエンティティのobject3DMap
の下にtype
として登録します。
A-Frame
はobj
をエンティティのルートであるobject3D
の子要素として追加します。setObject3D
が呼ばれると、エンティティはtype
イベントの詳細でobject3dset
イベントを発行します。
AFRAME.registerComponent('example-orthogonal-camera', {
update: function () {
this.el.setObject3D('camera', new THREE.OrthogonalCamera());
}
});
# removeAttribute (componentName, propertyName)
componentName
が登録されたコンポーネントの名前である場合、DOM
から属性を削除すると同時に、removeAttribute
はコンポーネントを実体から切り離し、コンポーネントの remove
ライフサイクルメソッドを呼び出します。
entity.removeAttribute('geometry'); // Detach the geometry component.
entity.removeAttribute('sound'); // Detach the sound component.
propertyName
が指定された場合、removeAttribute
は propertyName
で指定されたそのプロパティの値をそのプロパティのデフォルト値にリセットする。
entity.setAttribute('material', 'color', 'blue'); // The color is blue.
entity.removeAttribute('material', 'color'); // Reset the color to the default value, white.
# removeObject3D (type)
removeObject3D
は、type
で指定されたオブジェクトをエンティティの THREE.Group
から、ひいてはシーンから削除します。
エンティティのobject3DMap
を更新し、type
キーの値をnull
に設定します。通常、コンポーネントから呼び出され、removeハンドラ内で使用されます。
AFRAME.registerComponent('example-light', {
update: function () {
this.el.setObject3D('light', new THREE.Light());
// Light is now part of the scene.
// object3DMap.light is now a THREE.Light() object.
},
remove: function () {
this.el.removeObject3D('light');
// Light is now removed from the scene.
// object3DMap.light is now null.
}
});
# removeState (stateName)
removeState
は、エンティティからステートをポップします。これはstateremoved
イベントを発生させ、.is
を使用して状態が削除されたことを確認することができます。
entity.addEventListener('stateremoved', function (evt) {
if (evt.detail.state === 'selected') {
console.log('Entity no longer selected.');
}
});
entity.addState('selected');
entity.is('selected'); // >> true
entity.removeState('selected');
entity.is('selected'); // >> false
# Events
イベント名 | 概要 |
---|---|
child-attached | 子エンティティがエンティティにアタッチされました。 |
child-detached | 子エンティティがエンティティから切り離された。 |
componentchanged | エンティティのコンポーネントの1つが変更された。このイベントはスロットルされています。位置や回転の変更の読み取りには使用せず、ティックハンドラを使用してください。 |
componentinitialized | エンティティのコンポーネントの 1 つが初期化されました。 |
componentremoved | エンティティのコンポーネントの 1 つが削除された。 |
loaded | エンティティのコンポーネントがアタッチされ、初期化されました。 |
object3dset | THREE.Object3D が setObject3D(name) でエンティティに設定された。イベント詳細には、object3DMap に設定するために使用したname が含まれます。 |
pause | エンティティが非アクティブになり、動的動作が一時停止しました。 |
play | エンティティは現在アクティブで、動的な動作の観点から再生されています。 |
stateadded | エンティティは新しい状態を受け取った。 |
stateremoved | エンティティがある状態を持たなくなった。 |
schemachanged | コンポーネントのスキーマが変更された。 |
# Event Detail
Below is what the event detail contains for each event:
Event Name | Property | Description |
---|---|---|
child-attached | el | 付属の子要素への参照。 |
componentchanged | name | データが変更されたコンポーネントの名前。 |
id | id データが変更されたコンポーネントのID。 | |
componentinitialized | name | 初期化されたコンポーネントの名前。 |
id | データが変更されたコンポーネントのID。 | |
data | コンポーネントのデータです。 | |
componentremoved | name | 削除されたコンポーネントの名前です。 |
id | 削除されたコンポーネントのIDです。 | |
stateadded | N/A | 付加された状態(文字列)。 |
stateremoved | N/A | 取り外された状態(文字列)。 |
schemachanged | component | Nスキーマが変更されたコンポーネントの名前。 |
# コンポーネントの変化をリッスンする
componentchanged
イベントを使用して、エンティティへの変更をリッスンすることができます。
entity.addEventListener('componentchanged', function (evt) {
if (evt.detail.name === 'position') {
console.log('Entity has moved to', evt.target.getAttribute('position'), '!');
}
});
# 子要素のアタッチメントとアタッチメント解除をリスニングする
child-attached
とchild-detached
イベントを使うと、シーンがエンティティをアタッチまたはデタッチするタイミングをリッスンすることができます。
entity.addEventListener('child-attached', function (evt) {
if (evt.detail.el.tagName.toLowerCase() === 'a-box') {
console.log('a box element has been attached');
};
});