Skip to content

第19回 仕上げと公開 ​

この回でつくるもの:やられたときやボスを倒したときに画面がゆれ、弾がキラキラ光り、ハイスコアが保存されるようにします。最後に、ゲームを Web ブラウザで遊べる形にして、公開する方法を学びます。

この回で学ぶこと ​

  • static な変数で、どこからでもカメラをゆらす(第10回の復習)
  • Bloom(明るいところをにじませて光らせる効果)を使う
  • PlayerPrefs で、ゲームを終わってもハイスコアを残す
  • File > Build Profiles で Web(WebGL)用にビルドする
  • Unity Play でゲームを公開する方法と、公開するときの約束

前回までのふりかえり ​

第18回では、ScriptableObject の「出現表」どおりに敵が出るようにしました。 60秒たつと WARNING!! が出てボスが登場し、倒すと STAGE CLEAR の画面が出ます。 これでゲームの流れは完成です。今回は見た目と手ざわりを仕上げて、みんなに遊んでもらえる形にします。

1. カメラをゆらす ​

1-1. CameraShake スクリプトを作る ​

やられたときやボスを倒したときに画面がゆれると、ぐっと迫力が出ます。

  1. Project ウィンドウで Assets/_Game/Scripts を開きます。
  2. 右クリックし、Create > Scripting > MonoBehaviour Script を選びます。
  3. 名前を CameraShake にします。
  4. ダブルクリックして開き、中身を全部消して、次のコードを書きます。
csharp
using System.Collections;
using UnityEngine;

// カメラをゆらす
public class CameraShake : MonoBehaviour
{
    public static CameraShake instance;

    Vector3 startPos;

    void Awake()
    {
        instance = this;
        startPos = transform.localPosition;
    }

    public void Shake(float duration, float strength)
    {
        StopAllCoroutines();
        StartCoroutine(ShakeRoutine(duration, strength));
    }

    IEnumerator ShakeRoutine(float duration, float strength)
    {
        float time = 0f;
        while (time < duration)
        {
            Vector2 offset = Random.insideUnitCircle * strength;
            transform.localPosition = startPos + new Vector3(offset.x, offset.y, 0f);
            time += Time.deltaTime;
            yield return null;
        }
        transform.localPosition = startPos;
    }
}

保存します(Ctrl+S、Macは Cmd+S)。

コードの解説

行意味
public static CameraShake instance;第10回の GameManager.instance と同じです。static を付けると、どのスクリプトからでも CameraShake.instance で呼べます
startPos = transform.localPosition;ゆらす前のカメラの位置 (0, 0, -10) を覚えておきます
StopAllCoroutines();ゆれている途中でもう一度呼ばれたら、前のゆれを止めて新しくゆらし直します
Random.insideUnitCircle * strength半径1の円の中のランダムな点です。strength をかけて、ゆれの大きさにします
yield return null;1フレームだけ待ちます。毎フレーム、少しずつちがう場所にカメラを動かします
transform.localPosition = startPos;最後に元の位置に戻します

1-2. Main Camera に付ける ​

  1. Hierarchy で Main Camera を選びます。
  2. Add Component で Camera Shake を追加します。

先に付けておく

このあと PlayerLife と Enemy から CameraShake.instance を使います。Main Camera に Camera Shake が付いていないと、やられたときにエラー(NullReferenceException)が出ます。

1-3. PlayerLife から呼ぶ ​

Assets/_Game/Scripts/PlayerLife.cs を開き、次のように書きかえます。

csharp
using System.Collections;
using UnityEngine;

// 自機がやられる・復活する
public class PlayerLife : MonoBehaviour
{
    public GameObject explosionPrefab;    // 爆発(第9回)
    public AudioClip explosionSound;      // 爆発音(第9回)
    public GameObject model;              // 点滅させる見た目(第11回)
    public float invincibleTime = 2f;     // 無敵時間(第11回)

    bool isInvincible = false;

