【Unity】2Dシューティングゲームの作り方⑫:音とエフェクトの作成

Unity

こんにちは、ともくんのゲーム作り部屋にようこそ!

このページでは、Unityを使った2Dシューティングゲームの作り方12回目として、ゲーム内で音やエフェクトを表示する処理について紹介しています。

前回、ゲーム内にアイテムを配置してプレイヤーをパワーアップさせる処理を作っていきました。

今度は、ゲーム内で効果音やBGMを付けたり、エフェクトを付けてよりゲームを楽しめるようにしていきます。

ゲーム内で音声を流す場合は、Audio Sourceコンポーネントを使うことで音声データを紐づけて再生することができます。

また、爆発などのエフェクトはアニメーションを使って作ることができます。

そこで、ゲームでBGMなどの音を再生する処理と、爆発を表示させるエフェクト処理までをまとめていきます。

この記事を書いた人

ゲーム作りを学び始めた一児のパパです。
このブログは、子供から「ゲームを作ってみたい!」と言われ、非プログラマーでゲーム作りをしたことない僕が、ゲーム作りの本を読んで独学でゲーム開発を学んでいるブログです。
同じように初めてゲーム作りをしている方と一緒に学んでいけるようなブログに出来たらいいなと思っています。
また、「このコードはおかしい」とか「もっと良い書き方があるよ!」などあれば、どんどん指摘して頂けると助かります。

ゲームにBGMや効果音を付ける

ゲーム内でBGMを鳴らしたり効果音を付ける場合は、

  • Unityに音の素材をインポートする
  • AudioSourceコンポーネントで音源をセットして鳴らす

という作業を行っていきます。

Unityに音の素材をインポートする

まずは、音源となる素材をUnityにインポートしていきます。

インポートの方法は、画像などのインポートと同じく、音のデータファイルをプロジェクトウィンドウにドラッグ&ドロップすることで、Unity内に取り込むことができます。

今回は、素材を管理するアセットフォルダ内に「Audio」という名前のフォルダを作成して、その中にBGMや効果音などの音楽ファイルを管理していきます。

なお、Unityでは、音楽ファイルを取り込むと、Audio Clip(.clip)というデータ形式に変換されて保存されることになります。

AudioSourceコンポーネントで音楽をセットする

音源をインポートすることができたら、AudioSourceコンポーネントを使って音を鳴らす処理を作っていきます。

AudioSourceコンポーネントは、紐づけた音声データを再生するという役割を持っています。

ここでは、

  • プレイヤーの銃の発射音
  • ステージのBGM
  • アイテムを取った時の効果音
  • 敵にやられた時の音

をそれぞれ作っていきます。

プレイヤーの銃の発射音

まずは、プレイヤーが銃弾を発射した際の効果音を付けていきます。

Enterキーを押して銃弾が発射されるタイミングで効果音を鳴らしたいので、銃弾が発射される場所を指定した「playerBulletPoint」にAudioSourceコンポーネントを付けていきます。

なお、このプレイヤーが弾を撃つ処理は、作り方の4回目で紹介していますので、以下の記事も参考にしてみてください。

この「playerBulletPoint」を選択して、インスペクターウィンドウから「Add Component」をクリックします。

次に「Audio」のカテゴリの中から、「Audio Source」を選択します。

AudioSourceコンポーネントを付けることができたら、「Audio Resource」の項目にインポートした発射用の効果音データをドラッグ&ドロップで設定して紐づけます。

ここでは、「shot_se」という名前でインポートしています。

また、「Play On Awake」という項目のチェックを外していますが、これはオブジェクトが生成されたタイミングで音を流すかどうかを決めている項目で、ここではプレイヤーが発射したタイミングで音を再生したいので、このチェック項目を外しています。

これで、AudioSource側の設定は完了したので、「playerBulletPoint」にアタッチした銃弾を発射する処理である「PlayerShoot」のスクリプトに音を再生する処理を追加していきます。

using UnityEngine;

public class PlayerShoot : MonoBehaviour
{
    public GameObject playerBullet; // GameObject型の変数を宣言する
    AudioSource audioSource; // AudioSourceの変数を宣言する

