【Unity/2D】Flappy Bird風ゲームを作ってみる話 #11 SEを付ける
記事をご覧いただき、誠にありがとうございます。
投稿主の無能です。
前回は、BGMが再生できるようになりました。
今回は、SEを再生してプレイヤーのジャンプ音を出したいと思います。
SEについて
それではSEについてやっていきます。
ジャンプ音のSEは前回用意したものを使います。
Roll a Ballで効果音を再生した時は、AudioSourceをアタッチしたオブジェクトが破棄されるので、PlayClipAtPointという場所を指定して音を鳴らす、という方法で実現しました。
ただ、このPlayClipAtPointでの方法だと、スペースキーでジャンプをするので、エディタの例のようにスペースキーが押された間中効果音が再生されるので、音が重なって再生されます。
今回はオブジェクトが破棄されずAudioSourceが使えるので、音が重ならないようにしていきます。
SEをインポート
ではダウンロードしてあるジャンプ音をUnityにインポートしましょう。
前回作成しておいたSEフォルダにインポートして、「SE_Jump」にリネームします。
SEフォルダにインポートして「SE_Jump」にリネーム
プレイヤーにAudioSourceをアタッチ
ではプレイヤーにAudioSourceをアタッチします。
アタッチしたら、音量の調節を忘れずにしましょう。
ここでは0.3にします。
そして、ジャンプしたら効果音を再生するので、Play On Awakeのチェックを外しておきます。
AudioClipもスクリプトで設定するので、Noneのままで大丈夫です。
音量を0.3、Play On Awakeのチェックを外し、AudioClipはNoneのまま
スクリプトの追記
ではSEを再生するスクリプトの追記をしていきます。
PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
#region Var-Jump
[Header("ジャンプ力")]
[SerializeField] float jumpPower = 1f;
[Header("ジャンプの効果音")]
[SerializeField] AudioClip clip_Jump;
#endregion
#region Var-Internal
Rigidbody2D playerRB; // プレイヤーのRigidbody2D
public static bool isCollided = false; // 土管との接触判定のフラグ
AudioSource audioSource; // オーディオソース
#endregion
#region Start
void Start()
{
// プレイヤーのRigidbodyを取得
playerRB = GetComponent<Rigidbody2D>();
// オーディオソースを取得
audioSource = GetComponent<AudioSource>();
}
#endregion
#region Update
void Update()
{
// 接触フラグがtrueの場合
if (isCollided)
{
// 処理を中断
return;
}
// スペースキーが押された場合
if (Input.GetKey(KeyCode.Space))
{
// SEを再生する
PlaySE_Jump();
// ジャンプする
Jump();
}
// 土管との接触判定がtrueの場合
if (isCollided)
{
// 処理を中断
return;
}
}
#endregion
#region Jump
// ジャンプする
void Jump()
{
// プレイヤーに上方向のベクトルを持たせる
playerRB.velocity = Vector2.up * jumpPower;
}
#endregion
#region PlaySE_Jump
// ジャンプのSEを再生する
void PlaySE_Jump()
{
// SEを再生中の場合
if (audioSource.isPlaying)
{
// 処理を中断する
return;
}
// それ以外の場合
else
{
// SEを一度だけ再生
audioSource.PlayOneShot(clip_Jump);
}
}
#endregion
}
では見ていきましょう。
メンバ変数
追加したメンバ変数から見ていきます。
まずジャンプのSEとなるAudioClipのclip_Jumpです。
後は内部処理用の変数で、AudioSourceのaudioSourceです。
追加したメンバ変数はこの二つになります。
Start関数
次にStart関数を見ていきます。
Start関数では、先程アタッチしたaudioSourceを取得しています。
Start関数は以上です。
Update関数
次はUpdate関数を見ていきます。
スペースキーを押すとJump関数でジャンプの処理を行うので、その前にSEを再生するPlaySE_Jump関数を追加しています。
Update関数は以上です。
PlaySE_Jump関数
次は新たに追加したPlaySE_Jump関数になります。
まず条件分岐で、アタッチしたAudioSourceが現在音を再生中の場合は、処理を中断します。
isPlayingというのはAudioSourceが持っている再生中のフラグになります。
isPlayingがtrueだと再生中、falseだと再生していない、という事になります。
これで音が重なることを防げますね。
そしてそれ以外の場合、つまりisPlayingがfalseの場合は、SEをPlayOneShotで一度だけ再生します。
PlayOneShotもAudioSourceが持っている関数になります。
音量はAudioSourceで直接変更すればいいので、今回は指定したAudioClipの引数のみとなります。
これでスクリプトの追記は以上です。
では動作確認前の準備をしていきます。
動作確認前の準備
ではUnityで動作確認前の準備をします。
プレイヤーのInspectorビューに追加された項目を設定します。
ジャンプのSEの項目ができているので、先程インポートしたSEを設定します。
追加された項目にインポートしたSEを設定
上記の方法以外での実装方法
今回は割と簡単な方法でSEを音を重ねずに再生しましたが、上記の方法だと、一種類のSEだけしか音を重ならない状態で再生することしかできません。
理由は、例えばBGMを再生しているAudioSourceだと、絶えずBGMが流れているので、isPlayingがずっとtrueのままになるからです。
もし一つのAudioSourceから複数のSEを音を重ねずに鳴らしたい、という場合は、一つの例になりますが、
- Update関数でゲーム内時間を蓄積する
- floatで時間の閾値を設け、ゲーム内時間が閾値を超えたら再生する
- 再生中のフラグを設け、再生中であれば処理を中断する
- 処理が完了したら蓄積したゲーム内時間をリセット
という方法で実装できると思います。
AudioSourceを複数使う場合は、子オブジェクトにAudioSourceをアタッチし、子オブジェクトから効果音を再生するといいと思います。
もしSEが複数ある場合は、都度子オブジェクトを増やせば大丈夫です。
他にもいろいろな方法があると思うので、ご自身で考えてみてください。
まとめ
今回は
- SEをインポートした
- プレイヤーにAudioSourceをアタッチした
- スクリプトでSEが再生する機能を実装した
という事をやりました。
次回は、土管を通過したらスコアを取得する仕組みを作りたいと思います。
では、また次回!




コメント
コメントを投稿