    void OnTriggerEnter(Collider other)
    {
        if (isInvincible) return;

        if (other.CompareTag("Enemy") || other.CompareTag("EnemyBullet"))
        {
            if (other.CompareTag("EnemyBullet"))
            {
                Destroy(other.gameObject);
            }

            // シールドがあれば、シールドが代わりに消える(第15回)
            PowerUpManager powerUp = GetComponent<PowerUpManager>();
            if (powerUp != null && powerUp.UseShield())
            {
                return;
            }

            Hit();
        }
    }

    void Hit()
    {
        if (explosionPrefab != null)
        {
            Instantiate(explosionPrefab, transform.position, Quaternion.identity);
        }
        if (explosionSound != null)
        {
            AudioSource.PlayClipAtPoint(explosionSound, Camera.main.transform.position);
        }

        CameraShake.instance.Shake(0.3f, 0.3f);   // 第19回 // ★追加

        // パワーアップを元に戻す(第15回)
        PowerUpManager powerUp = GetComponent<PowerUpManager>();
        if (powerUp != null)
        {
            powerUp.ResetAll();
        }

        GameManager.instance.LoseLife();

        if (GameManager.instance.lives > 0)
        {
            StartCoroutine(Respawn());
        }
        else
        {
            gameObject.SetActive(false);
        }
    }

    // 少しのあいだ点滅しながら無敵になる
    IEnumerator Respawn()
    {
        isInvincible = true;
        transform.position = new Vector3(-6f, 0f, 0f);

        float time = 0f;
        while (time < invincibleTime)
        {
            model.SetActive(!model.activeSelf);
            yield return new WaitForSeconds(0.1f);
            time += 0.1f;
        }

        model.SetActive(true);
        isInvincible = false;
    }
}

保存します。Shake(0.3f, 0.3f) は「0.3秒間、0.3の強さでゆらす」という意味です。

1-4. ボスを倒したときにも大きくゆらす ​

Assets/_Game/Scripts/Enemy.cs を開き、次のように書きかえます。

csharp
using UnityEngine;

// 敵の基本(移動・HP・やられたとき)
public class Enemy : MonoBehaviour
{
    public float speed = 3f;              // 左へ進む速さ
    public int hp = 1;                    // 体力(第8回)
    public GameObject explosionPrefab;    // 爆発(第9回)
    public AudioClip explosionSound;      // 爆発音(第9回)
    public int score = 100;               // 倒したときの点数(第10回)
    public GameObject capsulePrefab;      // 落とすカプセル(第14回)
    public bool isBoss = false;           // ボスかどうか(第17回)

    [HideInInspector] public int maxHp;   // 最初の体力(第17回)

    bool isDead = false;

    void Awake()
    {
        maxHp = hp;
    }

    void Update()
    {
        transform.Translate(Vector3.left * speed * Time.deltaTime, Space.World);

        // 画面の左に出たら消す
        if (transform.position.x < -12f)
        {
            Destroy(gameObject);
        }
    }

    // ダメージを受ける(第8回)
    public void TakeDamage(int damage)
    {
        if (isDead) return;

        hp -= damage;
        if (hp <= 0)
        {
            Die();
        }
    }

    void Die()
    {
        isDead = true;

        GameManager.instance.AddScore(score);

        if (explosionPrefab != null)
        {
            Instantiate(explosionPrefab, transform.position, Quaternion.identity);
        }
        if (explosionSound != null)
        {
            AudioSource.PlayClipAtPoint(explosionSound, Camera.main.transform.position);
        }
        if (capsulePrefab != null)
        {
            Instantiate(capsulePrefab, transform.position, Quaternion.identity);
        }
        if (isBoss)
        {
            CameraShake.instance.Shake(1f, 0.4f);   // ★追加
            GameManager.instance.StageClear();
        }

        Destroy(gameObject);
    }
}

保存します。ボスのときは「1秒間、0.4の強さ」で、自機のときより長く強くゆらします。

