※本記事にはアフィリエイトリンクが含まれています。
Amazonのアソシエイトとして、ゲームのタネは適格販売により収入を得ています。
▶ この回の完成形を、この場で遊ぶ
前回の Godot 版と同じルールの20秒的あてです。Unity でも同じゲームを完成させ、受け取り方の違いを見ます。
Godot / Unity どちらの完成プロジェクトとも同じルールです。はじめる(または画面クリック、R)で開始します。
Unity の完成プロジェクト
ブラウザで遊んでいるものと同じゲームです。ZIP を解凍し、Unity 6.3 LTS(6000.3)でフォルダを開いて Play。
unity-click-targets.zip をダウンロード
Godot の完成プロジェクト(前回)
同じルールの Godot 4.7 版です。click_targets-3.zip を解凍し project.godot を開いて F5。
手順の詳細は 第1回(Godot) を参照してください。この回では Godot を一から書き直しません。
はじめに
「Godot では的をクリックできた。Unity だと、同じことをどう書くの?」——そんな続きの疑問向けです。
この記事では、Unity 6.3 LTS で、前回と同じ20秒的あてを1本作って完成させます。的は自分で出てきて、短い時間で消えます。出ているあいだにクリックすると1点、時間切れで終了です。自己ベストを更新するために、何度でもやり直せます。
今週身につけること:コンポーネントの分け方。 Godot の「ノードの木」と、Unity の「1つの GameObject に部品を足す」やり方を、同じゲームで並べて見ます。制限時間と得点は、それがゲームになるための枠です。
完成形と、やらないこと
- 作るもの: 20秒間、的がランダムに出現する。クリックで1点。逃すと得点は増えない。時間切れで終了、Rでやり直し。Unity 版の ZIP と、前回の Godot ZIP。
- やらないこと: Godot 側の再解説、画像素材の作り込み、音、ランキングサーバー、スマホ専用UI。
- 持ち帰る1アイデア: クリックは「画面全体」ではなく、当たり判定を持つオブジェクトが受け取る。Godot なら
Area2D、Unity ならCollider2D付きの GameObject。


並べて見る:Godot と Unity
| 役割 | Godot(第1回) | Unity(この回) |
|---|---|---|
| 的の入れ物 | Area2D ノード |
GameObject |
| 見た目 | 子の Polygon2D |
SpriteRenderer |
| 当たり | 子の CollisionShape2D |
CircleCollider2D |
| クリック | _input_event |
OnMouseDown |
| 出現・時間・得点 | main.gd |
GameManager.cs |
| 複製 | instantiate() + シーン |
Instantiate または実行時生成 |
どちらも「形の上のクリックだけを拾う」という考え方は同じです。違うのは、部品を子ノードとして積むか、同じオブジェクトにコンポーネントとして付けるかです。
準備(Unity)
- Unity 6 の LTS(執筆時点は 6.3 LTS / 6000.3)を Unity Hub から入れます。
- 完成一式から始める場合は、上の Unity ZIP を解凍し、Hub の「開く」でフォルダを選びます。自分で組む場合は 2D(Built-in または URP)の新規プロジェクトでも構いません。
- 大事: Edit → Project Settings → Player → Active Input Handling を Both(または Input Manager (Old))にします。
OnMouseDownは、新しい Input System だけだと呼ばれないことがあります(公式のOnMouseDownページにも注意があります)。

