ダークモード
第19回 仕上げと公開
この回でつくるもの:やられたときやボスを倒したときに画面がゆれ、弾がキラキラ光り、ハイスコアが保存されるようにします。最後に、ゲームを Web ブラウザで遊べる形にして、公開する方法を学びます。
この回で学ぶこと
staticな変数で、どこからでもカメラをゆらす(第10回の復習)- Bloom(明るいところをにじませて光らせる効果)を使う
- PlayerPrefs で、ゲームを終わってもハイスコアを残す
- File > Build Profiles で Web(WebGL)用にビルドする
- Unity Play でゲームを公開する方法と、公開するときの約束
前回までのふりかえり
第18回では、ScriptableObject の「出現表」どおりに敵が出るようにしました。 60秒たつと WARNING!! が出てボスが登場し、倒すと STAGE CLEAR の画面が出ます。 これでゲームの流れは完成です。今回は見た目と手ざわりを仕上げて、みんなに遊んでもらえる形にします。
1. カメラをゆらす
1-1. CameraShake スクリプトを作る
やられたときやボスを倒したときに画面がゆれると、ぐっと迫力が出ます。
- Project ウィンドウで
Assets/_Game/Scriptsを開きます。 - 右クリックし、Create > Scripting > MonoBehaviour Script を選びます。
- 名前を
CameraShakeにします。 - ダブルクリックして開き、中身を全部消して、次のコードを書きます。
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 に付ける
- Hierarchy で
Main Cameraを選びます。 - 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. 動作確認
- シーンを保存します(Ctrl+S、Macは Cmd+S)。
- ▶ を押します。
- わざと敵に当たって、画面が短くゆれればOKです。
- ゆれが終わったあと、カメラが元の位置にもどっていればOKです(画面がずれたままになっていないか見ます)。
- ▶ を押して止めます。
2. Bloom で光らせる
2-1. Bloom とは
Bloom(ブルーム)は、とても明るいところの光を、まわりにふわっとにじませる効果です。 画面ぜんたいにかける効果のことを ポストプロセス(Post-processing)といいます。 URP では、Volume(ボリューム)というしくみでポストプロセスを設定します。
2-2. Global Volume に Bloom を足す
- Hierarchy で
Global Volumeを選びます(Universal 3D テンプレートのシーンに最初から入っています)。 - Inspector の Volume コンポーネントの Profile に、プロファイル(設定のファイル)が入っていることを確認します。
- その下に並んでいる項目(オーバーライド)の中に Bloom があるか見ます。
- Bloom がないときは、一番下の Add Override を押し、Post-processing > Bloom を選びます。
- Bloom の左の三角を開きます。
- Threshold の左のチェックボックスを ON にし、値を
0.9くらいにします。 - Intensity の左のチェックボックスを ON にし、値を
1〜3くらいにします。
Global Volume がないとき
Hierarchy に Global Volume がないときは、GameObject > Volume > Global Volume で作ります。Profile の右の New を押すと、新しいプロファイルができます。
項目の左のチェックボックス
Volume の各項目は、左のチェックボックスを ON にしたものだけが使われます。値を変えても何も起きないときは、チェックが入っているか確認しましょう。
| 項目 | 意味 |
|---|---|
| Threshold | この明るさより明るいところだけが光ります。小さくすると、いろいろなものが光ります |
| Intensity | 光のにじみの強さです |
2-3. カメラの Post Processing を ON にする
- Hierarchy で
Main Cameraを選びます。 - Inspector の Camera コンポーネントの Rendering を開きます。
- Post Processing にチェックを入れます。
ここを忘れると光らない
Volume を設定しても、カメラの Post Processing が OFF だと、ポストプロセスはまったく表示されません。
2-4. マテリアルの Emission を強くする
Bloom は「とても明るいところ」だけを光らせます。弾やオプションをもっと明るくしましょう。
- Project ウィンドウで
Assets/_Game/Materialsを開きます。 - 自機の弾に使っているマテリアル(第5回で作ったもの)を選びます。
- Inspector の Emission にチェックが入っていることを確認します(入っていなければ入れます)。
- Emission Map の右の色の四角をクリックします。
- 色を選ぶ画面の Intensity を
2〜4くらいに上げます。 - 同じようにして、レーザー、ミサイル、オプションのマテリアルも Emission を強くします。
- File > Save Project で保存します。
光らせすぎに注意
なんでも光らせると、どれが敵の弾かわかりにくくなります。「自分の弾は水色や黄色」「敵の弾は赤」など、見分けやすい色にしましょう。
2-5. 動作確認
- ▶ を押します。
- 弾やオプションのまわりがぼんやり光っていればOKです。
- 光が弱いときは Intensity(Bloom または Emission)を上げます。画面ぜんたいが白っぽいときは Threshold を上げます。
- ▶ を押して止めます。
3. ハイスコアを保存する
3-1. PlayerPrefs とは
今のゲームは、終わるとスコアが消えてしまいます。 PlayerPrefs(プレイヤー・プレフス)を使うと、パソコンやブラウザの中に小さなデータを保存できます。ゲームを閉じても消えません。
| 書き方 | 意味 |
|---|---|
PlayerPrefs.SetInt("HighScore", 100); | 「HighScore」という名前で 100 を保存します |
PlayerPrefs.GetInt("HighScore", 0) | 「HighScore」の値を読みます。まだ保存されていなければ 0 になります |
PlayerPrefs.Save(); | 保存をすぐに書きこみます |
名前("HighScore")は「ロッカーの名札」のようなものです。書くときと読むときで、一字一句同じにします。
3-2. HighScoreText を作る
- Hierarchy で
Canvasの中のScoreTextを選びます。 - Ctrl+D(Macは Cmd+D)で複製し、名前を
HighScoreTextにします。 - Anchor Presets で top-center(上・真ん中)を選びます。
- Pos X を 0、Pos Y を -40 くらいにします(
BossHPBarと重ならないよう、必要なら調整します)。 - 文字の欄を
HI 000000にします。 - 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 をつなぐ
- Hierarchy で
GameManagerを選びます。 - High Score Text に、Hierarchy の
HighScoreTextをドラッグします。 - シーンを保存します(Ctrl+S、Macは Cmd+S)。
3-5. タイトル画面にもハイスコアを出す
- Project ウィンドウで
Assets/_Game/Scenes/Titleをダブルクリックして、Title シーンを開きます。 - Hierarchy の
Canvasを右クリックし、UI > Text - TextMeshPro を選びます。 - 名前を
HighScoreTextにします。 - START ボタンの上など、見やすい場所に置きます。Width を 600 くらいにして、中央ぞろえにします。
- 文字の欄を
HI-SCORE 000000にします。 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();
}
}- 保存します。
- Hierarchy で
TitleMenuスクリプトが付いているオブジェクト(TitleMenu)を選びます。 - High Score Text に、いま作った
HighScoreTextをドラッグします。 - シーンを保存します(Ctrl+S、Macは Cmd+S)。
3-6. 動作確認
- Title シーンで ▶ を押します。HI-SCORE 000000 と出ればOKです。
- START を押して遊び、ゲームオーバーまたはクリアまで進めます。
- TITLE ボタンでタイトルにもどり、HI-SCORE が今回のスコアになっていればOKです。
- ▶ を止めて、もう一度 ▶ を押しても、ハイスコアが残っていれば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 へ進みます。
- Unity を閉じます(保存を忘れずに)。
- Unity Hub を開き、左の Installs を選びます。
- 使っている Unity 6(6000.0)の右にある歯車のアイコンを押し、Add modules を選びます。
- Web Build Support にチェックを入れて、Install を押します。
- インストールが終わったら、Unity Hub からプロジェクトを開き直します。
先生へ
モジュールのダウンロードは大きいので、学校のネットワークでは時間がかかります。授業の前に、全員の PC に入れておくのがおすすめです。
4-3. プラットフォームを Web に切り替える
- File > Build Profiles を選びます。
- 左の Platforms の一覧から Web を選びます。
- 上の Scene List に
Title(0番)とGame(1番)がチェックされて入っていることを確認します(第12回で登録しました)。 - 右下の Switch Platform を押します。切り替えには数分かかることがあります。
Switch Platform のかわりに Install と出たら
Web Build Support が入っていません。4-2 の手順で入れてください。
4-4. Player Settings を確認する
- Build Profiles ウィンドウの Player Settings ボタンを押します(Edit > Project Settings > Player でも開けます)。
- Product Name に、ゲームの名前(例:
SpaceShooter)を入れます。 - Company Name は、
MyGamesなど、本名ではない名前にします。
個人情報をゲームに入れない
Product Name、Company Name、タイトル画面の文字などに、本名・学校名・住所 などを入れてはいけません。公開すると、だれでも見られるようになります。ニックネームを使いましょう。
4-5. Compression Format の注意
Web 用のビルドは、ファイルを小さくするために 圧縮(ぎゅっと小さくすること)されます。 圧縮のやり方によっては、置く場所の設定が合わず、ゲームが始まらないことがあります。
- Player Settings の中で、Web 用のタブが選ばれていることを確認します。
- Publishing Settings を開きます。
- Compression Format を確認します(Gzip、Brotli、Disabled から選べます)。
- 最初はそのまま(Gzip など)でかまいません。うまく動かないときは、Decompression Fallback を ON にするか、Compression Format を Disabled にしてビルドし直します。
index.html をダブルクリックしても動かない
ビルドしたフォルダの index.html をダブルクリックして開くと、ほとんどの場合ゲームは始まりません。ブラウザの安全のしくみで、ファイルを直接読めないためです。 自分のパソコンで試すときは、次の Build And Run を使いましょう。
4-6. ビルドする
- エクスプローラー(Mac は Finder)で、プロジェクトのフォルダ(
Assetsがあるところ)にBuild_Webという新しいフォルダを作ります。 - Unity の Build Profiles ウィンドウにもどり、Build And Run を押します。
- 保存先を聞かれたら、
Build_Webフォルダを選びます。 - ビルドが終わるまで待ちます(初めては10分以上かかることもあります)。
- ブラウザが開き、タイトル画面が出ればOKです。
- 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 にまとめる
- エクスプローラー(Mac は Finder)で
Build_Webフォルダを開きます。 - 中に
index.html、Buildフォルダ、TemplateDataフォルダがあることを確認します。 Build_Webフォルダを右クリックし、zip に圧縮します(Windows は 圧縮先 > ZIP ファイル、Mac は "Build_Web"を圧縮)。Build_Web.zipができればOKです。
5-3. アップロードする
ここから先は、先生・保護者と一緒に進めましょう。サイトの画面やボタンの名前は、ときどき変わることがあります。
- ブラウザで https://play.unity.com を開きます。
- 右上からサインインします(第0回で保護者と作った Unity アカウントを使います)。
- ゲームをアップロードするボタン(Upload など)を押します。
- 5-2 で作った
Build_Web.zipを選びます。 - ゲームのタイトルと説明を入れます。ここにも個人情報は書きません。
- サムネイル(ゲームの紹介画像)を設定します。ゲーム画面のスクリーンショットを使うとよいでしょう。
- 内容を先生・保護者と確認してから、公開します。
- 公開されたページを開き、ブラウザでちゃんと遊べるか確認します。
動かないとき
「読みこみが終わらない」「エラーが出る」ときは、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 用にビルドし、先生・保護者に確認してもらったうえで公開する方法を学びました。ゲームの完成、おめでとうございます!