1-5. 動作確認 ​

  1. シーンを保存します(Ctrl+S、Macは Cmd+S)。
  2. ▶ を押します。
  3. わざと敵に当たって、画面が短くゆれればOKです。
  4. ゆれが終わったあと、カメラが元の位置にもどっていればOKです(画面がずれたままになっていないか見ます)。
  5. ▶ を押して止めます。

2. Bloom で光らせる ​

2-1. Bloom とは ​

Bloom(ブルーム)は、とても明るいところの光を、まわりにふわっとにじませる効果です。 画面ぜんたいにかける効果のことを ポストプロセス(Post-processing)といいます。 URP では、Volume(ボリューム)というしくみでポストプロセスを設定します。

2-2. Global Volume に Bloom を足す ​

  1. Hierarchy で Global Volume を選びます(Universal 3D テンプレートのシーンに最初から入っています)。
  2. Inspector の Volume コンポーネントの Profile に、プロファイル(設定のファイル)が入っていることを確認します。
  3. その下に並んでいる項目(オーバーライド)の中に Bloom があるか見ます。
  4. Bloom がないときは、一番下の Add Override を押し、Post-processing > Bloom を選びます。
  5. Bloom の左の三角を開きます。
  6. Threshold の左のチェックボックスを ON にし、値を 0.9 くらいにします。
  7. Intensity の左のチェックボックスを ON にし、値を 1〜3 くらいにします。

Global Volume がないとき

Hierarchy に Global Volume がないときは、GameObject > Volume > Global Volume で作ります。Profile の右の New を押すと、新しいプロファイルができます。

項目の左のチェックボックス

Volume の各項目は、左のチェックボックスを ON にしたものだけが使われます。値を変えても何も起きないときは、チェックが入っているか確認しましょう。

項目意味
Thresholdこの明るさより明るいところだけが光ります。小さくすると、いろいろなものが光ります
Intensity光のにじみの強さです

2-3. カメラの Post Processing を ON にする ​

  1. Hierarchy で Main Camera を選びます。
  2. Inspector の Camera コンポーネントの Rendering を開きます。
  3. Post Processing にチェックを入れます。

ここを忘れると光らない

Volume を設定しても、カメラの Post Processing が OFF だと、ポストプロセスはまったく表示されません。

2-4. マテリアルの Emission を強くする ​

Bloom は「とても明るいところ」だけを光らせます。弾やオプションをもっと明るくしましょう。

  1. Project ウィンドウで Assets/_Game/Materials を開きます。
  2. 自機の弾に使っているマテリアル(第5回で作ったもの)を選びます。
  3. Inspector の Emission にチェックが入っていることを確認します(入っていなければ入れます)。
  4. Emission Map の右の色の四角をクリックします。
  5. 色を選ぶ画面の Intensity を 2〜4 くらいに上げます。
  6. 同じようにして、レーザー、ミサイル、オプションのマテリアルも Emission を強くします。
  7. File > Save Project で保存します。

光らせすぎに注意

なんでも光らせると、どれが敵の弾かわかりにくくなります。「自分の弾は水色や黄色」「敵の弾は赤」など、見分けやすい色にしましょう。

2-5. 動作確認 ​

  1. ▶ を押します。
  2. 弾やオプションのまわりがぼんやり光っていればOKです。
  3. 光が弱いときは Intensity(Bloom または Emission)を上げます。画面ぜんたいが白っぽいときは Threshold を上げます。
  4. ▶ を押して止めます。

3. ハイスコアを保存する ​

3-1. PlayerPrefs とは ​

今のゲームは、終わるとスコアが消えてしまいます。 PlayerPrefs(プレイヤー・プレフス)を使うと、パソコンやブラウザの中に小さなデータを保存できます。ゲームを閉じても消えません。

書き方意味
PlayerPrefs.SetInt("HighScore", 100);「HighScore」という名前で 100 を保存します
PlayerPrefs.GetInt("HighScore", 0)「HighScore」の値を読みます。まだ保存されていなければ 0 になります
PlayerPrefs.Save();保存をすぐに書きこみます

名前("HighScore")は「ロッカーの名札」のようなものです。書くときと読むときで、一字一句同じにします。