的オブジェクト(Unity)
的は「見た目」と「クリックを拾う範囲」をセットで持ちます。Unity では 1 つの GameObject に SpriteRenderer と CircleCollider2D と脚本を足します。
- 空の GameObject を作り、名前を
Targetにします(完成 ZIP ではコードが実行時に作ります)。 CircleCollider2Dを追加します。半径は見た目の円と揃えます。- 見た目用に
SpriteRenderer(白い円スプライトなど)を付け、色を変えます。 - 次の
Target.csをアタッチします。
スクリプト1:Target.cs(的に付ける)
ファイル名:Assets/Scripts/Target.cs。的の GameObject にアタッチします。
using UnityEngine;
/// 的1個。CircleCollider2D 必須。クリックで消えて得点。
[RequireComponent(typeof(CircleCollider2D))]
public class Target : MonoBehaviour
{
public System.Action onCleared;
const float Life = 1.15f;
float bornAt;
void Start()
{
bornAt = Time.time;
}
void Update()
{
if (Time.time - bornAt >= Life)
Destroy(gameObject); // 逃した的:得点なし
}
void OnMouseDown()
{
// Collider2D の上で左クリックされたときだけ呼ばれる
onCleared?.Invoke();
Destroy(gameObject);
}
}
別ゲームに持ち替えるときの変更点: 消す代わりに HP を減らしたいなら Destroy の前に処理を挟みます。キー入力にしたいなら OnMouseDown ではなく、親側でキーを見て対象を選ぶ形に変えます。
なぜ OnMouseDown か:画面全体のマウス座標を毎回自分で計算するより、「この Collider の上で起きたクリック」を Unity が渡してくれます(公式ドキュメント:Collider の上で左ボタンを押したときに呼ばれる)。
出現・得点・制限時間(GameManager)
親役は GameManager.cs です。完成 ZIP では、カメラ・UI・的の円スプライトまで実行時に用意するので、空のシーンに脚本を1つ付けて Play できます。
using UnityEngine;
using UnityEngine.UI;
/// 出現・制限時間・得点・やり直し(抜粋)。完成ZIPは UI 生成込みの全文です。
public class GameManager : MonoBehaviour
{
const float Limit = 20f;
const float SpawnEvery = 0.55f;
const int MaxOnScreen = 3;
public Text hud;
public Transform targetsRoot;
int score, best;
float timeLeft, spawnAcc;
string state = "ready"; // ready | play | over
void Update()
{
if (Input.GetKeyDown(KeyCode.R))
StartGame();
if (state != "play") return;
timeLeft -= Time.deltaTime;
spawnAcc += Time.deltaTime;
if (spawnAcc >= SpawnEvery)
{
spawnAcc = 0f;
Spawn();
}
if (timeLeft <= 0f)
{
EndGame();
return;
}
RefreshHud();
}
public void StartGame()
{
state = "play";
score = 0;
timeLeft = Limit;
spawnAcc = 0f;
foreach (Transform c in targetsRoot)
Destroy(c.gameObject);
Spawn();
Spawn();
RefreshHud();
}
void EndGame()
{
state = "over";
foreach (Transform c in targetsRoot)
Destroy(c.gameObject);
if (score > best) best = score;
hud.text = $"終了 得点 {score} 自己ベスト {best}";
}
void Spawn()
{
if (targetsRoot.childCount >= MaxOnScreen) return;
// 完成ZIP:円スプライト+CircleCollider2D+Target を生成し
// target.onCleared = () => { score++; RefreshHud(); };
}
void RefreshHud()
{
hud.text = $"得点 {score} 残り {Mathf.CeilToInt(timeLeft)} 秒";
}
}
Instantiate でプレハブを出す書き方でも同じです。完成 ZIP はアセット不足で壊れないよう、円をコードで描いています。

Playして確認すること
- Unity で Play。最初は止まります。はじめる(または盤面クリック、R)でスタートします。
- 的が次々と出ます。的の上で左クリックすると1点入ります。
- クリックしない的は約1.15秒で消えます。空白をクリックしても得点は増えません。
- 20秒で「終了」と自己ベストが出ます。もう一度または R でやり直しです。
「動けばOK」ではなく、次を確認してください。空白をクリックしても得点が増えないこと。 これが「Collider が入力を受け取っている」証拠です。Godot 第1回の「Area2D が受け取っている」と同じ確認です。

よくあるつまづき(1つ)
症状: Play しても的をクリックしても消えない。
気づき方: (1) 的に CircleCollider2D が付いているか。(2) Player 設定の Active Input Handling が Both か Input Manager になっているか(新しい Input System のみだと OnMouseDown が来ないことがあります)。(3) カメラが Orthographic で、的がカメラの見える範囲にあるか。
Godot 側で「得点は動くのに的が見えない」ときは、CanvasLayer の色付き矩形で盤面を覆っていないかも見ます(第1回の注意)。Unity では Canvas を Screen Space Overlay にしておけば、ワールドの的を Canvas の色で隠しにくいです。
できたこと/身についたこと
- 同じ20秒的あてを、Unity でも完成させられた。
- Godot のノード分割と、Unity のコンポーネント分割を対応づけて説明できる。
OnMouseDownとCircleCollider2Dで「オブジェクトがクリックを受け取る」形が作れた。
使い回しメモ
- スニペット:
Target.csのOnMouseDown一式(Godot ならtarget.gdの_input_event)。 - エンコードしている考え: 「入力はオブジェクトが拾う」。エンジンが違っても役割は同じ。
- 次の使い道: シューティングの敵をタップで倒す、マップ上の建物を選ぶ、メニューの透明な当たり領域。
次の自分のゲームで使うなら
ジャンルが違っても、「画面のどこかをクリックした」ではなく「どの当たりの上か」を先に決めると同じ詰まりを避けられます。エンジンを変えるときは、まず「見た目」「当たり」「入力の受け口」の3つがどこに乗っているかを書き出してみてください。
次に足してよい一言
的が消えるたびに短い音を1つ足す、または連続ヒットで得点が伸びる、くらいが次の小さな一歩です。
関連商品(PR)
この回は Unity 側の入門とクリック操作が中心なので、続きの学習用の本と、操作しやすいマウスだけ短く挙げます。価格は店舗で確認してください。
- Unityの教科書 Unity 6完全対応版(北村愛実) Amazonで見る
※本リンクはアフィリエイトリンクです。 - ゆるっとはじめる Godot Engine ゲームプログラミング(杉山悠真) Amazonで見る
※本リンクはアフィリエイトリンクです。 - Logicool G304 ワイヤレスゲーミングマウス(クリック操作の練習にも扱いやすい定番) Amazonで見る
※本リンクはアフィリエイトリンクです。
参考
クラスやメソッド、エンジンのバージョンは、次の公式ページで確認しています。


コメント