主人公が乗ると数秒後に落下する床をUnityで作成してみる

今回はアクションゲームでよくある主人公が乗るとその重みで落下する床をUnityで作成したいと思います。

仕様としては床ごとに主人公が乗っている時間を保持し、その時間を超えたら落下するようにします。
時間はインスペクタ上で設定出来るようにします。

また床がそのまま残っていると邪魔になるので、地面と接触したら床自体を消してしまいます。

スポンサーリンク

落ちる床のゲームオブジェクトを作成

まずは坂と落ちる床を作っていきます。

落ちる床1


落ちる床はFallFloor1とFallFloor2になります。Slopeも含めてすべて3D Object→Cubeで作成します。
FallFoor1とFallFloor2のTagにFallFloorを新しく作り設定しておきます。

落ちる床2

FallFloor1とFallFloor2にはFallFloorという新しいスクリプトを作成し追加します。
Rigidbodyは最初から付けておいてもいいんですが、今回はスクリプトから追加してみます。

落ちる床3

色々視界に入り見えづらいですが・・・、坂と落ちる床を繋げて上のようにしました。

落ちる床が主人公キャラの背の高さと同じぐらいでぶつかる位置にある場合は注意が必要です。
主人公キャラが持っているコライダが床と接触している時間で床を落とすので、床の下や横に主人公がぶつかっている時にも計測されてしまいます。

接触をコライダでなくキャラクターから真下にレイを飛ばし接触判定をすると厳密に床の上にいるかどうかを判定出来ます。

主人公キャラが落ちる床に乗った時の処理スクリプトForceFloor

次に主人公キャラが床に乗った時に床自体に乗っている時間を計測させますが、主人公キャラが床に乗っている
事を知らせるスクリプトForceFloorを作成し、主人公キャラに追加します。

主人公キャラをCharacterControllerで動かしている場合のコライダの接触判定はOnControllerColliderHitを使います。
床自体にIs Triggerにチェックを入れてるコライダがあればOnTriggerEnterで主人公キャラの進入を検知出来ますが、今回のように主人公キャラが床に乗らなければいけない時(衝突を使う)は主人公側から相手側を検知します。

主人公が接触した相手がFallFloorであった時はFallFloorスクリプトを取得し、その中に定義されているReceiveForce関数を呼び出します。
これで主人公が床に乗っている間ReceiveForce関数が呼ばれる事になります。

落ちる床を実現するスクリプトFallFloorを作成

次に床に設定したFallFloorスクリプトを作成します。

床のインスペクタ上で床が落ちるまでの時間を設定出来るようにします。
主人公キャラが床と接触した場合にReceiveForce関数が呼ばれますが、呼ばれた時に床にRigidbodyが設定されていなかった時Rigidbodyコンポーネントを床に追加し、isKinematicをtrueにします。

Rigidbodyは初期値としてUse Gravityにチェックが入っているので特にスクリプトから変更はしません。
isKinematicがtrueである時はスクリプトからしか影響が与えられないようになるので、重力が働かないようになります。

Update関数内で床に乗っている時間が制限時間を超えた時にRigidbodyのisKinematicをfalseに設定します。
isKinematicがfalseになったので、Use Gravityの影響が出て床は落下していきます。

OnCollisionEnterを使って、床がFieldレイヤーに設定されているゲームオブジェクトとぶつかった時に床を削除します。
ぶつかった相手のレイヤーを調べるには

col.gameObject.layer

を使います。

LayerMask.NameToLayer(“Field”)

を使えばFieldという名前のレイヤーの番号が取得出来ます。

これで落ちる床の作成と設定が出来ました。床のインスペクタ上でFallFloorのLimit Timeを設定してください。

それではUnityの実行ボタンを押して確認してみましょう。

落ちる床4

これで主人公が乗ると数秒後に落下する床を作成してみる事が出来ました。
床が落ちるトラップを作成する場面で重宝しそうですね。