3-2. HighScoreText を作る ​

  1. Hierarchy で Canvas の中の ScoreText を選びます。
  2. Ctrl+D(Macは Cmd+D)で複製し、名前を HighScoreText にします。
  3. Anchor Presets で top-center(上・真ん中)を選びます。
  4. Pos X を 0、Pos Y を -40 くらいにします(BossHPBar と重ならないよう、必要なら調整します)。
  5. 文字の欄を HI 000000 にします。
  6. Alignment を中央ぞろえにします。

3-3. GameManager を完成させる ​

Assets/_Game/Scripts/GameManager.cs を開き、次のように書きかえます。

csharp
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;

// スコア・残機・ゲームの状態を管理する
public class GameManager : MonoBehaviour
{
    public static GameManager instance;   // どこからでも使えるようにする

    public int score = 0;
    public TextMeshProUGUI scoreText;

    public int lives = 3;                 // 残機(第11回)
    public TextMeshProUGUI livesText;
    public GameObject gameOverPanel;
    public bool isPlaying = true;         // ゲーム中かどうか

    public GameObject clearPanel;         // クリア画面(第18回)

    public TextMeshProUGUI highScoreText; // ハイスコア(第19回) // ★追加

    void Awake()
    {
        instance = this;
    }

    void Start()
    {
        UpdateUI();
    }

    public void AddScore(int amount)
    {
        score += amount;
        UpdateUI();
    }

    public void LoseLife()
    {
        lives--;
        UpdateUI();

        if (lives <= 0)
        {
            GameOver();
        }
    }

    void GameOver()
    {
        isPlaying = false;
        SaveHighScore();                  // ★追加
        gameOverPanel.SetActive(true);
    }

    public void StageClear()
    {
        isPlaying = false;
        SaveHighScore();                  // ★追加
        clearPanel.SetActive(true);
    }

    // ハイスコアを保存する(第19回)
    void SaveHighScore()                                  // ★追加
    {                                                     // ★追加
        int best = PlayerPrefs.GetInt("HighScore", 0);    // ★追加
        if (score > best)                                 // ★追加
        {                                                 // ★追加
            PlayerPrefs.SetInt("HighScore", score);       // ★追加
            PlayerPrefs.Save();                           // ★追加
        }                                                 // ★追加
        UpdateUI();                                       // ★追加
    }                                                     // ★追加

    void UpdateUI()
    {
        scoreText.text = "SCORE " + score.ToString("D6");
        livesText.text = "LIFE " + lives;

        if (highScoreText != null)                                                              // ★追加
        {                                                                                       // ★追加
            highScoreText.text = "HI " + PlayerPrefs.GetInt("HighScore", 0).ToString("D6");    // ★追加
        }                                                                                       // ★追加
    }

    // ボタンから呼ぶ
    public void Retry()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }

    public void BackToTitle()
    {
        SceneManager.LoadScene("Title");
    }
}

保存します。

コードの解説

行意味
int best = PlayerPrefs.GetInt("HighScore", 0);今までのハイスコアを読みます
if (score > best)今回のスコアのほうが大きいときだけ…
PlayerPrefs.SetInt("HighScore", score);新しいハイスコアとして保存します
SaveHighScore();(GameOver と StageClear の中)ゲームが終わったとき(やられたときも、クリアしたときも)に保存します
if (highScoreText != null)HighScoreText がつながっていないときにエラーにならないようにします

3-4. HighScoreText をつなぐ ​

  1. Hierarchy で GameManager を選びます。
  2. High Score Text に、Hierarchy の HighScoreText をドラッグします。
  3. シーンを保存します(Ctrl+S、Macは Cmd+S)。

3-5. タイトル画面にもハイスコアを出す ​

  1. Project ウィンドウで Assets/_Game/Scenes/Title をダブルクリックして、Title シーンを開きます。
  2. Hierarchy の Canvas を右クリックし、UI > Text - TextMeshPro を選びます。
  3. 名前を HighScoreText にします。
  4. START ボタンの上など、見やすい場所に置きます。Width を 600 くらいにして、中央ぞろえにします。
  5. 文字の欄を HI-SCORE 000000 にします。
  6. Assets/_Game/Scripts/TitleMenu.cs を開き、次のように書きかえます。
