学習記事一覧 · Unity

Unity復習問題集 ── 1日目:手を動かして思い出す

対象:Unityの教科書 Unity 6完全対応版 Chapter 3〜8 履修済みの方
方針:コードは見ながらでOK。暗記不要。「なぜ?」「何が起きる?」「どう変える?」を考える問題です。
使用ゲーム:Roulette・SwipeCar・CatEscape・ClimbCloud・Igaguri


作業前の準備(GitHub Desktop)

各チュートリアルはリポジトリが分かれているので、使うリポジトリごとにブランチを作成してください。

1日目で使うリポジトリとブランチ作成

リポジトリ 使う問題 やること
Roulette Q1・Q2 review ブランチを作成
SwipeCar Q5 review ブランチを作成
CatEscape Q3 review ブランチを作成
ClimbCloud Q4 review ブランチを作成
Igaguri Q6 review ブランチを作成

ブランチの作り方(各リポジトリで共通):

  1. GitHub Desktop の左上でリポジトリを切り替える
  2. 上部のブランチ名をクリック →「New Branch
  3. ブランチ名を review にして作成
  4. 問題を解く前にブランチが review になっていることを確認する

なぜブランチを作るの?
main を汚さずに実験できます。間違えても main に戻れば元通りです。

コミットのタイミング

タイミング やること
1問解き終わったとき Summary に Q1完了 と入力して Commit
値を変えて実験したいとき 変える前に コミットしておく(いつでも戻せるように)
元に戻したいとき GitHub Desktop で該当ファイルを右クリック →「Discard Changes

2限:動かして確かめる①(Roulette・SwipeCar)

Unityでゲームを起動しながら答えてください。


Q1【Roulette】減速率を変えてみよう

RouletteController.cs の減速率の値を変えて、ゲームを3回動かしてください。

this.rotSpeed *= 0.96f;  // ← この値を変える

それぞれの止まり方を自分の言葉で記録してください。

試した値 止まり方(自分の言葉で)
0.99f
0.96f(元の値)
0.80f

考えてみよう: 1.0f にしたらどうなりますか?
まず予想を書いてから、実際に試して確かめてください。

予想 実際の結果

Q2【Roulette】ゲーム開始直後から自動で回り続けるには?

現在は「クリックしたとき rotSpeed = 10 になる」コードです。
ゲーム開始直後から自動で回り始めるようにするには、コードのどこをどう変えればよいですか?

ヒント:Start() の役割を思い出してください。

(ここに考えたことを書いてください)

Q5【SwipeCar】スワイプの長さと速度の関係を確かめよう

SwipeCar では「スワイプした距離(magnitude)」が速度になります。

実験: 短くシュッとスワイプした場合と、ゆっくり大きくスワイプした場合で、車の速さはどう変わりましたか?

スワイプの仕方 車の速さ
短くシュッとスワイプ
ゆっくり大きくスワイプ

考えてみよう: magnitude ではなく常に固定の速度 speed = 5 にしたら、ゲームとしてどう変わりますか?

良い点 悪い点(プレイヤーの体験として)

3限:動かして確かめる②(CatEscape・ClimbCloud)


Q3【CatEscape】矢の生成間隔を変えてみよう

ArrowGenerator.csspan を変えて、難しさの違いを確かめてください。

float span = 2.0f;  // ← この値を変える

考えてみよう: span = 0 にしたらどうなりますか?
予想してから試してください。

予想 実際の結果

Q4【ClimbCloud】ジャンプの強さを変えてみよう

※ コードについての補足
教科書のオリジナルコードは ForceMode2D.Force(省略時のデフォルト)を使っており、
値を直感的に比較しにくいため、この問題では ForceMode2D.Impulse に書き直しています。

モード 意味 値の感覚
ForceMode2D.Force(省略時) 毎秒かかり続ける力として計算される 大きな値が必要(例:600)
ForceMode2D.Impulse 瞬間的にドンと押す衝撃として計算される 値 ≈ ジャンプ直後の速度(m/s)

Impulse で値 12 にすると、オリジナル(Force で値 600)とほぼ同じジャンプ力になります。
(計算:600 × 0.02秒 ÷ 質量1 ≒ 12 m/s

this.rb.AddForce(new Vector2(0, 12), ForceMode2D.Impulse);

12 の部分を 51220 に変えて、違いを言葉で説明してください。

試した値 ジャンプの様子
5
12(元のゲームと同等)
20

さらに考えてみよう: 100 にしたら最強ジャンプになると思いますか?
予想してから試して、なぜそうなったかを説明してください。

予想 実際の結果 なぜそうなったか

4限:動かして確かめる③(Igaguri)


Q6【Igaguri】isKinematic を切り替えてみよう

Igaguri では的に当たったいがぐりを止めるために次のコードを使っています。

this.rb.isKinematic = true;

実験: この行をコメントアウト(先頭に // を付ける)して動かすと何が起きますか?

(実際に試した結果を書いてください)

考えてみよう: isKinematic = true は「物理演算を止める」という意味ですが、なぜ当たった後に物理演算を止めたいのでしょうか?

(理由を書いてください)

5限:Find / GetComponent 概念①(街の例え・2行の理由)

コードを見ながら考えてください。Unityは起動しなくてもOKです。


Q7【概念】Unityのシーンを「街」に例えると?

次の例えを読んで、各操作が何に対応するか説明してください。

街(シーン)の中に、たくさんの建物(GameObject)がある。
建物の中には、電気・水道・エレベーターなど様々な設備(コンポーネント)が入っている。

コード 「街」の例えで言うと?
GameObject.Find("役所")
GetComponent<水道>()

考えてみよう: 「建物を見つけてから設備を使う」2ステップが必要な理由は何ですか?

(理由を書いてください)

Q8【順番の理解】なぜ2行必要なのか

CatEscape では ArrowController から GameDirector のメソッドを呼ぶとき次のように書いています。

GameObject director = GameObject.Find("GameDirector");       // ①
director.GetComponent<GameDirector>().DecreaseHp();          // ②

①だけ、または②だけではなぜダメなのか、それぞれ説明してください。

パターン どうなる?
①だけしか書かない
②だけしか書かない

6限:Find / GetComponent 概念②(エラー・司令塔・1行vs2行)


Q9【エラー読み解き】このコードの問題はどこ?

次のコードを見て問題点を指摘してください。

void Update()
{
    GameObject director = GameObject.Find("GameDirector");
    director.GetComponent<GameDirector>().UpdateScore();
}

このコードは動くかもしれませんが、プロのエンジニアが見ると「まずい」と感じます。
何が問題でしょうか?

(問題点を書いてください)

Q10【設計の視点】どのスクリプトが「司令塔」か

CatEscape の4スクリプト間の呼び出し関係を、矢印(→)で表してください。

PlayerController
ArrowGenerator
ArrowController
GameDirector

呼び出し関係:

(例:ArrowController → GameDirector)
(自分で考えて書いてください)

考えてみよう: GameDirector が「司令塔」と呼ばれる理由を説明してください。

(理由を書いてください)

Q11【応用】1行に短縮できる?

Q8の2行コードは1行でも書けます。

// 2行版
GameObject director = GameObject.Find("GameDirector");
director.GetComponent<GameDirector>().DecreaseHp();
// 1行版(チェーン記法)
GameObject.Find("GameDirector").GetComponent<GameDirector>().DecreaseHp();

1行版と2行版、どちらが良いコードだと思いますか?
理由も含めて答えてください。(「場合による」も可。なぜそう思うかが大切です。)

(答えと理由を書いてください)

作成:2026年4月