ゲームには、サウンドがとても重要です。
シューティングゲームなら、
銃声が加わると、緊張感と爽快感を味わえるようになります。
オンラインゲームの場合、
サウンドを他のプレイヤーと共有するものとそうでないものを区別する必要があります。
その辺に、注意して実装していきます。
1.サウンドの実装
1-1.音源のインポート
ここで使用する音源は、次のモノを使用させていただきます(すべてフリー素材)。
効果音
銃声:効果音ラボの「拳銃を撃つ」
死亡の音: 〃 の「クイズ不正解」
ボタンクリック: 〃 の「決定、ボタン押下9」
BGM
GameSceneのBGM:DOVA - SYDROMEの「Battle Line」
ぞれぞれmp3でダウンロードできますので、
Assetsフォルダに「Sounds」というフォルダを作り、
そこにファイルをドラッグ&ドロップすればインポート完了です。
1-2.LauncherSceneのサウンド(ボタン押下)
このシーンでは、ボタンに効果音をつけます。
LauncherSceneに「決定、ボタン押下9」ファイルをドラッグ&ドロップします。
「決定、ボタン押下9」というオブジェクトができ、コンポーネントにAudio Sourceがアタッチされたものができます。
デフォルトで「Play On Awake」が有効になっているので、無効にし、
Pitchを1.5に調整しておきます。
それでは、このAudio Sourceを鳴らすためのコードを、
「LauncherManager.cs」に書き込んでいきます。
Unity MethodsのStart()、
Public MethodsのConnectToPhotonServer()、JoinRandomRoom()
に追記するだけです^^
↓追記する周辺のみ示す
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using Photon.Pun; using Photon.Realtime; public class LauncherManager : MonoBehaviourPunCallbacks { public GameObject LoginPanel; public InputField playerNameInput; public GameObject ConnectingPanel; public GameObject LobbyPanel; AudioSource buttonSound; //AudioSourceを宣言 #region Unity Methods private void Start() { PhotonNetwork.AutomaticallySyncScene = true; LoginPanel.SetActive(true); ConnectingPanel.SetActive(false); LobbyPanel.SetActive(false); buttonSound = GameObject.Find("決定、ボタン押下9").GetComponent<AudioSource>(); //オブジェクトのコンポーネントを取得 } #endregion #region Public Methods public void ConnectToPhotonServer() { buttonSound.Play(); //LoginButtonで呼ばれたら、即再生 if(!PhotonNetwork.IsConnected) { string playerName = playerNameInput.text; if(!string.IsNullOrEmpty(playerName)) { PhotonNetwork.LocalPlayer.NickName = playerName; PhotonNetwork.ConnectUsingSettings(); ConnectingPanel.SetActive(true); LoginPanel.SetActive(false); } } else{} } public void JoinRandomRoom() { buttonSound.Play(); //StatButtonで呼ばれたら、即再生 PhotonNetwork.JoinRandomRoom(); } #endregion
できたら、ゲームを実行してみて音がなるか確認してみましょう。
1-3.GameSceneのサウンド(銃声・死亡・BGM)
「拳銃を撃つ」、「クイズ不正解2」、「Battle Line」をGameScene上に、ドラッグ&ドロップします。
それぞれのAudioSourceをもったオブジェクトができます。
(見た目を整理するため、空のGameObjectをSoundsと名付けて作成し、その中にそれらのオブジェクトを入れます)
「Battle line」はBGMなので、
「Play On Awake」、「Loop」を有効とし、
それ以外の効果音は無効にします。
Volumeは、お好みに調整します。
(BGMは0.1、銃声は0.8がちょうどよい)
サウンドを鳴らすために、スクリプトによる制御を行っていきます
・・・とその前に、
本SceneにはCameraを削除しているので、
サウンド鳴らすためのAudioListenerというコンポーネントが存在しない状態です。
(PlayerPrefabのCameraがもつAudioListenerも無効にしている)
したがって、「Sounds」と名付けた空のGameObjectに、
Audio Listenerというコンポーネントをアタッチしておきましょう。
それでは、
効果音を鳴らすためのコードを追記していきます。
銃声(拳銃を撃つ)は「Shoot.cs」で、死亡(クイズ不正解2)は「TakingDamage」で制御します。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using Photon.Pun; public class Shoot : MonoBehaviourPunCallbacks { [SerializeField] Camera fpsCamera; AudioSource shootSound; //AudioSourceを宣言 // 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); //全プレイヤーに反映させるため、RPCメソッドに渡す RaycastHit _hit; Ray ray = fpsCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f)); if(Physics.Raycast(ray, out _hit,100)) { 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] //RPCメソッド public void ShootEffect() { shootSound.Play(); //銃声を再生 } }
サウンドはローカルだけで鳴らすモノか、
全ユーザーに鳴らせるモノかによって、記載を変えなければいけません。
銃声は全員に共有しなければ、
1人でプレイしてるような寂しさを覚えてしまいますよね^^;
なので、shootSoundはRPCメソッドとして渡せばOK!
↓「TakingDamage」は追記する周辺のみ示す
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using Photon.Pun; public class TakingDamage : MonoBehaviourPunCallbacks { [SerializeField] Image hpBar; private float hp; public float startHp = 100; [SerializeField] GameObject deadText; [SerializeField] Text killText; [SerializeField] Text respawnText; AudioSource dieSound; //AudioSourceを宣言 // Start is called before the first frame update void Start() { hp = startHp; hpBar.fillAmount = hp / startHp; dieSound = GameObject.Find("クイズ不正解2").GetComponent<AudioSource>(); //シーンにあるオブジェクトを探し、コンポーネントを取得 } // Update is called once per frame void Update() { } [PunRPC] public void TakeDamage(float _damage, PhotonMessageInfo info) { hp -= _damage; hpBar.fillAmount = hp / startHp; if(hp <= 0f) { deadText.SetActive (true); Die(); dieSound.Play(); //死亡のお知らせ音を再生 if(photonView.IsMine) { killText.GetComponent<Text>().text = "You were killed by " + info.Sender.NickName; } } }
HPがゼロになったら全員に知らせたいので、
すでにRPCのメソッドの処理の一環に「dieSound.Play()」を入れます。
以上で、ゲームにサウンドが実装されたはずです!
Editorで問題なければ、
相手プレイヤーとのサウンドの共有がされるかに注目し、
実際にビルドして、片方の音楽をミュートしたりしながら、確認してみましょう。
というわけで、
「オンラインFPSゲームを作ってみよう」シリーズは、ひとまず完結!と。
今後もUnityでゲーム開発するノウハウを発信していきますので、
本ブログを何とぞよろしくお願いします!!