【Unity/3D】落とし穴のギミックの作り方

【Unity】3Dアクションでの落とし穴ギミックの実装例

3Dのアクションゲームに落とし穴ギミックを実装。
床の3Dモデルの頂点の操作は困難なので、穴の3Dモデルで覆って擬似的に再現。

↓の自作ゲームで使用した。

デモ動画

ざっくりした手順

  1. Pit(落とし穴)プレハブを作成。
    1. PitタグとPitレイヤーに設定。
    2. IsTriggerを有効にしたColliderをアタッチ。
  2. 床を作成。
    1. Groundレイヤーに設定。
  3. キャラクタープレハブに追加で設定。
    1. 落下時用のレイヤーを作成、レイヤーと床との当たり判定を無効化。
    2. スクリプトでPitタグと衝突判定し、落下時用のレイヤーに差し替え。

詳細な手順

【ダウンロード】落とし穴の3Dモデル

自作。
素人目には中々上手く出来ました。

  • ライセンス:CC0
  • 頂点数:439

落とし穴の3Dモデル

  1. ダウンロードして適当なフォルダで解凍。
  2. Pitの3Dモデルとテクスチャを同時選択。
  3. Projectウィンドウ -> 任意のフォルダに、ドラッグ&ドロップしてインポート。
    (3Dモデルのフォルダ下にTexturesという名前でフォルダを作成して除けておいても良い)

Pit(落とし穴)プレハブを作成

落とし穴を設定

*画像の数字と本編の番号は対応していません。

  1. 上部メニュー -> GameObject -> Create Emptyを選択し、空のオブジェクトを作成、Pitと命名。
  2. ヒエラルキー -> Pitに先程インポートした3Dモデルをドラッグ&ドロップして設置。
  3. ヒエラルキー -> Pit下のPit-LowPolyを選択。
    1. インスペクター -> Transformコンポーネント -> Position Y:0.001に変更。
  4. ヒエラルキー -> Pitを選択。
    1. インスペクター -> Add Component -> Box Colliderをアタッチ、続いて設定。
      1. IsTrigger:有効化
      2. Center:(0, 0.05, 0)
      3. Size:(0.1, 0.1, 0.1)
        (穴の中心に来るように設置するのがポイント)
    2. インスペクター -> Add Component -> Rigidbodyをアタッチ、続いて設定。
      (多分Rigidbodyが無くても動くが一応)
      1. IsKinematic:有効化
      2. Collision Detection:Continuous Speculative
      3. Use Gravity:無効化(一応)

床の作成 (既に作成している場合はそちらを使用)

上部メニュー -> GameObject -> 3D Object -> Planeを選択、床を作成。

プレイヤーにスクリプトを追加 (移動や3Dモデルは、既に実装している事を想定)

以下のコードをプレイヤーのメインスクリプトに追記するか、新規にスクリプトをアタッチして記述。



using System.Collections;
//使わなかったので一応コメントアウトしている。
//using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{

//通常状態のプレイヤーのレイヤー。
	LayerMask defaultPlayerLayer;
//落下状態のプレイヤーのレイヤー。
	LayerMask fallenPlayerLayer;


//落下状態のフラグ。
	public bool isFalling;

//落下してから落下状態がリセットされるまでの距離。
	float endFallDistance = -2.0f;

//落下コルーチン管理用変数。
	Coroutine fall;

//落下開始位置。
	float startFallPositionY;


	void Awake()
	{
		defaultPlayerLayer = LayerMask.NameToLayer("Player");
		fallenPlayerLayer = LayerMask.NameToLayer("FallenPlayer");
	}

	void OnTriggerEnter(Collider col)
	{
//落下中でない状態で、Pitの中心に設定したColliderに触れた場合のみ実行。
		if (!isFalling && col.gameObject.CompareTag("Pit")) {
			StartFall();
		}
	}

	
	void StartFall()
	{        
		fall = StartCoroutine("Fall");
	}

	IEnumerator Fall()
	{
		isFalling = true;
		gameObject.layer = fallenPlayerLayer;
		startFallPositionY = transform.position.y;

		while (true) {

			if (transform.position.y - startFallPositionY <= endFallDistance) {

				isFalling = false;
				gameObject.layer = defaultPlayerLayer;

				yield break;
			}

			yield return null;
		}
	}


//落下コルーチンをリセット(オブジェクトプールで使い回す&死亡等で強制終了させる場合用)。
	void ResetFall()
	{
		if (fall != null) {
			StopCoroutine(fall);
			fall = null;
		}
	}

}

タグとレイヤーを作成&設定

タグとレイヤーの作成

  1. ヒエラルキー -> 何でも良いので適当に選択。
  2. インスペクター -> 名前欄の下にある「Tag」 > Add Tag…を選択、Tags&Layersを開く。
    1. 新規タグを作成「Pit」
    2. 新規レイヤーを作成「Pit」「Ground」「Player」「FallenPlayer」
  3. ヒエラルキー -> Pitを選択。
    1. インスペクター -> TagをPitに設定。
    2. インスペクター -> LayerをPitに設定。
      レイヤーの変更時に出るダイアログは「Yes, change children」でも「No, this object only」でも、どちらでもOK。
      (ColliderをPitオブジェクト本体に付けている為)
  4. ヒエラルキー -> 床(前項で作成したならばPlane)を選択。
    1. インスペクター -> LayerをGroundに設定。
  5. ヒエラルキー -> Playerを選択。
    1. インスペクター -> LayerをPlayerに設定。

一部レイヤー間の衝突判定を無効化

レイヤー間の衝突判定の無効化

*画像の数字と本編の番号は対応していません。

  1. 上部メニュー -> Edit -> Project Settings…を選択。
  2. Project Settingsウィンドウ -> サイドバーメニュー -> Physicsを選択。
  3. 下までスクロール -> Layer Collision Matrixの設定を変更。
    1. Ground x FallenPlayer:無効化
    2. Pit x FallenPlayer:無効化

以上で完成!

自作ゲーム「PitActPzl」での落とし穴ギミック
タイトルとURLをコピーしました