Unity 6でClimbCloudを作る② ― パラパラ漫画のアニメーションと、ゴール・シーンの切り替え(PC版)
ClimbCloudの2回目です。前回は、Rigidbody2DとCollider2Dで物理を付けて、猫が雲の上を歩き、クリックでジャンプするところまで作りました。今回はゲームとして完成させます。
Unity 6でClimbCloudを作る① ― Rigidbody2Dで歩いて、クリックでジャンプする(PC版)
| 回 | 内容 |
|---|---|
| ①(前回) | Rigidbody2DとCollider2Dで物理を付ける/AddForceで右へ歩かせる/クリックでジャンプする |
| ②(今回) | 歩く・ジャンプのアニメーション/旗に着いたらゴール/クリア画面への切り替え/落ちたらやり直し |
この記事で作るもの
- 歩いているときは、2枚の画像を交互に切り替えて歩いているように見せる
- ジャンプ中は、ジャンプ用の画像に切り替える
- 旗に触れたら、クリア画面(ClearScene)に切り替わる
- 雲から落ちて画面の下に消えたら、最初からやり直し
今回も、前回の PlayerController に機能を足していきます。使う画像は、歩く姿2枚(catWalkA.png・catWalkB.png)、ジャンプの姿(catJump.png)、旗(flag.png)、クリア画面の背景(backgroundClear.png)です。
1. パラパラ漫画のアニメーション
猫が歩いているように見せるために、0.1秒ごとに2枚の画像を交互に切り替えます。パラパラ漫画と同じ仕組みです。画像の切り替えは、SpriteRenderer(画像を表示するコンポーネント)の sprite を入れ替えるだけでできます。
画像を入れておく変数を用意する
PlayerControllerに、次の変数を追加します。
public Sprite[] walkSprites; // 歩く画像(2枚)
public Sprite jumpSprite; // ジャンプの画像
float time = 0; // 画像を切り替えてからの経過時間
int idx = 0; // 今表示している歩く画像の番号(0か1)
SpriteRenderer spriteRenderer; // 猫の SpriteRenderer
Sprite[] の [] は配列(同じ種類のものを複数まとめて入れる箱)の印です。public にしたので、Inspectorから画像を設定できます。スクリプトを保存したら、猫のInspectorで次のように設定しましょう。
| Inspectorの欄 | 設定するもの |
|---|---|
| Walk Sprites のサイズ | 2 |
| Walk Sprites → Element 0 | catWalkA |
| Walk Sprites → Element 1 | catWalkB |
| Jump Sprite | catJump |
Start では、SpriteRendererを取り出しておきます。
spriteRenderer = GetComponent<SpriteRenderer>();
0.1秒ごとに画像を切り替える
Update の中に、次のコードを追加します。
// アニメーション
if (rigid2D.linearVelocityY != 0)
{
// 空中にいるときは、ジャンプの画像
spriteRenderer.sprite = jumpSprite;
}
else
{
// 着地しているときは、0.1秒ごとに歩く画像を切り替える
time += Time.deltaTime;
if (time > 0.1f)
{
time = 0;
spriteRenderer.sprite = walkSprites[idx];
idx = 1 - idx; // 0 → 1 → 0 → 1 … と交互に切り替える
}
}
0.1秒を数える仕組みは、CatEscapeで矢を1秒ごとに作ったときと同じです(Time.deltaTime をためていく)。上下に動いているとき(linearVelocityY != 0)は空中なので、ジャンプの画像を表示します。前回のジャンプの条件(== 0)のちょうど逆ですね。
Unity 6でCatEscapeを作る① ― 猫の移動と、Prefabで矢を降らせる仕組み(PC版)
idx = 1 – idx で0と1を行ったり来たり
idx = 1 - idx; は、0と1を交互に切り替える定番の書き方です。
| 今の idx | 1 – idx | 次に表示する画像 |
|---|---|---|
| 0 | 1 – 0 = 1 | walkSprites[1](catWalkB) |
| 1 | 1 – 1 = 0 | walkSprites[0](catWalkA) |
本格的なアニメーションはUnityのAnimator(アニメーションの専用機能)で作るのが一般的ですが、2枚を切り替えるくらいなら、このようにスクリプトだけでも作れます。仕組みが見えるので、まずはこの方法で「アニメーションはパラパラ漫画」という感覚をつかみましょう。

