コンテンツにスキップ

第7週:箱を作って積み上げよう

前回はPrefabを作り、Instantiateでクリックした場所から玉を出しました。

  • Prefab=オブジェクトの設計図
  • Instantiate=設計図から実物を作る
  • ScreenToWorldPointでマウス位置をゲームの座標に変換

でも玉は床の左右からこぼれ落ちてしまいます。 今日はを作って閉じ込めます。

  • 左右の壁を作って玉を箱の中に閉じ込める
  • 玉の種類を6つに増やす
  • 配列を使ってランダムな玉を出す
  • 積み上がり方を物理設定で調整する

床の左右に壁を立てて、コの字型の箱を作ります。

箱の完成イメージ
箱の完成イメージ

前回作ったFloorを、壁と組み合わせやすい位置にしておきます。

  1. HierarchyでFloorを選択
  2. Position:(0, -4, 0)
  3. Scale:(8, 0.5, 1)
  1. Hierarchyで右クリック → 2D Object → Sprites → Square
  2. 名前をWallLeftに変更
  3. Position:(-3.75, -1, 0)
  4. Scale:(0.5, 6, 1)(縦長にする)
  5. Sprite RendererのColorを床と同じ色にする
  6. Add Component → Box Collider 2Dを追加

左の壁をコピーすると速いです。

  1. HierarchyでWallLeftを選択
  2. Ctrl + Dで複製(WallLeft (1)ができる)
  3. 名前をWallRightに変更
  4. PositionのX だけ3.75に変更
壁の作成
壁の作成

整理する:親オブジェクトでまとめる

Section titled “整理する:親オブジェクトでまとめる”

床と壁が3つになったので、まとめておきましょう。

  1. Hierarchyで右クリック → Create Empty
  2. 名前をBoxに変更、Positionは(0, 0, 0)
  3. FloorWallLeftWallRightを選択
    (Ctrlを押しながらクリックで複数選択)
  4. まとめてBoxの上にドラッグ

再生して、たくさんクリックしてみてください。

玉が箱の中に溜まっていきます!

箱に溜まる玉
箱に溜まる玉

箱の端をクリックすると、玉が壁の上に乗ってしまいます。 出る位置を箱の中に限定しましょう。

// worldPos.x を -3 から 3 の範囲に押し込める
float x = Mathf.Clamp(worldPos.x, -3f, 3f);
Vector3 spawnPos = new Vector3(x, spawnY, 0);

合体させるには、玉が6種類必要です。 Prefabを増やしましょう。

Ball2を作る手順です。

  1. ProjectウィンドウでAssets/Prefabsを開く
  2. Ball1を選択してCtrl + Dで複製
  3. 名前をBall2に変更(F2キー)
  4. Ball2ダブルクリックしてPrefabを開く
  5. Sprite RendererのSprite欄にlevel2をドラッグ
  6. Circle Collider 2Dを付け直す(次の項目で説明)
  7. 左上の「<」ボタンでシーンに戻る

同じ手順でBall3Ball6も作ります。

Prefabの複製と編集
Prefabの複製と編集

超重要:当たり判定の大きさを合わせる

Section titled “超重要:当たり判定の大きさを合わせる”

画像の大きさから計算できます。

Prefab 画像 画像の幅 Radiusの目安
Ball1 level1 96 px 0.48
Ball2 level2 128 px 0.64
Ball3 level3 160 px 0.80
Ball4 level4 200 px 1.00
Ball5 level5 240 px 1.20
Ball6 level6 288 px 1.44

6種類のPrefabをスクリプトに渡すために、配列を使います。

// 玉のPrefabをまとめて入れる箱(配列)
public GameObject[] ballPrefabs;
using UnityEngine;
using UnityEngine.InputSystem;
public class BallSpawner : MonoBehaviour
{
// 出てくる玉の種類(Ball1〜Ball3を入れる)
public GameObject[] ballPrefabs;
public float spawnY = 4f;
public float waitTime = 0.3f;
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);
// 箱の中に収める
float x = Mathf.Clamp(worldPos.x, -3f, 3f);
Vector3 spawnPos = new Vector3(x, spawnY, 0);
// 配列からランダムに1つ選ぶ
int index = Random.Range(0, ballPrefabs.Length);
Instantiate(ballPrefabs[index], spawnPos, Quaternion.identity);
timer = 0f;
}
}
}
  1. HierarchyでBallSpawnerを選択
  2. InspectorのBall Prefabsの左の三角をクリックして開く
  3. Size3と入力してEnter
  4. Element 0 にBall1をドラッグ
  5. Element 1 にBall2をドラッグ
  6. Element 2 にBall3をドラッグ
配列の設定
配列の設定
// 整数の場合:最大値は含まれない
Random.Range(0, 3); // 0, 1, 2 のどれか(3は出ない)
// 小数の場合:最大値も含まれる
Random.Range(0f, 3f); // 0.0 〜 3.0 のどこか

再生してクリックしてみてください。

赤・オレンジ・黄の玉がランダムに出てきて、箱に積み上がります!

ランダムな玉が積み上がる
ランダムな玉が積み上がる

遊んでみると、気になるところが出てきます。物理設定で直せます。

気になること 調整方法
玉が跳ねすぎる PrefabのLinear Dampingを0.5くらいにする
玉が転がり続ける PrefabのAngular Dampingを上げる(1〜3)
玉が落ちるのが遅い Gravity Scaleを1.5〜2にする
積んだ玉がずっと震えている 玉のMassをそろえる(全部1にする)
速い玉が壁をすり抜ける Collision DetectionContinuousに変える

すり抜け対策(Collision Detection)

Section titled “すり抜け対策(Collision Detection)”
症状 原因と対処法
玉が壁をすり抜ける 壁にBox Collider 2Dを付け忘れている
玉が壁の上に乗る Mathf.Clampの範囲を狭くする(±3)
玉が重なって表示される Colliderの大きさが画像と合っていない。付け直す
IndexOutOfRangeException Random.Rangeの最大値が配列の個数より大きい
1種類しか出てこない InspectorのSizeが1のまま。3にする
配列に何も入っていないエラー Element 0〜2 にPrefabをドラッグしたか確認
大きい玉が最初から出る 配列にBall4〜6を入れてしまっている
玉が箱の外に飛び出す 壁のScale Yを大きくする(6以上)

基礎課題全員必須

箱を作って玉を溜める:

  • WallLeftWallRightを作りBox Collider 2Dを付ける
  • Boxオブジェクトで床と壁をまとめる
  • 玉が箱の中に溜まることを確認
  • 最後にCtrl + Sで保存する

標準課題時間があれば

6種類の玉とランダム出現:

  • Ball2Ball6のPrefabを作る
  • それぞれCircle Collider 2Dの大きさを合わせる
  • BallSpawnerを配列に書き換える
  • Ball1Ball3がランダムに出ることを確認

発展課題チャレンジ

遊びやすさを追求する:

  • 物理設定を調整して、いちばん遊びやすい数値を見つける
  • 箱の幅や高さを変えて、難しさがどう変わるか試す
  • 次に出る玉を画面の上に表示してみる
    (ヒント:先にランダムを決めておき、 別のGameObjectのSpriteに設定する)
  • 背景の色や絵を工夫してゲームらしくする

いよいよこのゲームのいちばん大事な部分です。

次回は同じ玉同士がぶつかったら合体して大きくなる処理を作ります。 今日までで一番むずかしいところですが、 ここができるとゲームが一気に面白くなります。