この記事は「初心者でも作れるUnity簡単2Dゲームの作り方講座」の第6回です。
前回はゲームマネージャーを作成し、ゲームオーバー処理を呼び出す仕組みを作成しました。これによりプレイヤーが敵に横や下から触れたとき、とげオブジェクトに触れたとき、ステージ下に落下したときにゲームオーバーになるようにしました。
前回の記事:

今回がこの講座の最終回です。
ステージのゴールを作成し、プレイヤーがゴールしたら ”Clear” と表示されるようにします。
また、ゲームオーバーやクリア処理の後にリトライできるボタンを作成します。最後に、ジャンプ音やゲームオーバー音などの効果音を追加し、ゲームとして一通り遊べる形にしていきましょう。
ジャンプアクションゲームのゴールを作ろう
まずはゲームクリア処理から作成していきます。
今回は Goal というゲームオブジェクトを作成します。前回のとげと同じように当たり判定を使います。
プレイヤーがゴールに触れたかどうかを判定し、触れたら GameManager に「クリアした」と報告します。GameManager はその報告を受け取って、ゲーム状態を変更し、画面に”Clear”というテキストを表示します。
ゴールを配置しよう
まずは、Scene ビューに Goal を配置します。Project ウィンドウから Assets > 横スクロールアクションゲーム画像素材 を開きます。その中にある「ゴールポール」を Scene ビューにドラッグ&ドロップしましょう。

配置したゴールポールを選択して、Inspector から名前を Goal に変更します。

次に、Goal の位置を調整します。以下のように変更しましょう。

次に、Goal に当たり判定を追加します。Inspector画面の Add Component から Physics 2D > Box Collider 2D を選択して追加しましょう。

今回は、Box Collider 2D をトリガーとして使います。Box Collider 2D の Is Trigger にチェックを入れましょう。

トリガーとは?
Collider は、通常は「ぶつかるための当たり判定」として使います。
たとえば、Player が地面に乗れたり、Enemy にぶつかったりするのは、Collider によって物理的な接触が発生しているからです。
一方で Trigger は、「ぶつかって止める」のではなく、「触れたことだけを検知する」ために使います。つまり壁に当たって止まるような動きは起こりません。
Goal は「触れたらクリアにするためのセンサー」として使うので、今回は Trigger として設定します。
ゲームクリア表示用のテキストを作ろう
次に、”Clear”と表示するテキストを作成します。
Hierarchy から Canvas の中にある GameOverText を選択します。選択した状態で Ctrl + D を押して複製しましょう。

複製した GameOverText (1) を選択して、名前を ClearText に変更します。

次に、Text の文字を Clear に変更しましょう。

最後に、文字の色を黄色に変更します。

ゲームマネージャーにクリア処理を追加しよう
次はGameManager2Dスクリプトにゲームクリアの処理を追加していきます。
Project ウィンドウから Assets > Scripts フォルダを開きます。その中にある GameManager2D をダブルクリックで開きましょう。

開けたら、以下のように変更します。
GameManager2D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
using TMPro; using UnityEngine; public class GameManager2D : MonoBehaviour { public enum GameState { Playing, GameOver, Clear } [Header("UI")] public GameObject gameOverText; public GameObject clearText; public GameState currentState = GameState.Playing; public void GameOver() { currentState = GameState.GameOver; gameOverText.SetActive(true); } public void Clear() { currentState = GameState.Clear; clearText.SetActive(true); } } |
スクリプトの解説
まず、GameState に Clear を追加しています。これで、ゲームの状態として Playing、GameOver、Clear の 3 つを扱えるようになります。
|
1 2 3 4 5 6 |
public enum GameState { Playing, GameOver, Clear } |
次に、clearText を追加しています。
|
1 2 3 |
[Header("UI")] public GameObject gameOverText; public GameObject clearText; |
これは、Clear と表示する UI を GameManager から操作するために必要です。ゲームオーバーのときに gameOverText を表示したように、ゲームクリアのときは clearText を表示します。
最後に、Clear メソッドを作成しています。
|
1 2 3 4 5 |
public void Clear() { currentState = GameState.Clear; clearText.SetActive(true); } |
この処理では、まず currentState を Clear に変更しています。
そのあと、clearText.SetActive(true); で ClearText を表示しています。
ゴールのスクリプトをつくろう
ここまでできたら、Ctrl + S で必ず保存してUnityに戻りましょう。
次に、Goal 用のスクリプトを作成します。Project ウィンドウの Assets > Scripts フォルダを開きます。Scripts フォルダ内で右クリックし、Create > MonoBehaviour Script を選択します。名前は Goal2D にしましょう。

