Raycastを使ってイベントを発火させる
今回作成していく処理のRaycastは、カメラから見てマウスと重なるCollisionを持つ3Dモデルをクリックしたら、その3DモデルのEntity情報を取得するといったものになります。
早速 raycast.js をAssets上に作っていきましょう。
先ほどまではRoot Entityにスクリプトを追加していましたが、
今回はメインカメラのCamera Entityにスクリプトを追加します。
raycast.js にコードは以下に書き換えます。
var Raycast = pc.createScript('raycast');
Raycast.prototype.initialize = function() {
this.rayStart = new pc.Vec3(); // カメラからのRay
this.rayEnd = new pc.Vec3(); // カメラから見てぶつかったRay
if(!this.app.touch) { // タッチ操作でない場合
this.app.mouse.on(pc.EVENT_MOUSEDOWN, this.onMouseClick, this); // マウスクリックイベント
this.app.mouse.on(pc.EVENT_MOUSEMOVE, this.onMouseMove, this); // マウスムーブイベント
} else {
this.app.touch.on(pc.EVENT_TOUCHSTART, this.onMouseClick, this); // タッチ操作イベント
}
};
Raycast.prototype.onMouseClick = function(e) {
if(e.button === pc.MOUSEBUTTON_LEFT) { // 左ボタンの場合
this.doRaycast(e.x, e.y); // マウスの座標を引数で渡す
}
if(this.app.touch && e.touches.length === 1){ // タッチ操作が一つの場合
this.doRaycast(e.touches[0].x, e.touches[0].y); // タッチした座標を渡す
}
};
Raycast.prototype.onMouseMove = function(ev) {
var farClip = this.entity.camera.farClip; // カメラのfarClipの設定(Editorから設定可能)
var nearClip = this.entity.camera.nearClip; // カメラのnearClipの設定(Editorから設定可能)
this.entity.camera.screenToWorld(ev.x, ev.y, nearClip, this.rayStart); // 平面座標から3D空間へ座標を変換しRaycastの始まりの座標を作成
this.entity.camera.screenToWorld(ev.x, ev.y, farClip, this.rayEnd); // 平面座標から3D空間へ座標を変換しRaycastの終わりの座標を作成
// ↓ ここでレイキャストの処理を書いているよ
this.result = this.app.systems.rigidbody.raycastFirst(this.rayStart, this.rayEnd); // 作成した座標を元に当たり判定を持つEntityとぶつかったか結果を出す
};
Raycast.prototype.doRaycast = function (screenX, screenY) { // Raycast処理を使って
if (this.result) { // raycastの結果が出ているか
var hitEntity = this.result.entity; // Raycastで取得したEntity
console.log(hitEntity);
}
};
その後、各Scene1,2,3...に配置している3DモデルのEntityを選択し、Collisionを追加して当たり判定を作ります。
ここで Import Ammo と書かれたボタンが表示されていれば、クリックしてAmmoをインポートしてください。
Ammo.js はJavaScriptの物理演算エンジンなので、入れておけば物理演算がいい感じになると思います。
Launchで確認するとCollisionを入れた3Dモデルをクリックするとconsole.logでEntityが取得できていることが確認できます。
RaycastでEntityを取得までできました。
このRaycastのイベントを使って処理を作っていきます。
スワイプでカメラがTweenして場面を変えてくれていますが、RaycastでもカメラがTweenしてくれるようにします。
ここでの3DモデルはBoxを使用しているのでBoxで説明していきます。
前のSceneと次のSceneに移動するようにBoxをもう一つずつ増やしていきます。
Boxを複製して、前のSceneへ移動するBoxをPrev、次のSceneへ移動するBoxをNextとします。
それぞれのBoxのTagsに「prev」、「next」を付与します。
それぞれ作成できたらコピーして他のSceneにペースとしておきます。
Tagsを追加したのは、クリックしたEntityがTagsに「prev」が付いていれば前のSceneに移動するといった処理を行うためです。
ではその処理を raycast.js に追記していきます。
doRaycastをいかに書き換えます。
Raycast.prototype.doRaycast = function (screenX, screenY) { // Raycast処理を使って
if (this.result) { // raycastの結果が出ているか
var hitEntity = this.result.entity; // Raycastで取得したEntity
if(hitEntity.tags._list.includes("prev")) { // tagsにprevがある場合
this.app.fire("cameraMove:tween", -1); // カメラTweenで一つ前のSceneへ
}else if(hitEntity.tags._list.includes("next")) { // tagsにpnextがある場合
this.app.fire("cameraMove:tween", 1); // カメラTweenで一つ次のSceneへ
}
}
};
Launchで確認すると、Boxをクリックするとカメラが前後にTweenするのが確認できます。
これで、スワイプとクリックでScene移動が可能になり、UXが充実してきました。
ここまでできたら、次はDomの表示も行なっていきます。
コメント
0件のコメント
サインインしてコメントを残してください。