第6週:クリックした場所から出そう
前回は画像を取り込んで、Rigidbody 2Dで落として、Collider 2Dで床に乗せました。
- Rigidbody 2D:動かす(重力・速度)
- Collider 2D:形を教える(当たり判定)
- 末尾の2Dを忘れると動かない
でも玉は1つだけで、手で置いたものでした。 今日はクリックした場所から玉が出てくるようにします。
- Prefab(プレハブ)で玉の「設計図」を作る
Instantiateでスクリプトから玉を増やす- マウスのクリック位置をゲームの座標に変換する
Prefabという考え方
Section titled “Prefabという考え方”なぜPrefabが必要?
Section titled “なぜPrefabが必要?”玉を100個落としたいとき、100個を手で並べるのは無理です。 そこで「設計図」を1つ作っておいて、スクリプトからコピーを作る という方法をとります。
この設計図をUnityではPrefab(プレハブ)と呼びます。

Prefabのすごいところ
Section titled “Prefabのすごいところ”- スクリプトから何個でも作れる
- Prefabを直せば、コピー全部が直る
- ファイルとして保存されるので、他のシーンでも使える
玉のPrefabを作ろう
Section titled “玉のPrefabを作ろう”準備:Prefabsフォルダを作る
Section titled “準備:Prefabsフォルダを作る”- Projectウィンドウの
Assetsを右クリック - Create → Folder
- 名前を
Prefabsにする
Ballを整えてからPrefabにする
Section titled “Ballを整えてからPrefabにする”前回作ったBallをそのままPrefabにします。
その前に、Prefabにする前提で名前を分かりやすくしておきましょう。
- Hierarchyで
Ballを選択 - F2キーで名前を
Ball1に変更(レベル1の玉という意味) - Inspectorで次を確認:
- Sprite Rendererに
level1が設定されている Rigidbody 2Dが付いているCircle Collider 2Dが付いている
- Sprite Rendererに
Prefabにする
Section titled “Prefabにする”- Hierarchyの
Ball1をつかんで、 ProjectウィンドウのAssets/Prefabsフォルダにドロップ PrefabsフォルダにBall1というファイルができる- Hierarchyの
Ball1の文字が青色に変わる
(=Prefabとつながっている印)

