Appearance
当たり判定
物理系のモード(SimplePhysics・ KinematicCharacter・ DynamicCharacter)のオブジェクトは、 衝突したことを検知して処理を書くことができます。
使うためには、setMode()のオプションでcollisionDetection: trueを 指定しておく必要があります(デフォルトはfalse)。衝突する 両方のオブジェクトで有効にしてください。
js
obj.setMode('SimplePhysics',{collisionDetection: true});衝突を受け取る方法は2つあります。
ObjectA3.handleCollision()
オブジェクトのクラスを継承してhandleCollision()メソッドを 実装する方法です。「ぶつかったときにどうするか」をオブジェクト 自身に書けるので、ゲームのキャラクターやアイテムに向いています。
引数は、ぶつかった相手のオブジェクト、衝突の開始か終了か、 自分・相手のぶつかったパーツ番号の4つです。
以下はよく弾むボールを床に落とすサンプルです。バウンドのたびに 衝突の開始・終了がコンソールに表示されます。
js
import * as a3 from 'a3js';
// Sphereを継承してhandleCollision()を実装する
class MySphere extends a3.Sphere {
handleCollision(obj, started, myPartNo, yourPartNo) {
console.log(`衝突${started ? '開始' : '終了'}: `, obj);
}
}
await a3.initPhysics();
const view = new a3.Window(600,300);
view.camera.setPosition(0,0,10);
const ground = new a3.Box(10,0.5,10,"red");
ground.setMode('SimplePhysics',{rigidBody:'fixed', collisionDetection:true});
ground.setPositionNow(0,-3,0);
view.scene.add(ground);
// よく弾む(restitution:0.8)ボールを落とす
const ball = new MySphere('blue');
ball.setMode('SimplePhysics',{collisionDetection:true, restitution:0.8});
ball.setPositionNow(0,3,0);
view.scene.add(ball);相手が誰かによって処理を分けたいときは、instanceofで相手の クラスを調べるのが定番です。
js
handleCollision(obj, started, myPartNo, yourPartNo) {
if (!started) return; // 衝突開始のときだけ処理
if (obj instanceof Bullet) { // 弾丸が当たったときだけ処理
scene.remove(this);
}
}実戦的な使用例はTPSのサンプルプログラムを 参照してください。
Scene.setCollisionListener()
シーンに1つのリスナーを登録して、シーン内で起きたすべての衝突を まとめて受け取る方法です。衝突の組み合わせをまとめて管理したい 場合や、クラスを作らずに書きたい場合に向いています。
js
view.scene.setCollisionListener((collisions)=>{
for (const c of collisions) {
console.log(c.objectA, c.objectB, c.started);
}
});リスナーにはそのフレームで起きた衝突(Collision)の配列が 渡されます。Collisionは以下の情報を持っています。
objectA/objectB— 衝突した2つのオブジェクト。partOfA/partOfB— それぞれのぶつかったパーツのコライダー番号。started— 衝突開始のときtrue、衝突終了のときfalse。
センサー(物理的な衝突なしの検知)
collider: 'sensor'を指定すると、物理的な衝突(跳ね返り)を 起こさずに、通過したことだけを検知できます。ゴール判定や アイテムの取得に便利です。詳しくは SimplePhysicsモードと カーレースサンプルプログラムを 参照してください。