2. 旗に触れたらゴール(OnTriggerEnter2D)
次はゴールです。旗の画像をシーンに置き、Position を (9.8, -1, 0) にします。そして、旗に BoxCollider2D を追加して、Is Trigger にチェックを入れます。
Is Trigger とは
| Is Trigger | ぶつかったとき | 呼ばれるメソッド | 使う場面 |
|---|---|---|---|
| オフ | ぶつかって止まる・上に乗れる | OnCollisionEnter2D | 雲(床)、壁 |
| オン | すり抜ける。でも「触れた」ことは分かる | OnTriggerEnter2D | ゴール、アイテム、ワープ地点 |
旗は「ぶつかって止まる」必要はなく、「触れたかどうか」だけ分かればよいので、Is Triggerをオンにします。こうしておくと、猫が旗に触れた瞬間に、猫のスクリプトの OnTriggerEnter2D メソッドが自動で呼ばれます。PlayerControllerに次のメソッドを追加しましょう。
// 旗(Is Trigger のコライダー)に触れたときに呼ばれる
void OnTriggerEnter2D(Collider2D collision)
{
Debug.Log("ゴール");
}
再生して旗まで進み、Consoleに「ゴール」と表示されれば成功です。CatEscapeでは当たり判定を自分で計算しましたが、Collider2Dを使うと、Unityが当たりを調べてメソッドを呼んでくれます。
Unity 6でCatEscapeを作る② ― 当たり判定とHPゲージ、スクリプト同士の連携(PC版)
OnTriggerEnter2D が呼ばれるには、ぶつかる2つのうち少なくとも片方にRigidbody2Dが必要です。今回は猫に付いているので大丈夫です。
3. クリア画面に切り替える(シーン遷移)
ゴールしたら、クリア画面に切り替えます。Unityでは、ゲームの画面をシーンという単位で作ります。今遊んでいる画面が GameScene なので、クリア画面用に ClearScene を新しく作ります。
ClearScene を作る
- メニューの File → New Scene で新しいシーンを作り、File → Save As で
ClearSceneという名前で保存する - ClearSceneに
backgroundClear.pngを配置して保存する - ProjectウィンドウのGameSceneをダブルクリックして、ゲームのシーンに戻る
Build Profiles のシーンリストに登録する
スクリプトからシーンを切り替えるには、使うシーンをシーンリストに登録しておく必要があります。Unity 6では、メニューの File → Build Profiles を開き、Scene List にProjectウィンドウから2つのシーンをドラッグ&ドロップします。
| 番号 | シーン |
|---|---|
| 0 | GameScene(最初に表示されるシーン) |
| 1 | ClearScene |
以前のUnityでは「Build Settings」の「Scenes In Build」という名前でした。ネットの記事で古い名前を見かけたら、Build Profilesのことだと読み替えてください。
LoadScene でシーンを切り替える
PlayerControllerの先頭に using UnityEngine.SceneManagement; を追加し、OnTriggerEnter2D を次のように書き換えます。
void OnTriggerEnter2D(Collider2D collision)
{
Debug.Log("ゴール");
SceneManager.LoadScene("ClearScene"); // クリア画面に切り替える
}
SceneManager.LoadScene("シーン名") で、指定したシーンに切り替わります。旗に触れた瞬間に、クリア画面が表示されれば成功です。