csharp
using TMPro;                                // ★追加
using UnityEngine;
using UnityEngine.SceneManagement;

// タイトル画面のボタン
public class TitleMenu : MonoBehaviour
{
    public TextMeshProUGUI highScoreText;   // 第19回 // ★追加

    void Start()                                                                                    // ★追加
    {                                                                                               // ★追加
        if (highScoreText != null)                                                                  // ★追加
        {                                                                                           // ★追加
            highScoreText.text = "HI-SCORE " + PlayerPrefs.GetInt("HighScore", 0).ToString("D6");   // ★追加
        }                                                                                           // ★追加
    }                                                                                               // ★追加

    public void StartGame()
    {
        SceneManager.LoadScene("Game");
    }

    public void QuitGame()
    {
        Application.Quit();
    }
}
  1. 保存します。
  2. Hierarchy で TitleMenu スクリプトが付いているオブジェクト(TitleMenu)を選びます。
  3. High Score Text に、いま作った HighScoreText をドラッグします。
  4. シーンを保存します(Ctrl+S、Macは Cmd+S)。

3-6. 動作確認 ​

  1. Title シーンで ▶ を押します。HI-SCORE 000000 と出ればOKです。
  2. START を押して遊び、ゲームオーバーまたはクリアまで進めます。
  3. TITLE ボタンでタイトルにもどり、HI-SCORE が今回のスコアになっていればOKです。
  4. ▶ を止めて、もう一度 ▶ を押しても、ハイスコアが残っていればOKです。

ハイスコアを0にもどしたいとき

Edit > Clear All PlayerPrefs で、保存したデータを消せます。

4. Web(WebGL)でビルドする ​

4-1. ビルドとは ​

ビルドとは、Unity がなくても遊べる形にゲームを書き出すことです。 今回は Web(WebGL)用にビルドします。Web 用にすると、Chrome や Edge などのブラウザで遊べます。

4-2. Web Build Support を入れる ​

第0回で Web Build Support を入れた人は、4-3 へ進みます。

  1. Unity を閉じます(保存を忘れずに)。
  2. Unity Hub を開き、左の Installs を選びます。
  3. 使っている Unity 6(6000.0)の右にある歯車のアイコンを押し、Add modules を選びます。
  4. Web Build Support にチェックを入れて、Install を押します。
  5. インストールが終わったら、Unity Hub からプロジェクトを開き直します。

先生へ

モジュールのダウンロードは大きいので、学校のネットワークでは時間がかかります。授業の前に、全員の PC に入れておくのがおすすめです。

4-3. プラットフォームを Web に切り替える ​

  1. File > Build Profiles を選びます。
  2. 左の Platforms の一覧から Web を選びます。
  3. 上の Scene List に Title(0番)と Game(1番)がチェックされて入っていることを確認します(第12回で登録しました)。
  4. 右下の Switch Platform を押します。切り替えには数分かかることがあります。

Switch Platform のかわりに Install と出たら

Web Build Support が入っていません。4-2 の手順で入れてください。

4-4. Player Settings を確認する ​

  1. Build Profiles ウィンドウの Player Settings ボタンを押します(Edit > Project Settings > Player でも開けます)。
  2. Product Name に、ゲームの名前(例: SpaceShooter)を入れます。
  3. Company Name は、MyGames など、本名ではない名前にします。

個人情報をゲームに入れない

Product Name、Company Name、タイトル画面の文字などに、本名・学校名・住所 などを入れてはいけません。公開すると、だれでも見られるようになります。ニックネームを使いましょう。

4-5. Compression Format の注意 ​

