ゲームには、サウンドがとても重要です。
シューティングゲームなら、
銃声が加わると、緊張感と爽快感を味わえるようになります。
オンラインゲームの場合、
サウンドを他のプレイヤーと共有するものとそうでないものを区別する必要があります。
その辺に、注意して実装していきます。
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でゲーム開発するノウハウを発信していきますので、
本ブログを何とぞよろしくお願いします!!