4. 落ちたら最初からやり直し
雲から落ちてしまったときの処理も作ります。Update の最後に、次のコードを追加します。
// 画面の下に落ちたら、最初からやり直し
if (transform.position.y < -10)
{
SceneManager.LoadScene("GameScene");
}
自分自身のシーン(GameScene)をもう一度読み込むと、猫の位置も速さも、すべてシーンを保存したときの状態に戻ります。「やり直し」を1行で作れるのが、シーンを読み込み直す方法の便利なところです。
5. 完成したコード
using UnityEngine;
using UnityEngine.InputSystem; // Mouse を使うために必要
using UnityEngine.SceneManagement; // LoadScene を使うために必要
public class PlayerController : MonoBehaviour
{
Rigidbody2D rigid2D;
float jumpForce = 600.0f; // ジャンプの力
float walkForce = 30.0f; // 歩く力
float maxWalkSpeed = 2.0f; // 歩く速さの上限
public Sprite[] walkSprites; // 歩く画像(2枚)
public Sprite jumpSprite; // ジャンプの画像
float time = 0; // 画像を切り替えてからの経過時間
int idx = 0; // 今の歩く画像の番号
SpriteRenderer spriteRenderer;
void Start()
{
Application.targetFrameRate = 60;
rigid2D = GetComponent<Rigidbody2D>();
spriteRenderer = GetComponent<SpriteRenderer>();
}
void Update()
{
// ジャンプする(着地しているときだけ)
if (Mouse.current.leftButton.wasPressedThisFrame && rigid2D.linearVelocityY == 0)
{
rigid2D.AddForce(transform.up * jumpForce);
}
// 右へ歩く(速さの上限まで)
if (rigid2D.linearVelocityX < maxWalkSpeed)
{
rigid2D.AddForce(transform.right * walkForce);
}
// アニメーション
if (rigid2D.linearVelocityY != 0)
{
spriteRenderer.sprite = jumpSprite;
}
else
{
time += Time.deltaTime;
if (time > 0.1f)
{
time = 0;
spriteRenderer.sprite = walkSprites[idx];
idx = 1 - idx;
}
}
// 画面の下に落ちたら、最初からやり直し
if (transform.position.y < -10)
{
SceneManager.LoadScene("GameScene");
}
}
// 旗に触れたらゴール
void OnTriggerEnter2D(Collider2D collision)
{
Debug.Log("ゴール");
SceneManager.LoadScene("ClearScene");
}
}
6. よくあるつまずき
旗に触れても何も起きない
エラーが出ないのに OnTriggerEnter2D が呼ばれないときは、次の点を確認しましょう。
- 旗のBoxCollider2Dの Is Trigger にチェックが入っているか
- メソッド名が
OnTriggerEnter2Dと1文字も違わず書けているか(OnTriggerEnterは3D用で、2Dでは呼ばれない) - 引数が
Collider2Dになっているか(Collision2Dではない) - 猫にRigidbody2Dが付いているか
OnTriggerEnter2D は、Unityが名前で探して呼び出す特別なメソッドです。名前を間違えてもエラーにはならず、ただ「呼ばれない」だけなので、気づきにくいつまずきです。
クリア画面に切り替わらず、エラーが出る
Scene 'ClearScene' couldn't be loaded because it has not been added to the ...
ClearSceneがBuild ProfilesのScene Listに登録されていません。File → Build Profiles を開いて、ClearSceneを追加しましょう。シーン名のつづり(大文字・小文字)が LoadScene の文字列と一致しているかも確認します。
歩くと IndexOutOfRangeException が出る
IndexOutOfRangeException: Index was outside the bounds of the array.
Inspectorの Walk Sprites のサイズが0のままで、画像が入っていません。サイズを2にして、catWalkAとcatWalkBを設定しましょう。
SceneManager が見つからないというエラーが出る
error CS0103: The name 'SceneManager' does not exist in the current context
ファイルの先頭に using UnityEngine.SceneManagement; がありません。
7. もう一歩:クリア画面からもう一度遊ぶ
今のままだと、クリア画面に来たらそこで終わりです。ClearSceneに空のオブジェクト ClearDirector を作り、次のスクリプトを付けると、クリックでゲームに戻れるようになります。
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
public class ClearDirector : MonoBehaviour
{
void Update()
{
// クリックしたら、ゲームのシーンに戻る
if (Mouse.current.leftButton.wasPressedThisFrame)
{
SceneManager.LoadScene("GameScene");
}
}
}
このように、シーンごとに「監督」を置いてシーンの切り替えを担当させると、タイトル画面・ゲーム画面・結果画面…と、画面を増やしていくのも簡単になります。
まとめ
- SpriteRendererの
spriteを0.1秒ごとに入れ替えると、パラパラ漫画のアニメーションになる idx = 1 - idx;で0と1を交互に切り替えられる- Is Trigger をオンにしたコライダーは、すり抜けるが「触れた」ことは
OnTriggerEnter2Dで分かる - シーンを切り替えるには、Build Profiles の Scene List に登録して
SceneManager.LoadSceneを使う - 自分のシーンを読み込み直すと、「最初からやり直し」を1行で作れる
これでClimbCloudの完成です。物理エンジン、アニメーション、シーンの切り替えと、2Dゲームづくりの土台になる機能がそろいました。












ディスカッション
コメント一覧
まだ、コメントがありません