この記事は「初心者でも作れるUnity簡単2Dゲームの作り方講座」の第2回です。
前回の記事では完成イメージを確認し、Unity 2Dプロジェクトの作成、Gameビューの16:9設定、旧Input Systemの設定、素材の読み込み、背景・地面・足場の配置、Prefab化、Pixels Per Unitの調整、Hierarchyの整理まで行いました。
前回の記事:

既にプレイヤーを動かすためのステージの土台はできています。
今回の記事ではプレイヤーが操作できるキャラクターとしてPlayerオブジェクトを作成し、ゲーム画面の中で実際に動かせるようにしていきます。
具体的には、Playerの配置、左右移動、ジャンプ、地面に触れているかを判定する接地判定までを作っていきます。
Playerオブジェクトを作成しよう
まずは、ゲームの中で操作するプレイヤーを作成していきます。
Projectウィンドウから、Assets > 横スクロールアクションゲーム画像素材 を開きましょう。その中にある「プレイヤー1」の画像を、Sceneビューにドラッグ&ドロップします。

実際に配置してみると、Playerのサイズが小さすぎると思います。このままだと、前回作成した地面や足場に対してPlayerがかなり小さく見えてしまい、ゲームとして少し遊びにくくなってしまいます。
前回の地面と同じようにPixels Per Unit の値を変更し、画像の表示サイズを調整していきましょう。
「スライム」から「プレイヤー2」までの画像を、Shiftキーを押しながらまとめて選択しましょう。

今回は、Playerだけでなく、あとから使う敵キャラクターなどのサイズ感もそろえておきたいので、関連するキャラクター画像をまとめて設定しておきます。
画像をまとめて選択したら、Inspectorに表示されている Pixels Per Unit の値を変更します。

値を500に変更したら、Inspectorの右下にある Apply をクリックして設定を適用しましょう。

設定を適用すると、Sceneビューに配置したPlayerのサイズも変更されます。地面や足場と比べて、自然な大きさになっていると思います。

つぎに、Hierarchyで配置した「プレイヤー1」を選択します。

Inspectorの一番上にある名前を「プレイヤー1」から「Player」に変更しましょう。

名前を変更したら、Transformを調整して、Playerをステージの左側あたりに配置しましょう。

この時点ではPlayerが少し浮いて見えますが、その理由は次節で物理と当たり判定を付けながら確認していきます。

Playerに物理演算を付けてみよう
ここまででPlayerの見た目は配置できました。
ただし、今のPlayerは画像を置いただけの状態です。このままでは、前回作成した地面や足場と同じで、Unityの中ではただの絵として扱われています。
そこで、Playerに Rigidbody 2D を追加していきます。
Rigidbody 2Dとは?
Rigidbody 2D はオブジェクトに「物理的な要素」を与えるためのコンポーネントです。
少し簡単に言うと、Unityに対して「このオブジェクトはただの絵ではなく、大きさがあって、重さがあって重力の影響を受けるキャラクターですよ」と教えるためのものです。
Rigidbody 2D を付けると、そのオブジェクトは重力の影響を受けるようになります。つまり、何もしなければ下に落ちていきます。今回のPlayerは、これから左右に動いたり、ジャンプしたりするキャラクターです。そのため、Rigidbody 2Dを付けて、Unityの物理で動かせる状態にしておきます。
それでは、PlayerにRigidbody 2Dを追加していきましょう。
HierarchyからPlayerを選択します。

Inspectorの下の方にある Add Component をクリックし、Physics 2D > Rigidbody 2D を選択します(今回は2Dゲームなので2Dが付いている方を選択します)。

これでPlayerにRigidbody 2Dが追加されました。Rigidbody 2Dが追加されると、Playerは重力の影響を受けるようになります。
次に、Rigidbody 2Dの設定を少し変更しておきます。
InspectorのRigidbody 2Dの中にある Constraints を開き、Freeze Rotation の Z にチェックを入れましょう。

