
前回は、生け垣の迷路を作って、スライムちゃんが向きを変えながら歩けるようにしました。でも、今のステージは扉に入るだけでクリアなので、迷路を抜ければすぐに終わってしまいます・・・。今回は、いよいよ星を置きます。星を3つ全部集めないと扉が開かないようにして、取ったときにはキラキラと「+1」が出る演出も付けますよ!
- シリーズの目次:絶対に完成させるゲーム制作
- 前回:#3 壁を置いて、歩くすがたを付けよう
今回作るもの

ゲームの流れは、今回も同じです。ステージの中に、「星を集める」という目的を足します。
- ステージに星を3つ置く。星は、その場でふわふわ浮いている
- 画面の左上に、残りの星の数を出す
- 星を取ると、キラキラと「+1」が出る
- 扉は最初は閉じていて、星を全部集めると開く。開いた扉に入るとエンディング
作るスクリプトは3つ、前回までのスクリプトを1つ書きかえます。
| スクリプト | 役割 | 付ける場所 |
|---|---|---|
| Star | 取ったら、キラキラと「+1」を出して消える | 星 |
| StarCounter | 残りの数を表示する。全部集めたら扉を開く | 左上の文字 |
| PopupText | 文字を浮かせながら消す | 「+1」の文字 |
| Door(#2で作ったもの) | 星を全部集めるまで開かないようにする | 扉 |
星を置こう

まずは、星を1つ作って、プレハブにします。
Sprites/ItemsのstarをHierarchyにドラッグ&ドロップして、名前をStarにする- Scaleを(0.8, 0.8, 1)にする
- Add ComponentでCircle Collider 2Dを付ける
- Is Triggerにチェック(ぶつかるのではなく、重なったら取れるように)
- Radius:0.4
- Add ComponentでFloating Motionを付ける
- Height:0.1、Speed:3
Floating Motionは、#1でタイトルの文字をふわふわさせたスクリプトです。Heightは、Canvasの文字ではピクセル(20)でしたが、ステージではマス(1マスが1)なので、0.1にします。作ったスクリプトは、数字を変えるだけで別のものにも使えます。

Starスクリプトは、あとで作って付けます(上の画像は、全部付け終わった後のものです)。
出来たら、HierarchyのStarをPrefabsフォルダにドラッグしてプレハブにし、Hierarchyのほうは消します。前回の壁と同じように、空のゲームオブジェクトStarsを作って、その子にプレハブを3つ置きます。
| 名前 | Position |
|---|---|
| Star1 | (-7, 3) |
| Star2 | (-1, -3.8) |
| Star3 | (5, -3.8) |
左の通路の上、まん中の通路の下、右の通路の下に1つずつ。迷路をぐるっと回らないと、全部は取れない置き方です。
全部集めたら扉が開くようにしよう

次は、扉を最初は閉じておいて、星を全部集めたら開くようにします。閉じた扉の絵と、開いた扉の絵を入れかえるだけで、「開いた!」が伝わります。
Doorスクリプトを書きかえよう
#2で作ったDoorスクリプトを、次のように書きかえます。
using UnityEngine;
// 扉:星を全部集めると開き、開いた扉にスライムちゃんが入ったら、次のシーンへ
public class Door : MonoBehaviour
{
[SerializeField] private string nextSceneName = "Ending"; // 入ったら行くシーンの名前
[SerializeField] private ScreenFlash screenFlash; // 画面を光らせて、シーンを切り替える
[SerializeField] private Sprite openSprite; // 開いた扉の絵
[SerializeField] private GameObject openEffectPrefab; // 開いたときのキラキラ
private bool isOpen; // 開いているか
private bool isEntered; // もう入ったか(2回入らないように)
// 扉を開く(StarCounter が、星を全部集めたときに呼ぶ)
public void Open()
{
isOpen = true;
GetComponent<SpriteRenderer>().sprite = openSprite;
Instantiate(openEffectPrefab, transform.position, Quaternion.identity);
}
private void OnTriggerStay2D(Collider2D other)
{
if (!isOpen || isEntered)
{
return;
}
PlayerMove player = other.GetComponent<PlayerMove>();
if (player == null)
{
return;
}
isEntered = true;
player.Stop();
screenFlash.FlashAndLoad(nextSceneName);
}
}
isOpenとOpen()- 最初は閉じている(
false)。Open()が呼ばれたら開いて、扉の絵をopenSprite(開いた扉)に替え、キラキラを出す
- 最初は閉じている(
OnTriggerStay2D- #2では「重なった瞬間」の
OnTriggerEnter2Dでしたが、「重なっている間ずっと」のOnTriggerStay2Dに変えました。閉じた扉の前で待っているうちに扉が開いても、ちゃんと入れるようにするためです
- #2では「重なった瞬間」の
!isOpen || isEntered- 「開いていない」か「もう入った」なら、何もしない。
||は「または」
- 「開いていない」か「もう入った」なら、何もしない。
扉のゲームオブジェクト(HierarchyのDoor)を選んで、2か所を変えます。
- Sprite RendererのSpriteをdoor_closed(閉じた扉)にする
- DoorスクリプトのOpen Spriteにdoor_openを入れる(Open Effect Prefabは、あとでキラキラを作ってから入れます)

残りの数を表示しよう
画面の左上に、星のマークと「のこり 3」を出します。
- Canvasを右クリック>UI (Canvas)>Text – TextMeshPro、名前をStarTextにする
- アンカーを左上(top-left)にして、Pivotを(0, 1)、Pos X:150、Pos Y:-40、Width:600、Height:100
- Text:「のこり 3」、Font Size:64、太字、色:#FFE08A、左寄せ・上下はまん中
- StarTextを右クリック>UI (Canvas)>Image、名前をStarIconにする
- アンカーを左のまん中にして、Pos X:-60、Pos Y:0、Width・Height:96
- Source Imageにstarを入れる
- Flashを、Canvasの子の一番下にドラッグし直す(StarTextより手前に光らせるため)
ScriptsフォルダにStarCounterを作ります。
using TMPro;
using UnityEngine;
// 残りの星の数を表示する。全部集めたら扉を開く
public class StarCounter : MonoBehaviour
{
[SerializeField] private Door door; // 全部集めたら開く扉
private TMP_Text countText;
private int remainingStars;
private void Start()
{
countText = GetComponent<TMP_Text>();
// ステージに置いてある星を数える
remainingStars = FindObjectsByType<Star>(FindObjectsSortMode.None).Length;
UpdateText();
}
// 星を1つ取ったときに呼ぶ
public void CollectStar()
{
remainingStars--;
UpdateText();
if (remainingStars == 0)
{
door.Open();
}
}
private void UpdateText()
{
if (remainingStars > 0)
{
countText.text = $"のこり {remainingStars}";
}
else
{
countText.text = "扉が ひらいた!";
}
}
}
FindObjectsByType<Star>(…).Length- シーンにあるStarを全部探して、その数を数える。星を増やしたり減らしたりしても、数を書き直さなくてよい
CollectStar()- 星が取られたら、残りを1つ減らして表示を直す。0になったら
door.Open()で扉を開く
- 星が取られたら、残りを1つ減らして表示を直す。0になったら
UpdateText()- 残りがあれば「のこり 2」、0なら「扉が ひらいた!」。数字だけでなく、何が起きたかも文字で伝えます
UIの文字をスクリプトから変える方法は、9-4 スクリプトからUIを更新しようで紹介しています。
StarCounterの中で使っているStarは、まだ作っていないので、次の節でStarを作るまではエラーになります。StarCounterをStarTextに付けて、Doorの欄に扉のゲームオブジェクト(Door)をドラッグするのは、Starを作ったあとにしましょう。

取ったらキラキラと「+1」

星を取ったときに、何も出ずに消えるだけだと、取れたのかどうか分かりにくいですよね。そこで、キラキラの粒と「+1」の文字を出して、「取った!」をはっきり見せます。
どちらも、星を取るたびに作って、終わったら消すものなので、プレハブにしておきます。
キラキラを作ろう

キラキラは、Particle System(パーティクル)で作ります。たくさんの小さな粒を、まとめて飛ばせる仕組みです。
- Hierarchyで右クリック>Effects>Particle System、名前をStarSparkleにする
- TransformのPositionとRotationを、どちらも(0, 0, 0)にする
- Particle Systemのメインの欄(StarSparkleと書かれた欄)
- Duration:0.5、Looping:チェックを外す
- Start Lifetime:0.6、Start Speed:4
- Start Size:右の▼からRandom Between Two Constantsにして、0.4と0.8
- Start Color:#FFE08A(星と同じ黄色)
- Simulation Space:World
- Stop Action:Destroy
- Emission:Rate over Timeを0にして、Burstsの+で1つ足す(Time:0、Count:20)
- Shape:ShapeをCircle、Radiusを0.1
- Size over Lifetimeにチェックを入れて、Sizeを右下がりの線(だんだん小さくなる)にする
- Texture Sheet Animationにチェックを入れて、ModeをSprites、Spriteに
Sprites/Effectsのfx_sparkleを入れる - RendererのOrder in Layer:5(スライムちゃんより手前)
出来たら、Prefabsフォルダにドラッグしてプレハブにし、Hierarchyのほうは消します。扉のゲームオブジェクト(Door)のDoorスクリプトのOpen Effect Prefabにも、このStarSparkleを入れておきましょう。扉が開くときにも、同じキラキラを使い回します。
Burstは「一度にまとめて出す」設定です。Rate over Timeを0にして、Burstで20個出すと、ポンッと一度だけはじけるキラキラになります。Stop Action:Destroyにしておくと、粒が全部消えたあとに、StarSparkleのゲームオブジェクトも自動で消えます。パーティクルのくわしい使い方は、12-4 パーティクルで演出しよう:Particle Systemの基本で紹介しています。
「+1」を作ろう

「+1」は、星のあった場所に出したいので、Canvasの文字ではなく、ステージの中に置ける文字を使います。
- Hierarchyで右クリック>3D Object>Text – TextMeshPro、名前をPlusOneにする
- Positionを(0, 0, 0)、Rect TransformのWidth:3、Height:1.5
- TextMeshPro – Text
- Text:「+1」、Font Size:10、太字、Vertex Color:#FFE08A、まん中寄せ
- Extra SettingsのOrder in Layer:10(キラキラより手前)
ScriptsフォルダにPopupTextを作ります。
using TMPro;
using UnityEngine;
// 文字を上に浮かせながら、だんだん消す
public class PopupText : MonoBehaviour
{
[SerializeField] private float riseSpeed = 1.5f; // 1秒に上がる高さ
[SerializeField] private float lifeSeconds = 0.8f; // 消えるまでの時間
private TMP_Text popupText;
private float time;
private void Start()
{
popupText = GetComponent<TMP_Text>();
}
private void Update()
{
time += Time.deltaTime;
transform.position += Vector3.up * riseSpeed * Time.deltaTime;
// 時間がたつほど、透明にしていく
Color color = popupText.color;
color.a = 1f - time / lifeSeconds;
popupText.color = color;
if (time >= lifeSeconds)
{
Destroy(gameObject);
}
}
}
transform.position += Vector3.up * …- 毎フレーム、少しずつ上に動かす
color.a = 1f - time / lifeSecondsaは透明度(1で見える、0で透明)。0.8秒かけて、1から0へだんだん透明にする
Destroy(gameObject)- 消えきったら、自分のゲームオブジェクトを消す。残しておくと、星を取るたびに見えない「+1」がたまっていく
PlusOneにPopupTextを付けたら、Prefabsフォルダにドラッグしてプレハブにし、Hierarchyのほうは消します。
Starスクリプトを作ろう
最後に、星を取ったときの処理です。ScriptsフォルダにStarを作ります。
using UnityEngine;
// 星:スライムちゃんが取ったら、キラキラと「+1」を出して消える
public class Star : MonoBehaviour
{
[SerializeField] private GameObject sparklePrefab; // 取ったときのキラキラ
[SerializeField] private GameObject popupPrefab; // 取ったときの「+1」
private void OnTriggerEnter2D(Collider2D other)
{
PlayerMove player = other.GetComponent<PlayerMove>();
if (player == null)
{
return;
}
Instantiate(sparklePrefab, transform.position, Quaternion.identity);
Instantiate(popupPrefab, transform.position + Vector3.up * 0.8f, Quaternion.identity); // 星の少し上に出す
FindAnyObjectByType<StarCounter>().CollectStar();
Destroy(gameObject);
}
}
Instantiate(プレハブ, 位置, 向き)- プレハブから、ゲームオブジェクトを新しく作る。星のあった位置にキラキラ、少し上に「+1」を作る
FindAnyObjectByType<StarCounter>()- シーンにあるStarCounterを探して、
CollectStar()を呼ぶ
- シーンにあるStarCounterを探して、
Destroy(gameObject)- 取った星を消す
付けていきます。
- PrefabsフォルダのStarのプレハブを選んで、Starスクリプトを付ける
- Sparkle PrefabにStarSparkle、Popup PrefabにPlusOneを入れる
- StarTextにStarCounterを付けて、Doorの欄に扉のゲームオブジェクト(Door)をドラッグ
プレハブに付けたので、置いてある3つの星にもまとめて付きます。再生して、星を取ってみましょう。
星に重なってもキラキラが出ず、星も消えないときは、Consoleにエラーが出ていないか見てみましょう。Sparkle PrefabやPopup Prefabが空のままだと、Instantiateでエラーになって、そこで処理が止まってしまいます。

スライムキラキラッて出ると、思わず全部取りたくなりますね!
完成チェック


Titleシーンを開いて再生し、最初から最後まで通して遊びます。
- ステージに星が3つあって、ふわふわ浮いている。左上に「のこり 3」
- 星を取ると、キラキラと「+1」が出て、「のこり」の数が1つ減る
- 星を全部集める前は、扉に重なってもエンディングに行かない
- 最後の星を取ると、扉が開いてキラキラが出て、「扉が ひらいた!」になる
- 開いた扉に入ると、白く光ってからエンディングへ。「タイトルへ」でタイトルに戻る
これで、「星を集めて、扉を開けて、帰る」という、このゲームの遊びがそろいました!
ビルドして遊ぼう


今回も、ビルドして.exeで遊びます。
- Stage1シーンを保存(Ctrl+S)してから、File>Build Profilesを開いてBuild
- 前回と同じ
Build/StarGardenのフォルダを選ぶ(上書きしてOK) - 出来たStarGarden.exeで、星を3つ集めて扉から帰れるか遊んでみる
あとがき
今回は、星を置いて、残りの数を表示し、全部集めたら扉が開くようにしました。キラキラのパーティクルと「+1」の文字で、取ったときの気持ちよさも付きました。目的があって、達成したら扉が開く。ちいさくても、ちゃんと「ゲーム」の形です。
次回は、迷路の中におばけを出します。行ったり来たりするおばけに当たると、画面が揺れてやり直し。緊張感が出てきますよ!



星を全部集めて扉が開いたとき、ちょっとうるっとしちゃいました・・・



まだ泣くのは早いよ!次はおばけが出るから、よけながら集めてね!
コメント
コメント一覧 (1件)
[…] 前回:#4 星を集めたら、扉が開く […]