エンティティ操作
このチュートリアルでは、エンティティの位置 (Position) 、向き (Orientation) 、スケール (Scale) を変更する方法を紹介します。
エンティティは、PlayCanvasフレームワークを使用して構築されたほとんどのアプリケーションの基盤となります。エンティティは、プレイヤーキャラクター、弾丸、敵キャラクター、または単に空間上の点など、あらゆるものを表すことができます。
エンティティは、グラフノードの特殊な形態であり、pc.GraphNode
から多くの振る舞いを継承しています。以下で説明する操作は、グラフノードにも適用することができます。
エンティティ上で行う最も一般的な操作の1つは、そのトランスフォーム行列を変更することです。エンティティのローカルトランスフォームプロパティは、エンティティの位置、向き、スケールを決定し、すべての子エンティティにも影響を与えます。トランスフォームを操作する方法を学ぶことは、興味深くインタラクティブなアプリケーションを作る上で重要です。
ローカルとワールド座標
エンティティの移動や操作方法を理解する上で重要なのは、ローカル座標系とワールド座標系の理解です。ワールド座標系はすべ てのエンティティで共有されており、固定された原点 (0,0,0)
と固定された向きがあります。ワールド座標系では、(0,1,0)
が上を向いています。ローカル座標系はエンティティ自体に対する相対的な座標系です。したがって、ローカル原点はエンティティの位置であり、向きはエンティティの向きに従います。
Here is a visual representation of the world-space coordinate system (left) and the local-space coordinate system (right) of an entity:
ヒエラルキー (Hierarchy)
エンティティシステムを理解する上で重要な要素は、エンティティグラフまたはヒエラルキーです。エンティティはグラフノードの一種であり、親子関係を持ったグラフまたはヒエラルキーにまとめられます。各エンティティは1つの親を持ち、複数の子を持つことができます。子エンティティは親からの変換情報を継承します。エンティティのワールド変換行列は、ローカル変換を親エンティティのワールド変換行列と乗算することで計算されます。たとえば、子エンティティのローカル移動が(1,0,0)
であり、親エンティティのローカル移動が(0,1,0)
である場合、子エンティティのワールド位置は(1,1,0)
になります。
ポジション (Position)
エンティティの位置を取得するには、下記のように書きます。
// エンティティの相対位置を取得する
var lp = entity.getLocalPosition();
// エンティティのワールド空間内の位置を取得する
var wp = entity.getPosition();
これらの方法はともに pc.Vec3
(配列形式のベクトル量[x、y、z])を返します。
エンティティの位置を設定するには、下記の方法を使用するだけです。
// エンティティの相対位置を設定する
entity.setLocalPosition(x、y、z);
// エンティティのワールド空間内の位置を設定する
entity.setPosition(x、y、z);
エンティティの移動
エンティティを移動するには、エンティティの位置に加算するか、ヘルパー関数 translate
および translateLocal
を使用することができます。
// エンティティをワールド空間の正のx軸方向に1ユニット移動する
entity.translate(1, 0, 0);
// エンティティをエンティティのローカルz軸方向に1ユニット移動する
entity.translateLocal(0、0、1);
オリエンテーション (Orientation)
エンティティの向きを設定するには、絶対回転を設定するか、増分回転を適用することができます。
絶対回転は、オイラー角またはクォータニオンを使用して行うことができます。回転のこれらの2つの数学的表現に関するWikipediaの説明は少し分かりにくいですが、基本的な考え方は簡単です。以下が重要な事実です。
Euler Angles
- オイラー角(Euler angles)は、座標系の X軸、Y軸、Z軸の順 に、度数法で表される3つの回転です。
- 座標系の軸を見下ろす場合、正のオイラー角は、その軸を中心に反時計回りに回転します。
- オイラー角はわかりやすいため、その影響を頭で視覚化できます。
Quaternions
- クォータニオンは4つの数字として格納され、3D空間の任意の向きを表します。
- 直接設定することは困難ですが、オイラー角、回転行列、または軸角度表現から設定できます。
- 視覚化するのは難しいですが、頑健で回転を素早く補完できるので便利です(回転をアニメーション化する場合)。
エンティティのスクリプト化時、オイラー角を使用してエンティティの回転を設定することがより可能性が高いことがあります。例えば:
// 親エンティティ座標系のX軸を中心に反時計回りに30度回転し、
// 次にY軸を中心に45度回転し、最後にZ軸を中心に60度回転します。
entity.setLocalEulerAngles(30、45、60);
// ワールド空間のX軸を中心に反時計回りに30度回転し、
// 次にY軸を中心に45度回転し、最後にZ軸を中心に60度回転します。
entity.setEulerAngles(30、45、60);
ただし、クォータニオン形式でエンティティの回転角度を設定する場合、次の関数を使用できます。
// 単位回転クォータニオンを作成
var q = new pc.Quat();
// 親エンティティと同じ回転を持つようにエンティティを設定します。-等しい
// 開始時エンティティ.setLocalEulerAngles(0、0、0)
entity.setLocalRotation(q);
// エンティティの回転を、ワールドスペース座標系に対する回転なしとして設定します。
// - 等価 entity.setEulerAngles(0, 0, 0)。
entity.setRotation(q)。
エンティティを増分的に回転させるには、 rotate
を使用してエンティティをワールド空間の軸に対して回転させ、 rotateLocal
を使用してエンティティの現在の軸に対して回転させます。
たとえば、ワールド空間のアップ軸を中心にエンティティを180度回転するには次のようにします。
entity.rotate(0, 180, 0);
または、ローカルX軸の周りにエンティティを90度回転させるには:
entity.rotateLocal(90, 0, 0);
スケール (Scale)
エンティティを拡大縮小するには次の関数を呼び出します:
// ローカルY軸でエンティティを2の倍数でスケール
entity.setLocalScale(1, 2, 1);
もう少し興味深い例を紹介します:
// 時間上でsine関数を使用してエンティティをスケール
this.timer += deltaTime;
var s = Math.sin(this.timer) + 1;
entity.setLocalScale(s, s, s);
現在、ワールド空間でエンティティのスケールを設定することはできません。