今回はUnityで自前の血しぶきエフェクトを作成し、主人公の攻撃が敵に当たった、または敵から攻撃を受けた時に表示してわかりやすくします。
今回の機能を作成するにあたり以前作成した機能に処理を追加する必要があるので、このスクリプトやメソッドは何?と思ったら
の記事で今までの流れを確認出来ます。
エフェクトに関しては以前に敵キャラクターが登場した時に出すというのをやりました。
エフェクトはAsset Storeで探してきた物を使用しましたが、Unityではエフェクトを自分で作成する事も出来ます。
ヒエラルキー上で右クリック→Particle Systemを選択し、名前をBloodEffectとします。
パーティクルシステムはエフェクトを自分で作成する機能です。これを使って血しぶきに似たような物を作ってみます。
主人公用と敵キャラ用は同じエフェクトで色合いだけを変えるようにします。
まずは基本設定です。
パーティクルが出現した時のスピードや色、サイズの指定等を行っています。
パーティクルには重力をより働かせる為、Gravity Modifierを0.5にします。
次はEmission等の設定です。
ShapeをConeにしてコーン上にパーティクルが飛んで行くようにします。
次はパーティクルが出現してから消えるまでの色合いを設定します。
矢印の下が色合いで上が不透明度の設定になります。
色合いは変わらず、アルファ値だけを下げ少しづつ透明度を上げます。
次にSize over Lifetimeの設定です。
パーティクルは時間と共に小さくなっていくようにグラフを設定しました。
最後にCollisionの設定等を行います。
パーティクルの衝突はWorld座標で行うようにします。
またBounceを0にし衝突した時にパーティクルが跳ね返らないようにします。
シーン上に配置されたエフェクトはシミュレーションが表示されています。
それを見ながらパラメータを調整し、血しぶきに見えるように変更していきます。
とりあえずこれで血しぶきのパーティクルが出来ました(すぐれたものではないですが・・・・)
あとはダメージを与えた時に敵キャラ用のエフェクト、ダメージを受けた時に主人公用のエフェクトを表示させます。
スクリプトからエフェクトを出す
主人公操作スクリプトのTakeDamageメソッドを修正します。
1 2 3 4 5 6 7 8 9 10 11 12 | [SerializeField] private GameObject damageEffect; public void TakeDamage(Transform enemyTransform, Vector3 attackedPlace) { state = MyState.Damage; velocity = Vector3.zero; animator.SetTrigger("Damage"); var damageEffectIns = Instantiate<GameObject>(damageEffect, attackedPlace, Quaternion.identity); Destroy(damageEffectIns, 1f); } |
パーティクルを出現させるのはダメージを受けた時にしたいので、TakeDamageメソッド内で処理を記述します。
damageEffectはインスペクタで設定出来るようにします。
TakeDamageメソッドの第2引数にattackedPlaceを宣言します。
Instantiateでプレハブをインスタンス化し、位置をattackedPlaceにします。
敵から攻撃を受けた時に敵の攻撃が当たった場所をattackedPlaceに渡すことにします。
敵の攻撃スクリプトを修正します。
敵の手の部分に取り付けた攻撃の処理で主人公のTakeDamageメソッド呼び出しの時に攻撃が当たった位置を渡します。
1 2 3 4 5 6 7 8 9 10 11 12 13 | using UnityEngine; using System.Collections; public class AttackZombie : MonoBehaviour { void OnTriggerEnter(Collider col) { if (col.tag == "Player") { col.GetComponent<CharacterScript>().TakeDamage(transform.root, col.ClosestPoint(transform.position)); } } } |
コライダのClosestPointメソッドは与えた引数の位置に最も近いコライダの位置を返します。
上の場合だと敵の手にAttackZombieスクリプトを取り付けているので敵の手が主人公のコライダの当たった位置を返します。
敵キャラクターのEnemyスクリプトにもdamageEffectフィールドとTakeDamageメソッドを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 | // 攻撃を受けた時のエフェクト [SerializeField] private GameObject damageEffect; public void TakeDamage(Vector3 attackedPlace) { SetState(EnemyState.Damage); var damageEffectIns = Instantiate<GameObject>(damageEffect); damageEffectIns.transform.position = attackedPlace; Destroy(damageEffectIns, 1f); } |
AttackSwordスクリプトで敵に攻撃を与えた時に直接SetStateメソッドを呼び出していましたが、TakeDamageを呼ぶように変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | using UnityEngine; using System.Collections; public class AttackSword : MonoBehaviour { void OnTriggerEnter(Collider col) { if (col.tag == "Enemy") { Debug.Log("敵に当たった"); col.GetComponent<Enemy>().TakeDamage(col.ClosestPointOnBounds(transform.position)); } } } |
先ほどはClosestPointを使いましたが、今回はClosestPointOnBoundsメソッドを使ってみました。
ClosestPointはコライダ上でClosestPointOnBoundsはコライダの境界らしいです。
他の方の作ったパーティクルを使ってスクリプトから表示したサンプルを最後に載せておきます。
エフェクト自体はダメージ用のエフェクトではないのでちょっとあれですが・・・スクリプトからエフェクトを表示する事が出来ました。
次回はまた音声関連をやって、少し華やかさを入れたい所ですね。