作成できたら、Goal2D をダブルクリックで開きます。開けたら、以下のコードを記述してください。
Goal2D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using UnityEngine; public class Goal2D : MonoBehaviour { private GameManager2D GameManager; void Start() { GameManager = FindAnyObjectByType<GameManager2D>(); } void OnTriggerEnter2D(Collider2D other) { if (other.CompareTag("Player")) { GameManager.Clear(); } } } |
スクリプトの解説
まず、Start の中で GameManager2D を取得しています。
|
1 |
GameManager = FindAnyObjectByType<GameManager2D>(); |
これにより、Scene 内にある GameManager が持つ GameManager2D コンポーネントを Goal2D から使えるようになります。
次に、OnTriggerEnter2D を作っています。
|
1 |
void OnTriggerEnter2D(Collider2D other) |
OnTriggerEnter2D は、Trigger に設定した Collider に、別の Collider が入ってきたときに呼ばれる処理です。
その中で、触れた相手の Tag を確認しています。
|
1 |
if (other.CompareTag("Player")) |
触れた相手が Player だったときだけ、クリアを呼び出します。
|
1 |
GameManager.Clear(); |
これで、Player が Goal に触れると、GameManager にゲームクリアしたことを報告できます。
Trigger と OnCollision の違い
これまでの Enemy やとげでは、OnCollisionEnter2D を使ってきました。OnCollisionEnter2D は、Collider 同士が物理的にぶつかったときに呼ばれる処理です。
一方で、今回使っている OnTriggerEnter2D は、Is Trigger にチェックを入れた Collider に触れたときに呼ばれる処理です。Collider と物理的にぶつかることはありません。
動作を確認しよう
ここまでできたら、Ctrl + S で保存してUnity画面に戻ります。
Project ウィンドウから Goal2D スクリプトを、Hierarchy にある Goal にドラッグ&ドロップしましょう。

次に、GameManager を選択します。

Inspector にある GameManager2D の Clear Text に、Hierarchy の ClearText を設定しましょう。

ここまで出来たら、再生ボタンを押しましょう。Player を操作して Goal に触れてみてください。

Goal に触れたときに、画面に Clear と表示されれば成功です。
また、ゲームクリア状態になったあとにプレイヤーの操作が止まるかも確認しましょう。
前回作成した PlayerController2D では、GameManager の状態が Playing ではないときに操作を止める処理を入れています。
そのため、今回 currentState が Clear になると、Game Over のときと同じように Player の操作が止まります。

再生して確認してみると、Clear の文字が少し見づらいかもしれません。そこで、ClearText に Outline を追加して、文字のふちを少し目立たせます。
まずは再生を止めましょう。
Hierarchy から ClearText を選択します。

ClearText は現在非アクティブになっているので、Inspector の一番上にあるチェックを入れて、一度アクティブにします。

次に、Inspector の下の方にある Outline にチェックを入れましょう。

Outline は、文字の外側にふちを付ける設定です。背景と文字の色が近いと、文字が少し見づらくなることがあります。Outline を付けると、文字の輪郭がはっきりして、Game ビュー上でも見やすくなります。
Outline の Thickness を 0.25 に変更しましょう。

すると、Clear の文字が見やすくなります。

ここまでできたら、ClearText をもう一度非アクティブに戻しておきましょう。

ゲームリトライできるようにしよう
次にゲームのリトライボタンを作成します。
今の状態ではゲームオーバーやゲームクリアになった後、もう一度遊ぶには再生し直す必要があります。
そこで、画面上にリトライボタンを表示し、ボタンを押したら現在のシーンを読み込み直して最初から再度プレイできるようにします。
リトライボタンを用意しよう
まずは、ゲームリトライを行うために新しく Retry ボタンを作成します。
以前作成した GameOverText や ClearText と同じように、ボタンも UI の一つです。
Hierarchy から Canvas を選択します。Canvas を右クリックして、UI > Button – TextMeshPro を選択しましょう。作成した Button の名前を RetryButton に変更します。