    void Start()
    {
        audioSource = GetComponent<AudioSource>();   // AudioSourceコンポーネントを取得する
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Return))   // Enterキーを押した場合
        {
            audioSource.Play();  // Audioを再生する
            GameObject cloneObject = Instantiate(playerBullet, this.transform.position, Quaternion.identity);  // 弾を表示させて座標を移動させる処理
            cloneObject.name = "PlayerBullet";  // 名前を変更する処理
        }
    }
}

6行目でAudioSourceを取得するための変数を宣言しておき、Startメソッド内の10行目でGetComponentメソッドでAudioSourceコンポーネントを取得しています。

そして、17行目でEnterキーを押した際の処理の中に、Playメソッドを使って音を再生する処理を書いています。

このPlayメソッドは、AudioSourceに紐づけたAudioClipを再生する処理を行うことができます。

これで、プレイヤーが弾を撃った際に音が鳴るようになりました。

なお、音を鳴らす際の作り方は、以下の記事で詳しく解説しているので、参考にしてみてください。

ステージのBGM

次に、ステージの中で流すBGMを作っていきます。

BGMは、ゲームが始まったら自動的に音楽が再生されて、プレイヤーが敵から攻撃を受けてやられるまでの間、流れる形にしていきます。

まずは、BGMを流すためのオブジェクトを作る必要があるので、ヒエラルキーウィンドウの+ボタンから、「Audio」の中にある「Audio Source」を選択します。

このオブジェクト名を「BGM」と変更しておき、先ほどの弾の発射音と同じくインスペクターウィンドウのAudioSourceコンポーネントにある「Audio Resource」の項目に、BGMとなる音楽データを紐づけておきます。

この際に、「Play On Awake」「Loop」にチェックを入れておくことで、自動的にBGMがループで再生されることになります。

これでBGMは再生されるようになりますが、プレイヤーがやられたら停止する処理を作りたいので、新しく「BgmController」というスクリプトを作成して、「BGM」のオブジェクトにアタッチしておきます。

using UnityEngine;

public class BgmController : MonoBehaviour
{
    public GameObject player;   // プレイヤーのオブジェクトを取得
    AudioSource bgm;    // AudioSource型の変数を宣言

    void Start()
    {
        bgm = GetComponent<AudioSource>();  // AudioSourceを取得する
    }
    void Update()
    {
        if (player.activeSelf == false && bgm.isPlaying == true)
        {
            bgm.Stop(); // 音を停止する
        }
    }
}

6行目でAudioSource型の変数を宣言して、Startメソッド内の10行目でAudioSourceを取得しておきます。

14行目のif文の中で、変数isPlayingを使ってBGMが再生されているときに、プレイヤーが非アクティブになったら、16行目でStopメソッドを使ってBGMを停止するようにしています。

スクリプトが書けたら、インスペクターウィンドウの「BgmController」「Player」の項目に、ヒエラルキーウィンドウの「player」のオブジェクトをドラッグ&ドロップして設定しておきます。

これで、ゲームスタートと同時にBGMが再生されて、プレイヤーが敵の弾に触れてしまうと、BGMが停止されるようになりました。

アイテムを取った時の音

次に、前回作ったお助けアイテムをプレイヤーが取った時の音を付けていきます。

ここでは、アイテム用の音源のオブジェクトを作成して、プレイヤーがアイテムと接触したときに、そのオブジェクトに紐づく音を流すという処理を作っていきます。

まずは、BGMの時と同じく、ヒエラルキーウィンドウの+ボタンから、「Audio」の中にある「Audio Source」を選択します。

出来上がったオブジェクトの名前を変更して、インスペクターウィンドウのAudioSourceコンポーネントにある「Audio Resource」の項目に、アイテムを取った時用の音楽データを紐づけておきます。

この音はプレイヤーがアイテムと接触したときに再生することになるので、「Play On Awake」のチェックは外しています。

次に、プレイヤーとアイテムの接触処理を作るために、アイテムのオブジェクトにタグの設定を行っておきます。

アイテムのオブジェクトを選択して、インスペクターウィンドウのTagの横に書かれている「Untagged」を選択して、「Add Tag…」をクリックします。

「Tags」の+ボタンからタグを追加して、「Item」などのタグ名を付けておきます。

インスペクターウィンドウに戻って、再度Tagの項目から先ほど付けた「Item」のタグ名を選択しておきます。

今回はアイテムを2つしか作っていませんが、他にも作成している場合は、全てのアイテムにこのタグを設定しておきましょう。

