当初、オンラインFPSゲームの作り方#1~8で終える予定でしたが、
さらにテクニックの紹介を追加していくことにしました^^
単発で方法を説明するより、
今作っているゲームに実装していく形で説明する方が、
より実践的だと思ったからです^^
(なので、皆もトレイスいただくと、立派なゲームが作れるというわけ)
ということで、
今回は、パーティクルというエフェクトの実装方法(+Photonオンラインゲームにおけるコード)の紹介です。
非常に簡単!
1.パーティクルの作成
1-1.パーティクルの型を調達
パーティクルを一から作ることはしません!
エフェクトデザイナーという分野があるくらい、これまた深い領域なので・・・
アセットを使っていきましょう。
私が使用したパーティクルエフェクトのアセットは「Action RPG FX」です。
もちろん他のアセットでも構いません。
今回、銃口から放たれるエフェクトと
弾丸が当たった先のエフェクトを実装するので、
それに合いそうなアセットを見つけましょう。
マウスクリック(モバイルならShootボタン)によって音だけなっていたものが、
エフェクトが付くと爽快感がアップします!
アセットをインポートしたら、そのアセットの「Prefabs」_「Loot」_「Chests」にある「ChestLv2Open」を使用していきます。
GameSceneに「ChestLv2Open」をドラッグ&ドロップします。
このエフェクトを自分の好みのように編集していきます。
以降、作成していくエフェクトでは、全てこのパーティクルオブジェクトを使います。
このPrefabをシーンに配置したら、右クリックから「Unpack Prefab Completely」を選択してから、毎回変更を加えていきます。
1-2.銃撃箇所のエフェクト
現在、撃ったところは照準(CrossHair)のあるところになっています。
しかし、それは自分にしかわかりません。
撃ったところに何か変化が起きないと、
他のプレイヤーが「奴は今あそこを狙って撃ったのだな」と知ることができません。
また、自分自身も射撃音だけでは撃った実感を得にくいでしょう。
そこで、銃撃箇所にパーティクルオブジェクトが発生するように設定していきます。
ここでも「ChestLv2Open」を元に作成していきます。
GameSceneに配置したPrefabの名前を「HitEffect」に変更したら、
「Linger」のオブジェクト以外は削除します。
「HitEffect」と「Linger」の2つのオブジェクトに関して、Particle Systemの項目を変更します。
ここではDuration(エフェクトの時間)とPlay On Awakeを、図のように指定すれば十分です。
Lingerには一瞬キラッとしてほしいので、次のようにしました。
当たった場所が光り、やや塵が浮く感じのエフェクトになります。
完成したら、「Resources」フォルダに入れてPrefab化します。
1-3.銃口のエフェクト
現在、銃撃音は鳴っていますが、画面に映る銃口が寂しいですよね?
というわけで、Shootと同時に、銃口にエフェクトを追加します。
一度、PlayerPrefabをGameSceneに配置したら、その「Model」の配下に「ChestLv2Open」を「ShootFlashEffect」と名付けて配置します。
子オブジェクトとして、「VerticalGlow」以外は不要なので削除し、図のようにInspectorを設定します。
Durationを「1.00」、Play On Awakeは無効にします(コードで再生させるため)。
なお、Transformは親の「ShootFlashEffect」のみ変更するので構いません。
うまくAK-47の銃口から光が放たれるように調整しましょう。
設定したら、PlayerPrefabを選択して、「Overrides」で上書き保存すれば完了です。
2.スクリプトによるパーティクルの制御
各Effectのオブジェクトができたところで、スクリプトによって発生させるタイミングを制御していきます。
なお、これらのエフェクトはオンラインで他プレイヤーにも共有するので、RPCのメソッド中で発生させます。
2-1.銃撃箇所へのエフェクト発生
銃撃箇所も銃口のエフェクトも、「Shoot.cs」のコーディングで実現できます。
スクリプトは次の通り。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using Photon.Pun; public class Shoot : MonoBehaviourPunCallbacks { [SerializeField] Camera fpsCamera; AudioSource shootSound; [SerializeField] GameObject hitEffect; //銃撃箇所のエフェクト [SerializeField] ParticleSystem shootFlashEffect; //銃口のエフェクト // Start is called before the first frame update void Start() { shootSound = GameObject.Find("拳銃を撃つ").GetComponent<AudioSource>(); } // Update is called once per frame void Update() { if(Input.GetMouseButtonDown(0)) { photonView.RPC("ShootEffect", RpcTarget.AllBuffered); RaycastHit _hit; Ray ray = fpsCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f)); if(Physics.Raycast(ray, out _hit,100)) { photonView.RPC("GenerateHitEffect", RpcTarget.All, _hit.point); //Rayがオブジェクトに当たったらRPC属性メソッドに_hit point情報を渡す Debug.Log(_hit.collider.gameObject.name); if(_hit.collider.gameObject.CompareTag("Player") &&!_hit.collider.gameObject.GetComponent<PhotonView>().IsMine) { _hit.collider.gameObject.GetComponent<PhotonView>().RPC("TakeDamage", RpcTarget.AllBuffered, 10f); } } } } [PunRPC] public void ShootEffect() { shootSound.Play(); shootFlashEffect.Play(); //マウスクリックで読まれるRPC属性ShootEffectメソッドにParticleの再生を記載 } [PunRPC] public void GenerateHitEffect(Vector3 position) //_hit point情報はVector3 positionとして利用 { GameObject hitEffectGameObject = Instantiate(hitEffect, position, Quaternion.identity); //Prefabのpositionに生成 Destroy(hitEffectGameObject, 1f); //1秒後に削除 } }
コメントを記載したところが追記内容です。
PlayerPrefabにセットしたShootFlashEffectは、銃撃の入力で再生するようにするだけなので、非常にシンプルですね^^
*モバイルによる操作に対応させる方法はこちら
というわけで、
これにてParticleによるエフェクトを追加することができました!