【Unity】カジュアルな木っ端微塵死亡演出(非ParticleSystem)

カジュアルな木っ端微塵死亡エフェクト001

カジュアルなビジュアルスタイルのゲームと親和性の高い、木っ端微塵死亡エフェクトを実装。
ParticleSystemを使わず、小オブジェクトの生成で表現。

↓の自作ゲームで使用。

サンプル動画

真ん中の赤い床に接触すると破裂。

破片用のマテリアルを作成

  • 上部メニュー -> Assets -> Create -> Materialを選択。
    適当に「DeathEffectMaterial」と命名。
    • Shader:通常のままでも良いが、任意のシェーダーで。
    • Albedo:任意の色に変更。

死亡エフェクトを作成

死亡エフェクト本体と破片オブジェクトを作成

*画像の番号と、手順の番号は対応してないです。流れとして御覧ください。

カジュアルな木っ端微塵死亡エフェクトの設定002

次項の「レイヤーの設定」と跨いでいます。

カジュアルな木っ端微塵死亡エフェクトの設定001

  1. 上部メニュー -> GameObject -> Create Emptyを選択。
    DeathEffectと命名。
  2. DeathEffectスクリプトを作成し、アタッチ。
  3. ヒエラルキー -> DeathEffectを右クリック -> 3D Object -> Sphereを選択。
    続いて設定。
    1. インスペクター -> Transformコンポーネント -> Scaleを(0.3, 0.3, 0.3)程に変更。
    2. インスペクター -> Mesh Rendererコンポーネント -> Materials -> Element 0へ、「DeathEffectMaterial」を設定。
    3. インスペクタ -> Add Component -> Rigidbodyをアタッチ。
    4. ヒエラルキー -> Sphereを右クリック -> Duplicateで、Sphereを20個程まで複製。
      (ヒエラルキーで複数選択して実行すると早い)

DeathEffect側のコード



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

public class DeathEffect : MonoBehaviour
{


//破片のRigidbodyを保持。
	Rigidbody[] childrenRigidbodies;

//爆発力。
	float deathEffectForce = 15.0f;
//爆発の半径。
	float deathEffectForceRadius = 10.0f;
//上向きに掛かる力の補正値。
	float deathEffectUpwardsModifier = 1.0f;


	Coroutine lifetimeTimer;

//非アクティブ化するまでの時間。    
	float lifetime = 5.0f;

	void Awake()
	{
		childrenRigidbodies = GetComponentsInChildren<Rigidbody>();        

		SetRandomPosition();
	}



//エフェクトを開始したい時に呼ぶ。
	public void StartEffect()
	{
		for (int i = 0; i < childrenRigidbodies.Length; i++)
		{
			childrenRigidbodies[i].AddExplosionForce(deathEffectForce, transform.position, deathEffectForceRadius, deathEffectUpwardsModifier, ForceMode.Impulse);
		}

		lifetimeTimer = StartCoroutine("LifetimeTimer");
	}

//毎回ランダムに散らばらせて配置している。
	void SetRandomPosition()
	{
		for (int i = 0; i < childrenRigidbodies.Length; i++)
		{
			childrenRigidbodies[i].transform.position = Random.insideUnitSphere;
		}
	}

//(オブジェクトプールにするのを想定)リセット。
	public void Reset()
	{
		ResetVelocity();
		SetRandomPosition();
	}

//(オブジェクトプールにするのを想定)加速度のリセット。破片には球体を使っているので、AngularVelocityはリセットしなくても多分大丈夫。
	void ResetVelocity()
	{
		for (int i = 0; i < childrenRigidbodies.Length; i++)
		{
			childrenRigidbodies[i].velocity = Vector3.zero;
		}
	}


//一定時間経過で、非アクティブ化するタイマー。
	IEnumerator LifetimeTimer()
	{
		yield return new WaitForSeconds(lifetime);
		gameObject.SetActive(false);
		Reset();
	}


//ゲームオーバー等、タイマー以外で非アクティブ化した場合の、タイマーの強制終了用。
//Resetの方から呼んでも良いが、一応分けた。
	public void ResetLifetimeTimer()
	{
		if (lifetimeTimer != null) {
			StopCoroutine(lifetimeTimer);
			lifetimeTimer = null;
		}
	}


}

(任意)一部レイヤーとの衝突判定を無効化

レイヤーの作成&変更

  1. インスペクター -> Layer(名前欄のやや下) -> Add Layer…を選択。
    Tags&Layers画面を開き「DeathEffect」レイヤーを作成。
  2. 再びヒエラルキー -> DeathEffectを選択。
  3. インスペクター -> Layer -> DeathEffectを選択。
    (Change Layerダイアログでは、Yes, change childrenを選択)

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

*画像の番号と、手順の番号は対応してないです。

死亡エフェクトのレイヤー間の衝突設定
  1. 上部メニュー -> Edit -> Project Settings…を選択。
  2. Project Settingsウィンドウ -> サイドバーメニュー -> Physicsを選択。
  3. 下までスクロール -> Layer Collision Matrixで、DeathEffect x Player間等の衝突判定を無効化。

プレハブ化

  1. Projectウィンドウ -> 任意のフォルダに、DeathEffectをドラッグ&ドロップしてプレハブ化。
  2. ヒエラルキー -> DeathEffectを右クリック -> Deleteを選択、シーン上から削除。

プレイヤー側

  1. Player(対象とするオブジェクト)のメインスクリプトに追記。
    もしくは、新規スクリプトを作成し、記述。
  2. ヒエラルキー -> Playerを選択。
  3. インスペクター -> Playerスクリプト -> deathEffectPrefabに、DeathEffectプレハブをフォルダからドラッグ&ドロップして紐付け。
  4. プレイヤーの死亡タイミングで、CreateDeathEffectを呼ぶ。

Player側のコード



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

public class Player : MonoBehaviour
{

//インスペクターでDeathEffectプレハブを紐付け。
	[SerializeField]
	GameObject deathEffectPrefab;

	DeathEffect deathEffect;


	void Awake()
	{
//割愛するが、実際に使用する際には、リストにしてオブジェクトプール化するべき。
		deathEffect = Instantiate(deathEffectPrefab).GetComponent<DeathEffect>();
		deathEffect.gameObject.SetActive(false);
	}


//呼び出しの例。各自で差し替えてください。
	void OnCollisionEnter(Collision col)
	{
		if (col.gameObject.CompareTag("DamageFloor")) {
			gameObject.SetActive(false);
			CreateDeathEffect();
		}
	}


//プレイヤーの位置に移動させてから、アクティブ化して、エフェクト開始。
	void CreateDeathEffect()
	{
		if (!deathEffect.gameObject.activeSelf) {
			deathEffect.transform.position = transform.position;
			deathEffect.gameObject.SetActive(true);

			deathEffect.StartEffect();
		}        

	}

}

タイトルとURLをコピーしました