これは物理の力でPlayerが勝手に回転しないようにする設定です。
2Dアクションゲームでは、Playerが地面に着地したり、何かにぶつかったりしたときに物理の影響でコロコロ回転してしまうことがあります。

※画像は参考です。現時点では画像と同じ動きにはなりません。
今回作りたいのは丸いボールのように転がるキャラクターではなく、左右に走ってジャンプするプレイヤーです。
そのため、Z方向の回転を止めてPlayerが勝手に傾いたり回転したりしないようにしておきます。

ここまでできたら、一度再生して確認してみましょう。

再生すると、Playerが下に落ちていくと思います。Rigidbody 2Dを付けたことで、Playerが重力の影響を受けるようになったためです。
ただし、このままだと地面の上で止まらず、すり抜けて落下してしまいます。
Playerに「当たり判定」がまだないからです。
UnityでPlayerに当たり判定をつけよう
次はPlayerに当たり判定を付けていきます。
2DのUnityでは当たり判定を付けるために Collider 2D というコンポーネントを使います。Colliderは、日本語で言うと「ぶつかる範囲」のようなものです。
見た目の画像があっても、ColliderがなければUnityはどこからどこまでがキャラクターなのかわかりません。
HierarchyからPlayerを選択。

Inspectorの Add Component をクリックします。Physics 2D > Capsule Collider 2D を選択しましょう。

Capsule Collider 2Dを追加すると、Sceneビュー上のPlayerに緑色の枠が表示されます。この緑色の枠が、Playerの当たり判定です。

Playerのような人型やキャラクターには、四角い Box Collider 2D よりも、少し丸みのある Capsule Collider 2D の方が使いやすいです。
もう一度再生してみましょう。

おや。まだPlayerは地面をすり抜けてしまいます。
Playerには当たり判定を付けましたが、地面や足場の方にはまだ当たり判定が付いていないからです。
当たり判定はぶつかる両方のオブジェクトに必要です。Playerだけに当たり判定があっても、地面側に当たり判定がなければ、Unityは地面をぶつかるものとして扱うことができません。
地面と足場に当たり判定をつけよう
Playerが地面の上で止まるようにするには、地面と足場にもColliderを追加する必要があります。
Projectウィンドウから Assets > Prefabs を開きます。地面と足場のPrefabを、Shiftキーを押しながらまとめて選択します。

地面と足場のPrefabを選択した状態で、Inspectorの Add Component をクリックします。Physics 2D > Box Collider 2D を選択しましょう。

地面や足場は四角い形なので、今回は Box Collider 2D を使います。
これで、Playerと地面の両方に当たり判定が付きました。
ここまでできたら、もう一度ゲームを再生して確認してみましょう。

Playerが下に落ちた後、地面の上でしっかり止まるはずです。これでPlayerに物理と当たり判定を付けることができました。
プレイヤーを左右移動できるようにしよう
ここからはPlayerをキーボードで左右に動かせるようにしていきます。いよいよスクリプトを使ってPlayerを制御していきます。
スクリプトを作成しよう
最初にスクリプトを入れておくためのフォルダを作成します。
ProjectウィンドウのAssets内で右クリックし、Create > Folder を選択します。作成したフォルダの名前を「Scripts」に変更しましょう。

次に、作成したScriptsフォルダを開きます。Scriptsフォルダ内で右クリックし、Create > MonoBehaviour Script を選択します。作成したスクリプトの名前を「PlayerController2D」に変更しましょう。

名前を変更できたら、PlayerController2Dをダブルクリックして開きます。