次に、RetryButton の子オブジェクトにある Text を削除します。

今回は文字ではなくボタン用の画像を使うのでこの Text は使用しません。
次に、RetryButton を選択します。Inspector から位置とサイズを調整して、画面中央より少し下に大きく表示されるようにします。以下のように設定しましょう。

次に、RetryButton の見た目を設定します。今回は文字だけのボタンではなく、画像素材のリトライボタンを使います。まず、以下のRetryButton の画像を保存してダウンロードしましょう。
ダウンロードできたら、Project ウィンドウの Assets > 横スクロールアクションゲーム画像素材 フォルダに追加します。

画像を追加できたら、Hierarchy から RetryButton を選択します。
Inspector の Image コンポーネントを確認しましょう。Image コンポーネントの Source Image に、追加したRetryButtonのスプライトをドラッグ&ドロップします。

これで、RetryButton の見た目がリトライボタンの画像に変わります。

最後に、RetryButton は最初から表示するものではないので、非アクティブにしておきます。Inspector の左上にあるチェックを外して、RetryButton を非アクティブにしましょう。

RetryButton は、ゲームオーバーまたはゲームクリアになったあとに GameManager から呼び出して表示します。
スクリプトを書こう
今回は、RetryButton 用に新しいスクリプトを作成する必要はありません。
RetryButton を選択して Inspector を見ると、Button コンポーネントの中に On Click() という項目があります。

On Click() は、ボタンが押されたときに呼び出す処理を設定する場所です。
今回は GameManager2D に Retryメソッドという関数を作成し、その Retry を On Click 機能から呼び出します。
リトライの作り方は簡単で、現在のシーンをもう一度読み込み直すだけです。
例えば、ゲームプレイ中に一度Unityエディタの再生を止め、もう一度再生すると、プレイヤーや敵の位置、ゲームオーバーテキストの表示などが最初の状態に戻りますよね。
これはシーンが最初から読み込まれるからです。
つまり、スクリプトから今のシーンを読み込み直せばゲームを最初からやり直すことができます。
Project ウィンドウから Assets > Scripts フォルダを開きます。GameManager2D をダブルクリックで開きましょう。