ここまでできたら、プレイヤーのオブジェクトにアイテムと触れた際に音を再生する処理を「PlayerController」のスクリプトに追記していきます。

using UnityEngine;

public class PlayerController : MonoBehaviour
{
	// 省略 //

    public AudioSource itemGetAudio;    // アイテムを取得したときのAudioSourceの変数

    void Start()
    {
        Application.targetFrameRate = 60;   // フレームレートを60fpsで固定
    }

    void Update()
    {
	// 省略 //
    }

    void OnTriggerEnter2D(Collider2D collision) // 他のオブジェクトとの当たり判定の処理
    {
        if (collision.gameObject.name == "EnemyBullet" ||   // 敵の弾に当たった場合
            collision.gameObject.tag == "Enemy")            // 敵のオブジェクトに触れた場合
        {
            GameManager.instance.lifeCount--;   // ライフを1減らす処理
            this.gameObject.SetActive(false);   // オブジェクトを消去する
        }

        if (collision.gameObject.tag == "Item")	// アイテムと当たった場合
        {
            itemGetAudio.Play();	// 効果音を再生する
        }
    }
}

7行目でAudioSource型の変数をpublicで宣言しておき、後ほどインスペクターウィンドウからアイテムを取得した際の音楽データをこの変数に入れます。

また、OnTriggerEnter2Dメソッドの中の28~31行目で、「Item」タグの付いたオブジェクトと接触したときに、Playメソッドで音声を流す処理を行っています。

スクリプトが書けたら、プレイヤーのインスペクターウィンドウに表示されているAudioSource型の変数に、先ほど作ったAudioSourceのオブジェクトを紐づけてあげれば、接触した際に音が鳴るようになります。

敵から弾を受けた時の音

次に、敵からの攻撃をプレイヤーが受けてやられてしまった時の音を付けていきます。

敵から攻撃を受けるとリトライされるようにしているので、この音はそのリトライする前に流せるように「RetryDirector」で作っていきます。

まずは「RetryDirector」を選択して、これまでと同様にインスペクターウィンドウからAudioSourceコンポーネントを付けて、「Audio Source」に音声データを紐づけておきます。

攻撃を受けたら音を鳴らすようにしたいので、「Play On Awake」のチェックを外しておきます。

次に、RetryDirectorのスクリプトに音を鳴らす処理を作っていきます。

using UnityEngine;
using UnityEngine.SceneManagement;  // LoadSceneメソッドを使うのに必要

public class RetryDirector : MonoBehaviour
{
    GameObject player;  // playerを参照する
    AudioSource audioSource;    // AudioSource用の変数を宣言
    bool retryCheck = false;    // リトライをするかどうかを判定する変数を宣言

    void Start()
    {
        player = GameObject.Find("player"); // playerのオブジェクトを取得する
        audioSource = GetComponent<AudioSource>();  // AudioSourceを取得する
    }

    void Update()
    {
        if (player.activeSelf == false && retryCheck == false)  // playerのステータスが「非アクティブ」の場合
        {
            audioSource.Play(); // 音を再生する
            retryCheck = true;  // リトライ処理を開始したのでtrueに変更
        }

        if (retryCheck == true && audioSource.isPlaying == false)   // 音声が鳴り終わった場合
        {
            SceneManager.LoadScene("RetryScene");    // シーンを読み込んでリトライする
        }
    }
}

7行目でAudioSourceの変数を作り、Startメソッドの中の13行目でAudioSourceを取得しておきます。

また、8行目でリトライをするかどうかを判定するためのbool型の変数として、「retryCheck」を作っています。

このretryCheckがまだfalseの状態で、プレイヤーが非アクティブになったら、20行目でPlayメソッドで音を再生するようにして、21行目でretryCheckの変数をtrueに変更しておきます。

そして音声が鳴り終わってからリトライする処理をしたいので、24行目でisPlayingの変数を使い音が停止されている場合のif文を作り、その中でリトライシーンに切り替わる処理を作っています。

これで、敵から攻撃を受けたら音声が流れて、音声が鳴り終わるとリトライされるようになりました。

銃弾が当たった時の爆発エフェクトを作る

次に、プレイヤーの銃弾が敵に当たった時に爆発するエフェクトを作っていきます。

爆発エフェクトを作る際は、

  • 爆発のアニメーションを作る
  • 爆発の音を付ける
  • Prefab化して衝突時に表示させる

という流れで作っていきます。