Web 用のビルドは、ファイルを小さくするために 圧縮(ぎゅっと小さくすること)されます。 圧縮のやり方によっては、置く場所の設定が合わず、ゲームが始まらないことがあります。

  1. Player Settings の中で、Web 用のタブが選ばれていることを確認します。
  2. Publishing Settings を開きます。
  3. Compression Format を確認します(Gzip、Brotli、Disabled から選べます)。
  4. 最初はそのまま(Gzip など)でかまいません。うまく動かないときは、Decompression Fallback を ON にするか、Compression Format を Disabled にしてビルドし直します。

index.html をダブルクリックしても動かない

ビルドしたフォルダの index.html をダブルクリックして開くと、ほとんどの場合ゲームは始まりません。ブラウザの安全のしくみで、ファイルを直接読めないためです。 自分のパソコンで試すときは、次の Build And Run を使いましょう。

4-6. ビルドする ​

  1. エクスプローラー(Mac は Finder)で、プロジェクトのフォルダ(Assets があるところ)に Build_Web という新しいフォルダを作ります。
  2. Unity の Build Profiles ウィンドウにもどり、Build And Run を押します。
  3. 保存先を聞かれたら、Build_Web フォルダを選びます。
  4. ビルドが終わるまで待ちます(初めては10分以上かかることもあります)。
  5. ブラウザが開き、タイトル画面が出ればOKです。
  6. START を押して、ブラウザで遊べることを確認します。

QUIT ボタンについて

Web 版では Application.Quit() は何もしません。ブラウザのタブを閉じて終わります。気になる人は、Web 版では QUIT ボタンをかくしてもかまいません。

ブラウザだと見た目が少しちがう

Web 版は、エディタとくらべて光り方や速さが少しちがうことがあります。Bloom が強すぎる・弱すぎるときは、2章の値を調整してビルドし直しましょう。

5. Unity Play で公開する ​

5-1. 公開する前の約束 ​

