Cocos Creator で 3Dブロック崩しゲームを作る続きです。

今回の目標
ボールが動いて跳ね返る処理を作っていきます。

ボールを追加
まず、前回作った枠の中にボールを追加します。
New 3D Stage を選択してから右クリックで Create > Create 3D Node > Sphere の順で選択していきます。

ボールの設定を変更
追加した Sphere の設定を変更します。
- 名前を「Ball」に変更。
- Position を「Y=20」に変更。
- Scale を「X=25, Y=25, Z=25」に変更。
- 黄色のマテリアルを作成。
- 黄色のマテリアルをボールに設定。

以上の設定を施したのがこちらです。

ボールを動かす
次にボールが動くように設定します。
RigidBodyコンポーネント を追加
ボールに リジッドボディ3Dコンポーネント を追加することで、ボールが重力の影響を受けるようになります。
追加方法は、ボールを選択してから Add Component ボタンを押して Physics Component > Rigid Body 3D の順で選択します。

ボールに Rigid Body 3D が追加されればOK

Rigid Body 3D の設定を変更します。
- Linear Damping (線形減衰) を 0 に変更します。そうすると、スピードが落ちなくなります。
- Angular Damping (角ダンピング) を 0 に変更します。そうすると回転速度が落ちなくなります。

物理システムを有効にする
物理システムを有効にするために「Helloworld.ts」の start 関数を下記のように書き換えます。
start() {
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
// 物理システムを有効にする.
cc.director.getPhysics3DManager().enabled = true;
}
この状態で実行すると、ボールが床をすり抜けて下に落ちて行きます。

原因は、重力が Y軸方向に働いているからです。
今回のブロック崩しは無重力状態にして永遠にボールを動かしたいので「Helloworld.ts」の start 関数を下記のように書き換えます。
start() {
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
// 物理システムを有効にする.
cc.director.getPhysics3DManager().enabled = true;
// ボールを止まらなくする.
cc.director.getPhysics3DManager().allowSleep = false;
// 無重力にする.
cc.director.getPhysics3DManager().gravity = cc.v3(0,0,0);
}
この修正を行うと、ボールが下に落ちなくなります。しかし、ボールに力が加わっていないので静止してしまいます。
ボールに力を加える
「Helloworld.ts」を下記のように修正してボールに力を加えます。
const { ccclass, property } = cc._decorator;
@ccclass
export default class Helloworld extends cc.Component {
@property(cc.Node)
Ball: cc.Node = null;
@property(cc.Node)
Player: cc.Node = null;
AccLeft: Boolean = false;
AccRight: Boolean = false;
start() {
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
// 物理システムを有効にする.
cc.director.getPhysics3DManager().enabled = true;
cc.director.getPhysics3DManager().allowSleep = false;
cc.director.getPhysics3DManager().gravity = cc.v3(0,0,0);
// ボールを動かす
let rigidBody = this.Ball.getComponent(cc.RigidBody3D);
rigidBody.applyImpulse(cc.v3(0, 0, 3000), cc.v3(0,0,0));
}
/* 省略 */
}
Canvas に登録してある Helloworldコンポーネントの Ball変数に Ballの実体を登録します。

保存して実行すると、ボールがZ方向に3000のスピードで移動するようになります。

衝突判定を付ける
ボールや壁などに衝突判定が無いので、ボールがすり抜けてしまいます。
なので、ボールや壁、バーに 3Dコライダーコンポーネント を追加していきます。
3Dスフィアコライダーコンポーネントを追加
ボールに 3D Sphere Collider Component (3Dスフィアコライダーコンポーネント) を追加します。
ボールを選択した状態で Add Component をクリックし Physics Component > Collider > Sphere 3D の順で選択して行きます。

ボールに SphereCollider3D が追加されればOK

3Dボックスコライダーコンポーネントを追加
壁とバーに 3D Box Collider Component (3Dボックスコライダーコンポーネント) を追加します。
バーを選択した状態で Add Component をクリックし Physics Component > Collider > Box 3D の順で選択して行きます。

バーに BoxCollider3D が追加されればOK

同様の作業を壁にも実施しておきます。
実行してみると、ちゃんと衝突するようになりました。

ですが、減速してしまってゲームになりません。
なので Physics Material (3D物理マテリアル) を設定して、衝突時の挙動を制御して上げる必要があります。
3D物理マテリアル
Assets の + (プラス) ボタンから「Physics Material」を選択します。

Properties (プロパティ) を変更します。
- Friction (摩擦) は、0
- Restitution (反発) は、1
「Apply」で確定します。

作った Physics Material を ボールと壁とバーに設定します。

動作確認
壁とバーに当たった後、減速しないで跳ね返っています。

おわりに
今回の作業も GitHub で公開しています。
よろしければ参考にどうぞ。
次回は、ボールが当たったら消える箱を作っていきます。