スクリプトを書こう
PlayerController2Dをダブルクリックすると、コードを書く画面が開きます。
最初は、以下のような内容になっていると思います。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
using UnityEngine; public class PlayerController2D : MonoBehaviour { // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { } // Update is called once per frame void Update() { } } |
いきなり英語や記号が出てきて難しく見えるかもしれません。
ですが、今はすべてを理解しなくて大丈夫です。最初はUnityが自動で用意してくれた「スクリプトの形」だと思ってください。
最初に見る場所はこの2つだけです。
|
1 2 3 4 |
void Start() { } |
Startはゲームが始まったときに一度だけ動く場所です。
最初に準備しておきたいことはここに書きます。
もう一つは、こちらです。
|
1 2 3 4 |
void Update() { } |
Updateはゲーム中に何度もくり返し動く場所です。
キーを押しているか確認する処理などはここに書きます。今はこれだけわかれば大丈夫です。
では、このスクリプトにPlayerを左右に動かす処理を書いていきましょう。
以下の内容に書き換えてください。
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 |
using UnityEngine; public class PlayerController2D : MonoBehaviour { [Header("Move Settings")] public float moveSpeed = 5f; private Rigidbody2D playerRigidbody; private float horizontalInput; // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { //プレイヤーのRigidbody2Dを取得 playerRigidbody = GetComponent<Rigidbody2D>(); } // Update is called once per frame void Update() { // 入力、-1:左、0:なし、1:右、のように扱います horizontalInput = 0f; if (Input.GetKey(KeyCode.LeftArrow)) { horizontalInput = -1f; } else if (Input.GetKey(KeyCode.RightArrow)) { horizontalInput = 1f; } } void FixedUpdate() { // Rigidbody2Dの速度を変更して、左右に移動します。 playerRigidbody.linearVelocity = new Vector2(horizontalInput * moveSpeed, playerRigidbody.linearVelocity.y); } } |
スクリプトの解説
一気に増えたので、かなり難しく見えると思います。ですが、やっていることはとてもシンプルです。
内部では、次の順番で処理しています。
- StartでPlayerのRigidbody2Dを取得する
- Updateで左キー・右キーの入力を確認する
- 入力結果を保存する
- 保存をもとにプレイヤーの速度を変更する
変数宣言
|
1 2 |
[Header("Move Settings")] public float moveSpeed = 5f; |
moveSpeed は、プレイヤーの移動スピードを決める変数です。
public にしているので、Unity の Inspector から数値を変更できます。今回は 5f にしているため、プレイヤーはこの速さを基準に左右へ移動します(プログラムで数字の後ろにfを付けてる理由は後ほど説明します)。
[Header(“Move Settings”)] は、Inspector 上で項目を見やすくするための表示用の設定です。処理そのものには影響しません。
|
1 |
private Rigidbody2D playerRigidbody; |
playerRigidbody は、プレイヤーについている Rigidbody2D を入れておくための変数です。
プレイヤーを物理的に動かすには、Rigidbody2D の速度を変更する必要があります。その速度を決めるのがhorizontalInputです。
|
1 |
private float horizontalInput; |
先ほどの moveSpeed とは違い、private にしているので、Inspector には表示されません。
horizontalInput は左右の入力状態を保存するための変数です。この変数には次のような数値を入れます。
| -1 | 左に進む |
| 0 | 止まる |
| 1 | 右に進む |
今プレイヤーがどちらに動こうとしているのかをこの変数で管理します。
float 型と数字の後ろに付くfとは
まず、floatとは小数を入れられる変数の種類です。
たとえば、5 のような整数だけでなく、5.5 や 0.3 のような細かい数値も扱えます。
Unityでは、移動速度、ジャンプ力、位置、時間などに小数を使うことが多いので、float はよく使います。
|
1 2 |
[Header("Move Settings")] public float moveSpeed = 5f; |
数字の後ろについている f は、「この数値は float です」という意味です。C# では、0.3 や 5.5 のような小数は、何も付けないと基本的に double という別の種類の数値として扱われます。しかし、float の変数には float の数値を入れる必要があります。そのため、0.3f や 5f のように、数字の後ろに f を付けてこの数値は float と明示します。
そもそもなぜ double ではなく float を使っているの?
理由としては、Unityの物理演算や座標(Transform)の計算が、float 型を基準に作られているためです。
StartでPlayerのRigidbody2Dを取得する
この部分でPlayerの持つRigidbody2Dを探して取得しています。取得は一回行えば十分なのでStart() の中に記述しています。Updateなどに書いてしまうと何度も何度も取得処理が行われてしまいメモリの無駄遣いになります。
|
1 2 3 4 5 |
void Start() { //プレイヤーのRigidbody2Dを取得 playerRigidbody = GetComponent<Rigidbody2D>(); } |
Rigidbody2Dは前の章でPlayerに追加した「物理で動かすための部品」です。
Playerを動かすには、このRigidbody2Dに「横に進んで」と命令する必要があります。そのため、最初にPlayerのRigidbody2Dを取得しています。
Updateで左キー・右キーの入力を確認する
次に、左キーと右キーを確認しています。
|
1 2 3 4 5 6 7 8 9 10 11 |
// 入力、-1:左、0:なし、1:右、のように扱います horizontalInput = 0f; if (Input.GetKey(KeyCode.LeftArrow)) { horizontalInput = -1f; } else if (Input.GetKey(KeyCode.RightArrow)) { horizontalInput = 1f; } |
左キーを押しているときは、
|
1 |
if (Input.GetKey(KeyCode.LeftArrow)) |
horizontalInputに-1を入れます。
|
1 |
horizontalInput = -1f; |
もし左キーを押していなくて、右キーを押しているときは、
|
1 |
else if (Input.GetKey(KeyCode.RightArrow)) |
horizontalInputに1を入れます。
何も押していないときは、0のままです。
| -1 | 左に進む |
| 0 | 止まる |
| 1 | 右に進む |
つまり、この数字でPlayerの向きを決めています。
FixedUpdateでhorizontalInputを使って速度を変更する
最後に、FixedUpdate で Player を実際に動かします。
|
1 2 3 4 5 |
void FixedUpdate() { // Rigidbody2Dの速度を変更して、左右に移動します。 playerRigidbody.linearVelocity = new Vector2(horizontalInput * moveSpeed, playerRigidbody.linearVelocity.y); } |
FixedUpdate は、物理計算のタイミングで呼ばれます。
new Vector2 は X と Y を一括で扱える変数になります。
|
1 |
new Vector2(Xの座標,Yの座標) |
ここのXの座標でUpdateで保存したhorizontalInputを使います。
|
1 |
horizontalInput * moveSpeed |
この部分で、横方向の速度を作っています。
|
1 2 |
[Header("Move Settings")] public float moveSpeed = 5f; |
moveSpeed とは最初に宣言したこの部分の変数です。
horizontalInput が0なら、0 × moveSpeed なので横方向の速度は0です。
horizontalInput が1なら、1 × moveSpeed なので横方向の速度は5になります。
horizontalInput が-1なら、-1 × moveSpeed なので横方向の速度は-5になります。
つまり、このスクリプトでは、
- Updateで入力を数字に変える
- FixedUpdateでその数字を速度に変える
という流れになっています。もう一つ大事なのが、縦方向の速度です。
|
1 |
playerRigidbody.linearVelocity.y |
これは、今の縦方向の速度をそのまま使うという意味です。今回変更したいのは、左右の動きだけです。そのため、横方向の速度だけを変更して、縦方向の速度はそのまま残しています。
もし縦方向の速度まで0にしてしまうと、重力で落ちる動きや、あとで作るジャンプの動きまで消えてしまいます。
まとめると、この1行は次のような意味になります。
|
1 |
playerRigidbody.linearVelocity = new Vector2(horizontalInput * moveSpeed, playerRigidbody.linearVelocity.y); |
横の速度は、キー入力と移動速度から作る
縦の速度は、今の状態をそのまま使う
このようにして、Playerの左右移動を作っています。
FixedUpdateとは?
ここで初めて、FixedUpdateというものが出てきました。
FixedUpdateは、Unityが「物理の計算をするタイミング」で呼ばれる場所です。
物理の計算とは、重力で落ちる、地面にぶつかって止まる、Rigidbody2Dの速度で動くといった処理のことです。
Updateは、画面が更新されるたびに呼ばれます。画面の更新回数は、パソコンの性能やゲームの重さによって変わります。軽い場面ではたくさん呼ばれますし、重い場面では少なくなることがあります。

一方、FixedUpdate は決まった時間ごとに呼ばれます。Unityの初期設定では、約0.02秒ごとに呼ばれます。つまり、1秒間に約50回です。画面の更新回数に合わせるのではなく、物理計算用の決まったリズムで動いています。

今回のようにRigidbody2Dを使ってPlayerを動かすときはこのように分けて書くと、Unityの物理の仕組みに合った動きになります。
処理速度が速いパソコンでは高速で動き、処理速度が遅いパソコンではゆっくり動くと困る。そんな処理を作る場合はFixedUpdateの中に書きましょう。
動作確認をしよう
スクリプトを書けたら、必ず CTRL+S で保存してから Unity に戻りましょう。
Player を動かすためには、作成した PlayerController2D を Player にアタッチする必要があります。Project ウィンドウから Assets > Scripts を開きます。その中にある PlayerController2D を、Hierarchy にある Player へドラッグ&ドロップしましょう。

これで Player に PlayerController2D がアタッチされました。
Hierarchy で Player を選択し、Inspector を確認してみましょう。

PlayerController2D が追加されていれば成功です。
また、Move Speed の項目が表示されていると思います。これは Player の移動速度です。最初は5のままで大丈夫です。ここまでできたら一度Unityで再生して確認してみましょう。

キーボードの左矢印キーを押すとPlayer が左に動きます。右矢印キーを押すとPlayer が右に動きます。何も押していないときはその場で止まります。
これでプレイヤーキャラクターの左右移動ができるようになりました。
Unityでキャラをジャンプできるようにしよう
次はPlayer をジャンプできるようにしていきます。
今回はSpace キーを押したら Player が上にジャンプするようにします。
ジャンプ処理も考え方はとてもシンプルです。
Space キーが押されたら、Player の Rigidbody2D に上方向の速さを入れます。
これだけでプレイヤーキャラクターは上に飛び上がります。
スクリプトを書こう
まずは、前の章で作成した PlayerController2D を開きます。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 |
using UnityEngine; public class PlayerController2D : MonoBehaviour { [Header("Move Settings")] public float moveSpeed = 5f; public float jumpPower = 8f; private Rigidbody2D playerRigidbody; private float horizontalInput; // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { //プレイヤーのRigidbody2Dを取得 playerRigidbody = GetComponent<Rigidbody2D>(); } // Update is called once per frame void Update() { // 入力、-1:左、0:なし、1:右、のように扱います horizontalInput = 0f; if (Input.GetKey(KeyCode.LeftArrow)) { horizontalInput = -1f; } else if (Input.GetKey(KeyCode.RightArrow)) { horizontalInput = 1f; } if (Input.GetKeyDown(KeyCode.Space)) { playerRigidbody.linearVelocity = new Vector2(playerRigidbody.linearVelocity.x, jumpPower); } } void FixedUpdate() { // Rigidbody2Dの速度を変更して、左右に移動します。 playerRigidbody.linearVelocity = new Vector2(horizontalInput * moveSpeed, playerRigidbody.linearVelocity.y); } } |
スクリプトの解説
今回ジャンプ実装のために追加した処理は主に2カ所です。
まずはこちらです。
|
1 2 3 |
[Header("Move Settings")] public float moveSpeed = 5f; public float jumpPower = 8f; |
これは、Player のジャンプ力を決める数字です。数字を大きくすると、Player は高くジャンプします。数字を小さくすると、Player のジャンプは低くなります。
public を付けているので、Unity の Inspector からも数字を変更できます。

そのため、実際にゲームを再生しながら「少し高すぎる」「もう少し低くしたい」と思ったときに、スクリプトを開かずに調整できます。
次に、こちらです。
|
1 2 3 4 |
if (Input.GetKeyDown(KeyCode.Space)) { playerRigidbody.linearVelocity = new Vector2(playerRigidbody.linearVelocity.x, jumpPower); } |
この部分では、Space キーが押された瞬間を確認しています。Input.GetKeyDown(KeyCode.Space) は、「Space キーが押された瞬間だけ反応する」という意味です。
前回の左右移動では Input.GetKey を使いました。Input.GetKeyはキーを押している間ずっと反応します。左右移動ではキーを押している間はずっと動いてほしいので GetKey を使いました。
ですが、ジャンプは Space キーを押している間ずっと上に飛び続けてほしいわけではありません。
Space キーを押した瞬間に1回だけジャンプしてほしいので、今回は GetKeyDown を使っています。

Space キーが押されたときは次の1行でPlayer の速度を変更しています。
|
1 |
playerRigidbody.linearVelocity = new Vector2(playerRigidbody.linearVelocity.x, jumpPower); |
linearVelocity は、Rigidbody2D の速度です。new Vector2(横の速さ, 縦の速さ) の形で、横と縦の速度を指定します。
今回、横の速さには playerRigidbody.linearVelocity.x を入れています。
これは、今の横方向の速度をそのまま使うという意味です。ジャンプするときに左右移動の速さまで勝手に変えたくないためです。
そして縦方向に jumpPower の速度を入れることでPlayer が上に飛び上がります。
つまり、この 1 行は横の速さはそのままで縦の速さだけ jumpPower にするということです。
これでSpace キーを押した瞬間にプレイヤーがジャンプするようになります。
なぜ Jump は FixedUpdate で行わないの?
左右移動は FixedUpdate で行いましたが、今回の Jump は Update の中に書いています。理由は、Jump では GetKeyDown を使っているからです。GetKeyDown は、キーを押した瞬間に 1 回だけ反応します。Space キーを押しっぱなしにしても、ずっと反応するわけではありません。
一方、FixedUpdate は物理計算用の決まったタイミングで呼ばれます。そのため、FixedUpdate の中で GetKeyDown を確認すると、Space キーを押した瞬間をうまく拾えないことがあります。

まとめると、Jump は「押した瞬間を拾う処理」なので Update に書いています。
左右移動は「押している間ずっと速度を変える処理」なので FixedUpdate に書いています。
動作を確認しよう
ここまでできたら、必ず CTRL + S でスクリプトを保存してから Unity に戻りましょう。Unity に戻ったら、再生ボタンを押して確認します。

Space キーを押したときに Player がジャンプできれば成功です。
これでPlayer にジャンプ処理を追加できました。
しかし、今の状態には 1 つ問題があります。Space キーを連打してみてください。

地面にいない空中の状態でもSpace キーを押すたびに何度もジャンプできてしまいます。
この問題を解決するために次はPlayer が地面にいるときだけジャンプできるようにするための「接地判定」を作っていきましょう。
接地判定を行って無限ジャンプを防ごう
次は、空中で何度もジャンプできてしまう問題を直していきます。
どのように防げばいいのでしょうか?
考え方はシンプルです。Player の足元に地面や足場があるときだけジャンプできるようにします
つまり、Space キーを押したときにすぐジャンプするのではなく、先に「今、地面にいるか?」を確認します。
- 地面にいるならジャンプする。
- 地面にいないならジャンプしない。
この形にすれば空中で何度もジャンプできる問題を防ぐことができます。
まずはPlayer の足元を調べるための目印を作成しましょう。
Hierarchy から Player を選択します。

Player を選択した状態で右クリックし、Create Empty を選択しましょう。作成された Empty オブジェクトの名前を GroundCheck に変更します。

GroundCheck はプレイヤーの足元に地面があるかを調べるための目印です。
GroundCheck を選択し、Inspector の Transform を調整して、Player の足元より少し下に配置しましょう。

Player の中心ではなく足元に置くことが大切です。ここがずれると地面との接地判定が正しくできません。
Unity C#スクリプトで地面との設置判定を制御しよう
次に、スクリプトで地面にいるかを確認できるようにします。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 |
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; private Rigidbody2D playerRigidbody; private float horizontalInput; private bool isGrounded; // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { //プレイヤーのRigidbody2Dを取得 playerRigidbody = GetComponent<Rigidbody2D>(); } // Update is called once per frame void Update() { // 入力、-1:左、0:なし、1:右、のように扱います horizontalInput = 0f; if (Input.GetKey(KeyCode.LeftArrow)) { horizontalInput = -1f; } else if (Input.GetKey(KeyCode.RightArrow)) { horizontalInput = 1f; } //GroundCheckに小さな円を作成、Groundレイヤーに接触しているか確認 isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer); if (Input.GetKeyDown(KeyCode.Space) && isGrounded) { playerRigidbody.linearVelocity = new Vector2(playerRigidbody.linearVelocity.x, jumpPower); } } void FixedUpdate() { // Rigidbody2Dの速度を変更して、左右に移動します。 playerRigidbody.linearVelocity = new Vector2(horizontalInput * moveSpeed, playerRigidbody.linearVelocity.y); } } |
スクリプトの解説
今回追加した目的は、Player が地面にいるかを調べることです。まず追加したのがこちらです。
|
1 2 3 4 |
[Header("Ground Check")] public Transform groundCheck; public float groundCheckRadius = 0.2f; public LayerMask groundLayer; |
groundCheck には、先ほど作成した GroundCheck を設定します。これは「どこを調べるか」を決めるものです。今回は Player の足元を調べたいのでGroundCheck を足元に配置しましたね。
groundCheckRadius は、調べる範囲の大きさです。GroundCheck の位置に小さな円を作り、その円が地面に触れているかを確認します。
groundLayer は、何を地面として見るかを決める設定です。地面や足場だけを判定したいので、Ground Layer を指定します。
次に追加したのがこちらです。
|
1 |
private bool isGrounded; |
isGrounded は、Player が地面にいるかどうかを入れておくものです。
- 地面にいるときは true。
- 地面にいないときは false。
この true / false を使って、ジャンプできるかどうかを判断します。
次にこの1行です。
|
1 2 |
//GroundCheckに小さな円を作成、Groundレイヤーに接触しているか確認 isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer); |
この OverlapCircle が実際に地面にいるかを調べています。GroundCheck の位置に、小さな円を作ります。その円の大きさが groundCheckRadius です。その円が groundLayer に触れていれば、isGrounded は true になります。触れていなければ、isGrounded は false になります。
つまり、この 1 行でPlayer の足元に Ground Layer があるか調べています。このGround Layerは後でUnityエディタから行います。
最後にジャンプ可能かどうかを調べる条件を変更しています。
|
1 2 3 4 |
if (Input.GetKeyDown(KeyCode.Space) && isGrounded) { playerRigidbody.linearVelocity = new Vector2(playerRigidbody.linearVelocity.x, jumpPower); } |
前回は、Space キーを押しただけでジャンプしていました。今回は、条件に isGrounded を追加しています。&& は、「両方そろったら」という意味です。つまり、
- Space キーが押された。
- Player が地面にいる。
この2つがそろったときだけジャンプします。そのため、空中で Space キーを押しても、isGrounded が false なのでジャンプできません。
&& とは?
if 文では、1つの条件だけでなく複数の条件を組み合わせることができます。
| 書き方 | 意味 | スクリプト例 | スクリプトの意味 |
| && | 両方の条件がそろった | Input.GetKeyDown(KeyCode.Space) && isGrounded | スペースキーが押されて地面にいる |
| || | 片方の条件がそろった | Input.GetKeyDown(KeyCode.Space) || isGrounded | スペースキーが押された、又は地面にいる |
| ! | 条件を反対にする | !isGrounded | 地面にいない |
| == | 同じなら | horizontalInput == 0 | 入力が0なら |
| != | 同じではないなら | horizontalInput != 0 | 入力が0でない |
| >又は< | より大きい、より小さい | horizontalInput > 0 | 入力が0より大きい |
| >=又は<= | 以上、以下 | horizontalInput >= 0 |
入力が0、または0より大きい |
動作を確認しよう
ここまでできたら必ず CTRL + S で保存してUnityに戻りましょう。
忘れてはいけないのが、地面や足場に Ground Layer を設定することです。今回のスクリプトでは、GroundCheck の位置に小さな円を作り、その円が Ground Layer に触れているかを確認しています。
そのため、地面や足場が Ground Layer になっていないと、Player が地面に立っていても「地面にいる」と判定されません。
Project ウィンドウから Prefabs フォルダを開きましょう。地面と足場の Prefab を、Shift キーでまとめて選択します。

Inspector の上の方にある Layer のドロップダウンを開き、Add Layer を選択しましょう。

User Layer 6 に Ground と入力します。

Layer を作成しただけでは、まだ地面や足場には設定されていません。もう一度 Prefabs フォルダに戻り、地面と足場の Prefab を Shift キーでまとめて選択し直しましょう。

Inspector の Layer を開き、Ground を選択します。

これで、地面と足場に Ground Layer を設定できました。
Layer とは?
Layer は、オブジェクトを種類ごとに分けるための設定です。今回の場合は、地面や足場に Ground という Layer を付けています。
Layer を使うと、スクリプトから「Ground Layer だけを調べる」ことができます。
もし Layer を使わないと、Player の足元にあるものが地面なのか、敵なのか、アイテムなのかを区別しにくくなります。今回はジャンプできるかどうかを調べたいだけです。そのため、地面と足場だけを Ground Layer にしてGroundCheck が Ground Layer に触れているかを確認しています。
つまり Layer は、地面なのか、敵なのか、またはアイテムなのかというようにUnity にオブジェクトの種類を教えるための目印です。
次にHierarchy から Player を選択します。

Inspector の PlayerController2D を確認しましょう。Ground Check の項目にある Ground Check へ、先ほど作成した GroundCheck オブジェクトを設定します。

次に、Ground Layer のドロップダウンを開きます。一覧の中から Ground のみにチェックを入れましょう。

ここまでできたら、再生して確認しましょう。Space キーを押すと、Player がジャンプします。そのあと、空中で Space キーを連打してみましょう。

空中で何度もジャンプできなくなっていれば成功です。
プロジェクトファイルのダウンロード
今回の講座で作ったプロジェクトファイルのダウンロードリンクを用意しました。
今回のまとめ
この章ではPlayer の基本的な操作を作成しました。
Player オブジェクトを作成し、Rigidbody2D と Collider2D を追加して、物理と当たり判定を設定しました。
その後、スクリプトを使って左矢印キーと右矢印キーで Player を左右に動かせるようにしました。
さらに、Space キーでジャンプできるようにし、最後に GroundCheck を使って、地面や足場にいるときだけジャンプできるようにしました。これで空中で Space キーを連打しても無限にジャンプできない基本的な横スクロールアクションの操作ができました。
ただ、現時点ではまだ「キャラクターを操作している」というよりも、「画像を左右に動かしている」という印象が強いと思います。
次回はPlayer が進む方向を向くようにして、歩いているときのアニメーションを追加し、最後に Camera が Player を追いかけるように設定していきます。
次の記事:

現場レベルのゲーム制作が、すべてここで学べます。









コメント