Unity Play(https://play.unity.com)は、Unity で作った Web ゲームを公開できるサイトです。公開すると、URL を知っている人や、サイトを見た人が遊べるようになります。

公開する前に必ず確認すること

  • 公開する前に、必ず先生・保護者に確認 してもらいましょう。ひとりで公開してはいけません
  • ゲームの中(タイトル、説明文、画像、Product Name など)に、本名・学校名などの個人情報を入れない でください
  • ほかの人が作った素材は、ライセンス(使ってよい決まり)を守っているか確認します。この教材の Kenney の素材は CC0 なので自由に使えます。自分で追加した素材は、作った人の決まりを確認しましょう

5-2. ビルドを zip にまとめる ​

  1. エクスプローラー(Mac は Finder)で Build_Web フォルダを開きます。
  2. 中に index.html、Build フォルダ、TemplateData フォルダがあることを確認します。
  3. Build_Web フォルダを右クリックし、zip に圧縮します(Windows は 圧縮先 > ZIP ファイル、Mac は "Build_Web"を圧縮)。
  4. Build_Web.zip ができればOKです。

5-3. アップロードする ​

ここから先は、先生・保護者と一緒に進めましょう。サイトの画面やボタンの名前は、ときどき変わることがあります。

  1. ブラウザで https://play.unity.com を開きます。
  2. 右上からサインインします(第0回で保護者と作った Unity アカウントを使います)。
  3. ゲームをアップロードするボタン(Upload など)を押します。
  4. 5-2 で作った Build_Web.zip を選びます。
  5. ゲームのタイトルと説明を入れます。ここにも個人情報は書きません。
  6. サムネイル(ゲームの紹介画像)を設定します。ゲーム画面のスクリーンショットを使うとよいでしょう。
  7. 内容を先生・保護者と確認してから、公開します。
  8. 公開されたページを開き、ブラウザでちゃんと遊べるか確認します。

動かないとき

「読みこみが終わらない」「エラーが出る」ときは、4-5 の Compression Format を Disabled(または Decompression Fallback を ON)にしてビルドし直し、もう一度 zip にしてアップロードしてみましょう。

先生へ

Unity Play の利用には Unity アカウントが必要で、利用規約に年齢の条件があります。生徒のアカウントで公開しない場合は、先生のアカウントでまとめて公開する、校内の PC だけで Build And Run して見せ合う、などの方法もあります。公開範囲と方法は、学校の方針に合わせて決めてください。

6. ふりかえりと、次にやってみよう ​

6-1. 全20回のふりかえり ​

おつかれさまでした! 第0回から第19回までで、こんなことができるようになりました。

回作ったもの学んだこと
0〜2準備・宇宙の舞台・自機Unity の画面、カメラ、親子のオブジェクト、マテリアル
3〜4自機を動かすスクリプト、変数、Input System、Mathf.Clamp
5〜6弾・星空プレハブ、Instantiate、Particle System
7〜9敵・当たり判定・爆発と音コルーチン、Collider と Rigidbody、AudioSource
10〜12スコア・残機・タイトルUI、static、シーンの切り替え
13いろいろな敵Prefab Variant、Mathf.Sin、Atan2
14〜16パワーアップ・オプション配列、switch、enum、Queue、List
17〜18ボス・ステージの流れ状態の切り替え、ScriptableObject
19仕上げと公開カメラのゆれ、Bloom、PlayerPrefs、ビルド

一つ一つは小さなしくみでも、組み合わせると「ゲーム」になります。これがゲーム作りのおもしろいところです。

6-2. 次にやってみよう ​

ここからは、自分のアイデアでゲームを育てていきましょう。

  • 2面目を作る: Stage2 の StageData を作り、ボスを倒したら Game シーンをもう一度読みこむ(または Stage2 用のシーンを作る)
  • ボスの攻撃パターンを増やす: AttackLoop にパターンを足したり、体力が減ったら攻撃が激しくなるようにしたりする
  • 地形を作る: 上下に岩のかべを置いて左へ流し、当たるとやられるようにする(タグ Enemy を使うと、今の PlayerLife のままでやられます)
  • 新しい敵: 自機を追いかける敵、上下から出てくる敵、かたい敵(hp が多い)など
  • スマホ対応: 画面に仮想のスティックやボタンを置く(Input System の On-Screen Stick などを調べてみましょう)
  • 音と演出: ボス戦だけ BGM を変える、パワーアップしたときに音を鳴らす

こまったときは

付録の「スクリプト完成版一覧」で、自分のコードと見比べましょう。全部のスクリプトの最終形がのっています。

チャレンジ課題 ​

  • ハイスコアを更新したときだけ「NEW RECORD!」の文字を出してみましょう(ヒント:SaveHighScore の if (score > best) の中で文字を表示します)
  • ボスがダメージを受けたときに、少しだけカメラをゆらしてみましょう(ヒント:Enemy の TakeDamage で isBoss のときだけ Shake を呼びます)
  • Bloom の Tint で光の色を変えたり、Vignette(画面のふちを暗くする効果)を足したりしてみましょう
  • 友だちのゲームを遊んで、よかったところを伝え合いましょう

つまずきポイント ​

こんなときはここを確認
やられたときに NullReferenceException が出るMain Camera に Camera Shake を付けたか
ゆれたあと画面がずれたままShakeRoutine の最後の transform.localPosition = startPos; があるか
Bloom で光らないカメラの Post Processing が ON か。Bloom の項目のチェックが ON か。マテリアルの Emission の Intensity が十分か
ハイスコアが保存されない"HighScore" のつづりが、書くところと読むところで同じか。High Score Text をつないだか
Switch Platform が押せない/Install と出るUnity Hub で Web Build Support を入れたか
ブラウザでゲームが始まらないindex.html をダブルクリックしていないか(Build And Run を使う)。Compression Format を見直す

まとめ ​

  • static な instance を使って、どこからでもカメラをゆらせるようにしました
  • Global Volume の Bloom と、マテリアルの Emission で、弾やオプションを光らせました
  • PlayerPrefs で、ゲームを閉じても消えないハイスコアを作りました
  • Web 用にビルドし、先生・保護者に確認してもらったうえで公開する方法を学びました。ゲームの完成、おめでとうございます!