爆発のアニメーションを作る

アニメーションを作る際は、パラパラ漫画のように爆発している複数の画像をインポートしておきます。

爆発の最初の画像をゲーム内に配置して、「Window」から「Animation」「Animation」を選択します。

すると、Animationのウィンドウが開くので、「Create」を選択します。

Animationを保存する画面が表示されるので、ここではAssetsフォルダ内に「Animation」フォルダを作成して、「Explosion」という名前を付けておきます。

Animationを作ることができたら、「Add Property」をクリックして、「Sprite」の+ボタンを選択しておきます。

の部分をクリックしてあげると、タイムラインのところに最初に設定した画像が表示されます。

そして、プロジェクトウィンドウからそれぞれの爆発の画像を順番にドラッグ&ドロップして、アニメーションとして動くように並べてあげます。

なお、今回は最後のアニメーションの1枚に空の画像を指定しています。

このままだとアニメーションがループして動いてしまうので、プロジェクトウィンドウのAnimationから「Explosion」を選択して、インスペクターウィンドウにある「Loop Time」のチェックを外してあげます。

実際にゲームを実行してみると、爆発の画像が切り替わってアニメーションができているのが確認できます。

爆発の音を付ける

次に爆発のアニメーションとともに、音を再生するようにしていきます。

ヒエラルキーウィンドウから爆発のオブジェクトを選択して、インスペクターウィンドウから「Add Component」「Audio」「Audio Source」を選択して、Audio Resourceの項目に、爆発の音声を紐づけてあげます。

なお、爆発が表示された際に音声を流せれば良いので、Play On Awakeのチェックは入ったままにしています。

Prefab化して衝突時に表示させる

ここまでできたら、爆発のオブジェクトをPrefab化して銃弾が敵に当たった際に表示させるという処理を作っていきます。

まずは、ヒエラルキーウィンドウから爆発のオブジェクトを選択して、プロジェクトウィンドウにドラッグ&ドロップしてPrefab化します。

次に、エフェクトを表示させるために、「ExplosionEffect」という新しいスクリプトを作成します。

using UnityEngine;

public class ExplosionEffect : MonoBehaviour
{
    public GameObject explosion; // 爆発のオブジェクトを入れておく変数を宣言

    void OnTriggerEnter2D(Collider2D collision) // 当たり判定のあるオブジェクトと当たった場合
    {
        if (collision.gameObject.name == "PlayerBullet")   // 当たったオブジェクトがプレイヤーの弾の場合
        {
            GameObject instance = Instantiate(explosion);   // 爆発のオブジェクトを表示させる
            instance.transform.position = collision.transform.position; // 爆発のオブジェクトの位置を弾が当たった位置に移動させる
            Destroy(instance, 1.0f);    // 1秒後に破壊する
        }
    }
}

まず5行目でpublicを付けてGameObject型の変数を作り、後ほどインスペクターウィンドウから爆発のPrefabオブジェクトを入れてあげます。

プレイヤーの弾と当たった場合の処理として、11行目でInstantiateメソッドを使って爆発のオブジェクトを表示させています。

また、12行目で銃弾と敵オブジェクトが当たった位置に爆発のエフェクトが表示されるように、transform.positionの変数を使って移動しています。

エフェクトの表示が終わったら消去したいので、13行目でDestroy関数の第二引数に1.0を指定してあげることで、1秒後にオブジェクトを破壊することができます。

スクリプトが作成できたら、ExplosionEffectのスクリプトファイルを選択して、インスペクターウィンドウのExplosionの変数に先ほどPrefab化したオブジェクトを入れてあげます。

あとは、このスクリプトファイルを敵のオブジェクト(Prefabファイル)にアタッチしてあげれば、敵に銃弾が当たると爆発のアニメーションと音声が流れるようになります。

まとめ

このページでは、ゲーム内で音声を流したり、エフェクトを表示させる処理を作っていきました。

Unityでは、音声を流す際はAudio Sourceコンポーネントを使って再生することができます。

また、爆発などのような動くアニメーションは、Unity内のAnimationを使うことで簡単に作成することができます。

ここまでで、一通りのゲームの仕組みを作ることができたので、次はボスを作りスタートシーンとエンドシーンを作成してゲーム自体を完成させていきます。

後日、記事をアップロードする予定です!

最後までお読みいただきまして、ありがとうございました!

コメント