シーンから玉を消す
Section titled “シーンから玉を消す”これからスクリプトで玉を作るので、最初から置いてある玉は不要です。
- Hierarchyの
Ball1を選択 - Deleteキーで削除
再生してみると、床だけがある状態になっています。
スクリプトで玉を作ろう
Section titled “スクリプトで玉を作ろう”Spawnerオブジェクトを作る
Section titled “Spawnerオブジェクトを作る”玉を作る役目のGameObjectを用意します。
- Hierarchyで右クリック → Create Empty
- 名前を
BallSpawnerに変更 - Positionは
(0, 0, 0)のまま
最初のバージョン:スペースキーで出す
Section titled “最初のバージョン:スペースキーで出す”いきなりマウス対応は難しいので、まずキーを押したら真ん中から出る ものを作ります。
Assets/Scriptsフォルダを右クリック- Create → MonoBehaviour Script
- 名前を
BallSpawnerにする - ダブルクリックしてVisual Studioで開く
using UnityEngine;using UnityEngine.InputSystem;
public class BallSpawner : MonoBehaviour{ // Inspectorから玉のPrefabを設定する public GameObject ballPrefab;
// 玉が出てくる高さ public float spawnY = 4f;
void Update() { // スペースキーを押した瞬間 if (Keyboard.current.spaceKey.wasPressedThisFrame) { // 画面の真ん中の上に玉を作る Vector3 spawnPos = new Vector3(0, spawnY, 0); Instantiate(ballPrefab, spawnPos, Quaternion.identity); } }}スクリプトを取り付けてPrefabを渡す
Section titled “スクリプトを取り付けてPrefabを渡す”BallSpawner.csをBallSpawnerオブジェクトにドラッグ- Hierarchyで
BallSpawnerを選択 - InspectorにBall Prefabという欄が出ている
Assets/Prefabs/Ball1をその欄にドラッグ

再生して確認
Section titled “再生して確認”再生ボタンを押して、スペースキーを何回か押してみてください。
玉が次々に出てきて、床に積み上がります!

コードの解説
Section titled “コードの解説”| コード | 意味 |
|---|---|
public GameObject ballPrefab; |
Inspectorから設定できる玉の設計図 |
Keyboard.current.spaceKey |
スペースキーの状態 |
wasPressedThisFrame |
押した瞬間だけtrue |
Instantiate(A, B, C) |
設計図Aから、位置Bに、向きCで作る |
Quaternion.identity |
「回転なし」を表す決まった書き方 |
クリックした場所から出そう
Section titled “クリックした場所から出そう”いよいよマウス対応です。
難しいのは「座標の違い」
Section titled “難しいのは「座標の違い」”マウスの位置と、ゲームの中の位置は単位が違います。
| スクリーン座標 | ワールド座標 | |
|---|---|---|
| 何の座標か | 画面上のピクセル位置 | ゲーム世界の位置 |
| 原点(0,0) | 画面の左下 | 画面の中央(カメラの位置) |
| 単位 | ピクセル(例:1920) | メートル(例:8) |
| 使うもの | マウスの位置 | GameObjectのPosition |

マウスの位置をそのままPositionに入れると、 玉がとんでもなく遠くに飛んでいきます。 そこで変換が必要です。
変換してくれる命令
Section titled “変換してくれる命令”// スクリーン座標 → ワールド座標に変換するVector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);Camera.mainは「MainCameraタグが付いたカメラ」を自動で見つけてくれます。
完成版のBallSpawner
Section titled “完成版のBallSpawner”using UnityEngine;using UnityEngine.InputSystem;
public class BallSpawner : MonoBehaviour{ public GameObject ballPrefab; public float spawnY = 4f;
void Update() { // マウスの左ボタンを押した瞬間 if (Mouse.current.leftButton.wasPressedThisFrame) { // 1. マウスの画面上の位置を取る Vector2 screenPos = Mouse.current.position.ReadValue();
// 2. ゲーム世界の位置に変換する Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
// 3. 高さは固定して、横の位置だけマウスに合わせる Vector3 spawnPos = new Vector3(worldPos.x, spawnY, 0);
// 4. 玉を作る Instantiate(ballPrefab, spawnPos, Quaternion.identity); } }}再生して確認
Section titled “再生して確認”再生して、画面のいろいろな場所をクリックしてみてください。
クリックした真上から玉が落ちてきます!

ここまでできれば、もう「遊べる」状態です。 たくさんクリックして積み上げてみましょう。
玉が出すぎるのを抑える
Section titled “玉が出すぎるのを抑える”クリック連打で玉が出すぎると、動作が重くなります。 前の玉が落ちきるまで待つようにしてみましょう。
using UnityEngine;using UnityEngine.InputSystem;
public class BallSpawner : MonoBehaviour{ public GameObject ballPrefab; public float spawnY = 4f; public float waitTime = 0.5f; // 次に出せるまでの秒数
private float timer = 0f; // 経過時間
void Update() { // 時間を進める timer += Time.deltaTime;
// 待ち時間が過ぎていないなら、何もしない if (timer < waitTime) { return; }
if (Mouse.current.leftButton.wasPressedThisFrame) { Vector2 screenPos = Mouse.current.position.ReadValue(); Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos); Vector3 spawnPos = new Vector3(worldPos.x, spawnY, 0); Instantiate(ballPrefab, spawnPos, Quaternion.identity);
// タイマーをリセット timer = 0f; } }}よくある問題と解決方法
Section titled “よくある問題と解決方法”| 症状 | 原因と対処法 |
|---|---|
NullReferenceException が出て玉が出ない |
InspectorのBall Prefab欄が空。Prefabをドラッグする |
| 玉がとんでもない場所に出る | ScreenToWorldPointを使っていない |
| 玉が画面の外に出る | spawnYが大きすぎる。4くらいにする |
| クリックしても反応しない | using UnityEngine.InputSystem; を書いたか確認 |
Camera.mainがnull |
カメラのTagがMainCameraか確認 |
| 玉が1個しか出ない | UpdateではなくStartに書いていないか確認 |
| 玉が大量に出て重くなる | wasPressedThisFrameを使っているか確認 (isPressedだと押している間ずっと出る) |
基礎課題全員必須
クリックで玉が出るようにする:
Ball1のPrefabを作るBallSpawnerオブジェクトとスクリプトを作る- InspectorでBall Prefabを設定する
- クリックした場所の上から玉が落ちることを確認
- 最後にCtrl + Sで保存する
標準課題時間があれば
出方を調整する:
waitTimeを追加して連打を防ぐspawnYをInspectorで変えて出る高さを調整Debug.Logでクリック位置を表示し、 スクリーン座標とワールド座標の値を見比べる
発展課題チャレンジ
出る玉をランダムにする:
level2.pngを使ってBall2のPrefabも作るpublic GameObject[] ballPrefabs;で配列にするRandom.Range(0, ballPrefabs.Length)で ランダムに選ぶ- ヒント:配列はInspectorでSizeを2にしてから設定します
今のままでは玉が床の左右からこぼれ落ちてしまいます。
次回は箱を作って玉を閉じ込め、 さらに何種類もの玉がランダムに出てくるようにします。 これで合体の準備が整います。