開けたら、以下のように変更します。
GameManager2D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
using TMPro; using UnityEngine; using UnityEngine.SceneManagement; public class GameManager2D : MonoBehaviour { public enum GameState { Playing, GameOver, Clear } [Header("UI")] public GameObject gameOverText; public GameObject clearText; public GameObject retryButton; public GameState currentState = GameState.Playing; public void GameOver() { currentState = GameState.GameOver; gameOverText.SetActive(true); retryButton.SetActive(true); } public void Clear() { currentState = GameState.Clear; clearText.SetActive(true); retryButton.SetActive(true); } public void Retry() { //今のシーンを取得して読み込み SceneManager.LoadScene(SceneManager.GetActiveScene().name); } } |
スクリプトの解説
まず、using UnityEngine.SceneManagement; を追加しています。
|
1 2 3 |
using TMPro; using UnityEngine; using UnityEngine.SceneManagement; |
これはシーンを読み込み直すために必要なUnity内蔵の機能です。SceneManager を使うことで、別のシーンを読み込んだり、今のシーンをもう一度読み込んだりできます。
次に、retryButton を追加しています。
|
1 2 3 4 |
[Header("UI")] public GameObject gameOverText; public GameObject clearText; public GameObject retryButton; |
これでGameManager から RetryButton を表示できるようになります。
次に、GameOverメソッドの中に retryButton.SetActive(true); を追加しています。
|
1 2 3 4 5 6 |
public void GameOver() { currentState = GameState.GameOver; gameOverText.SetActive(true); retryButton.SetActive(true); } |
ゲームオーバーになったときにGameOverText と一緒に RetryButton も表示します。
Clearメソッドの中にも同じように retryButton.SetActive(true); を追加しています。
|
1 2 3 4 5 6 |
public void Clear() { currentState = GameState.Clear; clearText.SetActive(true); retryButton.SetActive(true); } |
これでゲームクリアしたときにリトライボタンが表示されます。
最後に Retryメソッドを追加しています。
|
1 2 3 4 5 |
public void Retry() { //今のシーンを取得して読み込み SceneManager.LoadScene(SceneManager.GetActiveScene().name); } |
ここではSceneManager.GetActiveScene() で、まず現在開いているシーンを取得しています。
そのあと、.name でそのシーンの名前を取得しています。SceneManager.LoadScene は、読み込みたいシーンをシーン名で指定します。
- 現在のシーンを取得する
- 現在のシーン名を取得する
- そのシーン名を LoadSceneメソッドに渡す
という流れで今のシーンを読み込み直しています。
これでリトライボタンから Retryメソッドが呼ばれ、現在のシーンが最初から読み込まれます。
動作を確認しよう
ここまでできたら、Ctrl + S で必ず保存してUnity画面に戻りましょう。Hierarchy から GameManager を選択します。

Inspector の GameManager2D に Retry Button という項目が追加されています。
Hierarchy にある RetryButtonオブジェクトを GameManager2Dコンポーネントの Retry Button変数にドラッグ&ドロップさせて設定しましょう。

これでゲームマネージャからリトライボタンを表示できるようになります。
次はRetryButton の On Click() に Retryメソッドを設定しましょう。
まずはHierarchyのRetryButtonを選択します。

Inspector画面の Buttonコンポーネントにある On Click()を確認しましょう。List Empty と書いてある場所の右下にある + ボタンをクリックします。

新しい項目が追加されたら、Hierarchy にある GameManagerオブジェクトを On Click()部分にドラッグ&ドロップします。

次に右側の No Function と書かれているドロップダウンをクリックします。GameManager2D > Retry() を選択しましょう。


これで、RetryButton が押されたときに、GameManager2D の Retry が呼び出されます。OnClick は、「ボタンが押されたときに何を実行するか」を設定する場所です。今回は、RetryButton が押されたら GameManager の Retry を実行するように設定しました。
ここまでできたら、再生ボタンを押しましょう。

まずはプレイヤーを操作してゲームオーバーにしてみます。GameOverText と RetryButton が表示されれば成功です。
次に、リトライボタンをクリックしてみましょう。シーンが最初から読み込まれ、Player や Enemy が最初の状態に戻れば成功です。
最後にゴールに触れてゲームクリアにしたときの確認もしてみましょう。ClearText と RetryButton が表示され、RetryButton を押すと最初からやり直せれば完成です。
Unity6で作った2Dゲームに効果音をつけよう
最後に効果音を追加してゲームとして仕上げていきましょう。

今回は音を鳴らす処理を GameManager にまとめて作成します。
プレイヤーがジャンプしたとき、敵キャラを踏んだとき、ゲームオーバーやゲームクリアになったとき、それぞれのオブジェクトから GameManager に「この音を鳴らして」と伝える形にします。
ゲームオーバー判定などと同じ作り方ですね。
下準備をしよう
まずUnityで音を鳴らすための準備をします。Hierarchy から GameManager を選択します。

Inspector の Add Component をクリックし、Audio > Audio Source を選択しましょう。

Audio Source は、Unityで音を再生するためのコンポーネントです。
画像を表示するために SpriteRenderer が必要だったように、音を鳴らすためには Audio Source が必要になります。
次に、効果音をまとめるフォルダを作成します。Project ウィンドウの Assets 内で右クリックします。Create > Folder を選択し、名前を Sounds に変更しましょう。

作成した Sounds フォルダを開きます。
次に、今回使う効果音を用意します。以下の 4 つをダウンロードしてください。
- ゲームオーバー
”チーン1”で検索した結果[1]|効果音ラボ - ゲームクリア
”歓声と拍手1”で検索した結果[1]|効果音ラボ - ジャンプ音
”ニュッ2”で検索した結果[1]|効果音ラボ - 敵を倒す
”可愛くメッセージ表示”で検索した結果[1]|効果音ラボ
ダウンロードできたら、Soundsフォルダにドラッグ&ドロップしましょう。

ゲームマネージャーに音の管理をさせよう
ここでは GameManager から音を再生する仕組みを作成します。
GameManager は、鳴らしたい音を受け取りその音を Audio Source で再生します。
Project ウィンドウから Assets > Scripts フォルダを開きます。GameManager2D をダブルクリックで開きましょう。

スクリプトを開いたら以下のように追記します。
GameManager2D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
using TMPro; using UnityEngine; using UnityEngine.SceneManagement; public class GameManager2D : MonoBehaviour { public enum GameState { Playing, GameOver, Clear } [Header("UI")] public GameObject gameOverText; public GameObject clearText; public GameObject retryButton; public GameState currentState = GameState.Playing; private AudioSource gameAudioSource; void Start() { //ゲームマネージャーのAudioSourceを取得 gameAudioSource = GetComponent<AudioSource>(); } public void GameOver() { currentState = GameState.GameOver; gameOverText.SetActive(true); retryButton.SetActive(true); } public void Clear() { currentState = GameState.Clear; clearText.SetActive(true); retryButton.SetActive(true); } public void Retry() { //今のシーンを取得して読み込み SceneManager.LoadScene(SceneManager.GetActiveScene().name); } public void PlaySound(AudioClip sound) { gameAudioSource.PlayOneShot(sound); } } |
スクリプトの解説
このスクリプトでは最初に AudioSource を入れるための変数を用意しています。
|
1 |
private AudioSource gameAudioSource; |
AudioSource は、Unityで音を再生するためのコンポーネントです。

今回は GameManager に Audio Source を追加し、スクリプトから使えるようにします。
そのためにStart の中で AudioSource を取得しています。
|
1 2 3 4 5 |
void Start() { //ゲームマネージャーのAudioSourceを取得 gameAudioSource = GetComponent<AudioSource>(); } |
GetComponent<AudioSource>() は、このスクリプトが付いている GameObject から AudioSource を探して取得する処理です。
GameManager2D は GameManager に付いているコンポーネントです。
Audio Source も GameManager に追加したので、GetComponent<AudioSource>() で取得できます。
次に、PlaySound という関数を追加しています。
|
1 2 3 4 |
public void PlaySound(AudioClip sound) { gameAudioSource.PlayOneShot(sound); } |
PlaySound は、音を再生するために作った関数です。AudioClip sound の部分では、再生したい音を受け取っています。
AudioClip は、Unityで扱う「音そのもの」のデータです。ジャンプ音、ゲームオーバー音、クリア音などの音素材は、Unityでは AudioClip として扱われます。
受け取った音は、PlayOneShot で再生しています。
|
1 |
gameAudioSource.PlayOneShot(sound); |
PlayOneShot は、指定した音を 1 回だけ再生する処理です。効果音はBGMのようにずっと流すものではなく、ジャンプした瞬間やゲームオーバーになった瞬間に1回だけ鳴らしたい音です。そのため、今回は PlayOneShot を使います。
関数と引数
関数は、よく使う処理をまとめておくためのものです。今回の PlaySound は、音を鳴らす処理をまとめた関数です。
|
1 |
public void PlaySound(AudioClip sound) |
この AudioClip sound の部分を、引数(ひきすう)といいます。引数は、関数に渡す情報です。今回の場合は、どの音を鳴らすのかを PlaySound に渡しています。たとえば、ジャンプ音を渡せばジャンプ音が鳴ります。ゲームオーバー音を渡せばゲームオーバー音が鳴ります。
同じ PlaySound という関数でも、渡す AudioClip を変えることで、違う効果音を再生できます。
つまり、PlaySound は「受け取った音を1回だけ鳴らすための関数」です。
ゲームオーバー・ゲームクリア音を作成しよう
そのまま GameManager2D は開いたままにして、ゲームオーバー音と ゲームクリア音を追加していきます。
先ほど作成した PlaySound 関数と引数をどのように使うのかを確認していきましょう。次のハイライト部分のコードを追記しましょう。
GameManager2D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
using TMPro; using UnityEngine; using UnityEngine.SceneManagement; public class GameManager2D : MonoBehaviour { public enum GameState { Playing, GameOver, Clear } [Header("UI")] public GameObject gameOverText; public GameObject clearText; public GameObject retryButton; [Header("Sound")] public AudioClip gameOverSound; public AudioClip clearSound; public GameState currentState = GameState.Playing; private AudioSource gameAudioSource; void Start() { //ゲームマネージャーのAudioSourceを取得 gameAudioSource = GetComponent<AudioSource>(); } public void GameOver() { currentState = GameState.GameOver; gameOverText.SetActive(true); retryButton.SetActive(true); PlaySound(gameOverSound); } public void Clear() { currentState = GameState.Clear; clearText.SetActive(true); retryButton.SetActive(true); PlaySound(clearSound); } public void Retry() { //今のシーンを取得して読み込み SceneManager.LoadScene(SceneManager.GetActiveScene().name); } public void PlaySound(AudioClip sound) { gameAudioSource.PlayOneShot(sound); } } |
スクリプトの解説
まず、ゲームオーバーとゲームクリアの音を入れる変数を追加しています。
|
1 2 3 |
[Header("Sound")] public AudioClip gameOverSound; public AudioClip clearSound; |
AudioClip は、Unityで扱う音のデータです。ここに、Sounds フォルダに追加したゲームオーバー音とクリア音を割り当てます。
次に、GameOver の中で PlaySound を呼び出しています。
|
1 2 3 4 5 6 7 |
public void GameOver() { currentState = GameState.GameOver; gameOverText.SetActive(true); retryButton.SetActive(true); PlaySound(gameOverSound); } |
これでゲームオーバーになったときに gameOverSound が再生されます。
Clearメソッドの中でも、同じように PlaySound を呼び出しています。
|
1 2 3 4 5 6 7 |
public void Clear() { currentState = GameState.Clear; clearText.SetActive(true); retryButton.SetActive(true); PlaySound(clearSound); } |
ゲームクリアになったときに clearSound が再生されます。
今回の PlaySound は、渡された AudioClip を1回だけ再生する関数です。GameOverメソッドでは gameOverSound を渡し、Clearメソッドでは clearSound を渡しています。
同じように PlaySound を使っていても、渡す音を変えることで違う効果音を鳴らせます。
動作を確認しよう
ここまでできたら、Ctrl + S で必ず保存してUnity画面に戻りましょう。Hierarchy から GameManager を選択します。

Inspector の GameManager2D を確認すると、Sound という項目が追加されています。
Game Over Sound に、Sounds フォルダ内のゲームオーバー用の音源を、Clear Sound に、Sounds フォルダ内のクリア音をドラッグ&ドロップしましょう。

ここまでできたら、再生して確認します。
プレイヤーが敵キャラやとげに触れてゲームオーバーになったときにゲームオーバー音が鳴れば成功です。また、プレイヤーがゴールに触れてゲームクリアになったときにクリア音が鳴るかも確認しましょう。
ジャンプで音を鳴らそう
続いて、プレイヤーがジャンプしたときにも音を鳴らしてみましょう。Project ウィンドウから Assets > Scripts フォルダを開きます。PlayerController2D をダブルクリックで開きましょう。

開けたら、以下のように変更します。
PlayerController2D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
using UnityEngine; public class PlayerController2D : MonoBehaviour { [Header("Move Settings")] public float moveSpeed = 5f; public float jumpPower = 8f; [Header("Ground Check")] public Transform groundCheck; public float groundCheckRadius = 0.2f; public LayerMask groundLayer; [Header("Animation")] public float walkAnimationSpeed = 1f; [Header("Death")] public float fallY = -10f; [Header("Sound")] public AudioClip jumpSound; private Rigidbody2D playerRigidbody; private float horizontalInput; private bool isGrounded; private SpriteRenderer playerSprite; private Animator playerAnimator; private GameManager2D GameManager; // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { //プレイヤーのRigidbody2Dを取得 playerRigidbody = GetComponent<Rigidbody2D>(); //プレイヤーのSpriteRendererを取得 playerSprite = GetComponent<SpriteRenderer>(); //プレイヤーのAnimatorを取得 playerAnimator = GetComponent<Animator>(); //GameManager2Dをシーン内から探して取得 GameManager = FindAnyObjectByType<GameManager2D>(); } // Update is called once per frame void Update() { //ゲームの状態を確認 if (GameManager.currentState != GameManager2D.GameState.Playing) { //状態がPlayingでなければ処理終了 horizontalInput = 0f; playerAnimator.speed = 0f; return; } //プレイヤーの落下判定 if(transform.position.y < fallY) { GameManager.GameOver(); } // 入力、-1:左、0:なし、1:右、のように扱います horizontalInput = 0f; playerAnimator.speed = 0f; if (Input.GetKey(KeyCode.LeftArrow)) { horizontalInput = -1f; playerSprite.flipX = true; //アニメーションを再生 playerAnimator.speed = walkAnimationSpeed; } else if (Input.GetKey(KeyCode.RightArrow)) { horizontalInput = 1f; playerSprite.flipX = false; //アニメーションを再生 playerAnimator.speed = walkAnimationSpeed; } //GroundCheckに小さな円を作成、Groundレイヤーに接触しているか確認 isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer); if (Input.GetKeyDown(KeyCode.Space) && isGrounded) { playerRigidbody.linearVelocity = new Vector2(playerRigidbody.linearVelocity.x, jumpPower); GameManager.PlaySound(jumpSound); } //地面にいないならアニメーションを止める if (!isGrounded) { playerAnimator.speed = 0f; } } void FixedUpdate() { // Rigidbody2Dの速度を変更して、左右に移動します。 playerRigidbody.linearVelocity = new Vector2(horizontalInput * moveSpeed, playerRigidbody.linearVelocity.y); } void OnCollisionEnter2D(Collision2D collision) { if(collision.gameObject.CompareTag("Death")) { GameManager.GameOver(); } } } |
スクリプトの解説
最初にジャンプ音を入れるための変数を追加しています。
|
1 2 |
[Header("Sound")] public AudioClip jumpSound; |
AudioClip は、Unityで扱う音のデータです。ここに Soundsフォルダに追加したジャンプ音を割り当てます。
次に、ジャンプ処理の中に GameManager.PlaySound(jumpSound); を追加しています。
|
1 2 3 4 5 |
if (Input.GetKeyDown(KeyCode.Space) && isGrounded) { playerRigidbody.linearVelocity = new Vector2(playerRigidbody.linearVelocity.x, jumpPower); GameManager.PlaySound(jumpSound); } |
ここではSpace キーが押されていて、さらにプレイヤーが地面にいるときだけジャンプします。そのジャンプ処理と同じタイミングでGameManager の PlaySound を呼び出しています。
これでPlayer がジャンプした瞬間に jumpSound が再生されます。
音を実際に鳴らしているのは Player ではなく、GameManager です。Player は「ジャンプ音を鳴らして」と GameManager に伝えています。
音を再生する処理を GameManager にまとめたまま、Player のジャンプ音も鳴らすことができます。
動作を確認しよう
ここまでできたら、Ctrl + S で必ず保存してUnity画面に戻りましょう。Hierarchy で Player を選択します。

Inspector の PlayerController2D を確認すると、Sound という項目が追加されています。Jump Sound に、Sounds フォルダ内のジャンプ音を設定しましょう。

再生して確認します。Player を操作して Space キーでジャンプしてみましょう。ジャンプした瞬間に音が鳴れば成功です。
敵を倒す音をつくろう
最後に敵キャラを踏んだときの音を追加します。Project ウィンドウから Assets > Scripts フォルダを開きます。EnemyPatrol2D をダブルクリックで開きましょう。

開けたら、以下のように変更します。
EnemyPatrol2D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
using UnityEngine; public class EnemyPatrol2D : MonoBehaviour { [Header("Move Settings")] public float moveSpeed = 2f; public float moveDistance = 3f; [Header("Stomp Settings")] public float stompHeight = 0.3f; public float playerBouncePower = 8f; [Header("Sound")] public AudioClip stompSound; private Vector2 startPosition; private int moveDirection = 1; private SpriteRenderer enemySprite; private GameManager2D GameManager; // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { //最初の位置を保存 startPosition = transform.position; //スライムのSpriteRendererを取得 enemySprite = GetComponent<SpriteRenderer>(); //GameManager2Dをシーン内から探して取得 GameManager = FindAnyObjectByType<GameManager2D>(); } // Update is called once per frame void Update() { //敵を動かす transform.Translate(Vector2.right * moveDirection * moveSpeed * Time.deltaTime); //反復移動させる if (transform.position.x > startPosition.x + moveDistance) { moveDirection = -1; enemySprite.flipX = true; } else if (transform.position.x < startPosition.x - moveDistance) { moveDirection = 1; enemySprite.flipX = false; } } void OnCollisionEnter2D(Collision2D collision) { if (collision.gameObject.CompareTag("Player")) { if (IsStompedByPlayer(collision.gameObject)) { Destroy(gameObject); Rigidbody2D playerRigidbody = collision.gameObject.GetComponent<Rigidbody2D>(); playerRigidbody.linearVelocity = new Vector2(playerRigidbody.linearVelocity.x, playerBouncePower); GameManager.PlaySound(stompSound); } else { GameManager.GameOver(); } } } bool IsStompedByPlayer(GameObject player) { Rigidbody2D playerRigidbody = player.GetComponent<Rigidbody2D>(); bool playerIsAboveEnemy = player.transform.position.y > transform.position.y + stompHeight; bool playerIsFalling = playerRigidbody.linearVelocity.y <= 0f; return playerIsAboveEnemy && playerIsFalling; } } |
スクリプトの解説
まずはEnemy を踏んだときの音を入れる変数を追加しています。
|
1 2 |
[Header("Sound")] public AudioClip stompSound; |
この stompSound変数に Soundsフォルダに追加した敵を倒す音を割り当てます。
次に、Enemy を踏んだと判定された処理の中で、GameManager.PlaySound を呼び出しています。
|
1 2 3 4 5 6 7 |
if (IsStompedByPlayer(collision.gameObject)) { Destroy(gameObject); Rigidbody2D playerRigidbody = collision.gameObject.GetComponent<Rigidbody2D>(); playerRigidbody.linearVelocity = new Vector2(playerRigidbody.linearVelocity.x, playerBouncePower); GameManager.PlaySound(stompSound); } |
Player が Enemy を上から踏んだときに stompSound が再生されます。
今回も音を実際に鳴らしているのは GameManager です。Enemy は「敵を踏んだ音を鳴らして」と GameManager に伝えているだけです。
Destroy(gameObject); で Enemy は消えますが、音は GameManager の AudioSource から鳴らしています。
そのため、Enemy が消えても効果音は消えずに再生することができます。これも音源管理を1つのオブジェクトにまとめる理由です。
動作を確認しよう
ここまでできたら、Ctrl + S で必ず保存してUnity画面に戻りましょう。Hierarchy で Enemy を選択します。

Inspector の EnemyPatrol2D を確認すると、Sound という項目が追加されています。Stomp Sound に、Sounds フォルダ内の敵を倒す音を設定しましょう。

それではUnityエディタを再生して確認します。敵キャラをを上から踏んでみましょう。Enemy が消え、同時に効果音が鳴れば成功です。
プロジェクトファイルのダウンロード
今回の講座で作ったプロジェクトファイルのダウンロードリンクを用意しました。
まとめ
お疲れ様した!これにてUnity6を用いたシンプル2D横スクロールアクションゲームのチュートリアル講座は終了です。
ここまでで、プレイヤーの移動、ジャンプ、接地判定、アニメーション、カメラ追従、敵キャラ、ゲームオーバー、ゲームクリア、リトライから効果音まで作成しました。
これで簡単な 2D アクションゲームとして一通り遊べる形になりました。
しかし、まだまだ改善できる部分や追加できる要素はたくさんあります。たとえば、ステージを増やしたり、Enemy の種類を増やしたり、アイテムを追加したり、制限時間を作ったりすることもできます。
作っている途中で、「こういう動きがあったら面白そう」「こんな仕組みを追加したい」と思いついた部分もあるかもしれません。今回学んだ内容を応用すれば、いろいろな仕組みを作れるようになります。
最初はスクリプトの中で何がどう動いているのかを完璧に理解できなくても大丈夫です。
まずはパズルのように学んだことを組み合わせて自分で何か動かしてみましょう。コピペを組み合わせながらでも自分の思った動きを作れたなら、それは大きな一歩です。
途中でエラーが出たり、思った通りに動かなかったりすることもあります。
しかし、うまく動かないときには必ず原因があります。エラーを確認し、どの処理で止まっているのかを探しながら少しずつ直していきましょう。
自分で試して失敗して原因を見つけて直すことがゲーム制作ではとても大切な勉強になります。
今回作成したゲームをもとに、ぜひ自分だけのステージや仕組みを追加してみてください。
また、さらに発展的・実践的な内容を扱ったUnity入門の森の講座もあるのでぜひ挑戦してみてください。
この講座の発展形としては以下の「ロックマン風本格2Dアクションゲーム講座」が特におススメです。

Unity 2Dアクションゲームの作り方 ~ロックマン風横スクロールゲーム編~はこちら >>
現場レベルのゲーム制作が、すべてここで学べます。






コメント