はじめに
前回、いろいろ書きましたが今回からゲーム開発を実際に行っていきます。
現在のゲーム画面はこんな感じです。
本記事は下記のものを実装した記録です。
・自機の移動
やったことは以下の通りです。
# | 実装内容 | 主なスクリプト断片・設定 | 目的/気付き |
---|---|---|---|
1 | Player プレハブを作成 SpriteRenderer と BoxCollider2D を追加 |
- | まずは見た目と衝突枠だけ用意 |
2 | Transform.Translate で移動 |
float inputY = Input.GetAxis("Vertical"); transform.Translate(0, inputY * speed * Time.deltaTime, 0);
|
動くことは確認できたが、物理計算と分離されていて弾や敵との衝突挙動が不自然 |
3 | Rigidbody2D を追加 Body Type を Dynamic に設定 |
Rigidbody2D Gravity Scale = 0
|
物理ベースに乗せ直し、衝突処理を統一 |
4 | FixedUpdate へ移植 |
void FixedUpdate() {
|
物理フレームで速度を与えることで フレーム落ち時も挙動が安定 |
5 | 画面外へのはみ出し防止 カメラ境界を計算して Clamp |
var pos = transform.position;
|
UI や敵が見切れないように調整 |
自機の移動
Player プレハブを作成
まず、自機(Player)を作るための最初のステップをご案内します。
🛠 Step 1:Player プレハブを作成する
Hierarchy ウィンドウで右クリック → Create Empty
→ 名前を Player に変更します。
Player オブジェクトに以下のコンポーネントを追加しましょう:
コンポーネント | 用途 |
---|---|
SpriteRenderer | 自機の見た目(画像)を表示 |
BoxCollider2D | 敵や弾との当たり判定に使う枠 |
🎨 SpriteRenderer には、仮でも良いので画像を設定しておきましょう。
まだ用意がなければ、Unity に標準で入っている「Sprites > Square」などで代用できます。
🎁 例:ここまでできた Player の構成
オブジェクト名 | コンポーネント |
---|---|
Player | SpriteRenderer BoxCollider2D |
✅ これで画面上に「表示され、当たり判定も持つ」自機オブジェクトが完成します。
🚀 次は 移動処理 や 弾の発射 処理を追加していきましょうか?
どこでなにをすればいいか解説してあります。
しかし、プレハブというものが当たり前みたいな顔をして出てきました。
気軽に聞いてみます
プレハブ(Prefab)とは、「再利用できるオブジェクトのテンプレート」のことです。
ゲーム中に何度も使いたいオブジェクト(自機、弾、敵など)を一度作って、保存しておくのに使います。
🛠 プレハブの作り方(自機を例に)
✅ Step 1:Hierarchyに Player を作る
- Unity の Hierarchy ウィンドウで右クリック
- 2D Object > Sprite を選択
- 名前を
Player
に変更 - 見た目の画像(スプライト)を設定
- 必要に応じて以下のコンポーネントを追加:
BoxCollider2D
(当たり判定)Rigidbody2D
(物理挙動や移動用)
✅ Step 2:Project にドラッグしてプレハブ化
- Project ウィンドウで
Prefabs
というフォルダを作成(任意) - Hierarchy の
Player
オブジェクトを Project にドラッグ - 青いキューブのアイコン「Player.prefab」が生成されればOK!
✅ Step 3:プレハブの使い方
- シーンに何度でもドラッグして配置できる
Instantiate(playerPrefab)
で動的に生成できる- Prefab本体を修正すれば、すべてのインスタンスに一括反映
🎉 これで自機のプレハブが完成です!
このあとは「移動スクリプト」や「弾の発射スクリプト」を追加して、プレハブに組み込んでいきましょうか?
プレハブというものをこれで作ることができました。
Transform.Translate で移動
とりあえずで画面に配置してみた自機の移動を実装したいところです。
しかし、実装方法が想像もできないのでまずはChatGPTに質問してみます。
以下のような SimplePlayerMovement.cs を作成して、自機オブジェクトにアタッチしてください。
using UnityEngine;
public class SimplePlayerMovement : MonoBehaviour
{
public float speed = 5f;
void Update()
{
float moveY = Input.GetAxis("Vertical"); // ↑↓キー/WとSキーに対応
transform.Translate(0, moveY * speed * Time.deltaTime, 0);
}
}
🔧 ポイント:
・Input.GetAxis("Vertical")
は、W/Sキーや↑/↓キーの入力を取得します。
・transform.Translate
により、自機を上下方向に移動させます。
⚠️ この方法は「物理演算(Rigidbody)」を使っていないため、衝突や重力との連携が必要な場合は Rigidbody2D
を使う方法に切り替えるとよいです。
Unityの教本を読んでいたおかげでギリ分かります。
上下方向の入力をmoveYに代入してY軸の移動に利用しているっぽいですね。
しかし分からないものもあります。Time.deltaTimeとはなんでしょうか?
🕒 Time.deltaTime とは?
→ 「前のフレームから今のフレームまでにかかった時間(秒数)」 を表します。
例えば:
・60FPS(1秒間に60フレーム)のとき → Time.deltaTime ≒ 0.0167秒
・30FPS のとき → Time.deltaTime ≒ 0.0333秒
🧠 なぜ必要なの?
PCによってフレームレート(処理の速さ)は異なります。
Time.deltaTime を使うと、どんな環境でも同じ速度で動くようにできます。
❌ 使わない場合(不安定な例)
transform.Translate(0, 1, 0);
これは毎フレーム「1」だけ動く処理です。
・60FPS → 1秒間に60回動いて「60」進む
・30FPS → 30回しか動かず「30」しか進まない
→ 高速なPCほど速く進んでしまい、バランスが崩れます。
✅ Time.deltaTime を使うと…
transform.Translate(0, 1 * Time.deltaTime, 0);
60FPS:1回あたり ≒ 0.0167 → 合計で ≒ 1.0
30FPS:1回あたり ≒ 0.0333 → 合計で ≒ 1.0
→ どんなFPSでも約1秒で「1」進むようにできます!
🎯 まとめ
Time.deltaTime を使うことで、
・PCやスマホの性能差に関係なく
・プレイヤーやオブジェクトの移動速度が一定になります。
→ Unityゲームでは「移動・アニメ・タイマー処理」などに欠かせない存在です!
FPSに応じてフレームの秒数を返してくれるものといった感じでしょうか。
transform.Translate(0, moveY * speed * Time.deltaTime, 0); というコードは
"上下のキーを入力すると一定の速度で動くようにしたもの"って感じですかね?
文章にすると楽ですが、素人がコードで1から書けと言われると時間がかかりそうです。
コード | 意味 |
---|---|
Time.deltaTime |
FPSに応じてフレームの秒数を返してくれる |
こんな感じでC#のメモも残していきます。
ここで上下キーを押して確認してみます。
思ってたんとちがう。
画面上でも垂直方向に動いてほしかったのですが、水平に動いてしまいました。
これは自機のRotation(角度)を-90で設定しているせいな気がします。聞いてみましょう。
これは、自機のローカルY軸が画面右を向いている(=Rotation -90°)ためです。
Unity の基本ルールとして、
transform.Translate()
はデフォルトで ローカル軸(Space.Self) に基づいて動きます。
つまり、スプライトが回転していると、移動の方向もその回転の影響を受けてしまいます。
✅ あなたの設定
項目 | 値 | 解釈 |
---|---|---|
自機の向き | Rotation.z = -90° |
ローカルY軸が画面右方向を向いている |
移動処理 | transform.Translate(0, inputY * speed * Time.deltaTime, 0); |
ローカルY方向=画面右に動く |
✅ 対処法(見た目は回転したまま、移動は画面の上下方向)
transform.Translate(0, inputY * speed * Time.deltaTime, 0, Space.World);
- Space.World を指定すると、「ワールド座標系(画面基準)」で移動できます
- これにより、自機が回転していても 画面の上下 方向へまっすぐ移動します
💡 補足
Unityの Transform 系関数(Translate / Rotate / LookAt など)は、Space.Self
(ローカル)と Space.World
(ワールド)を切り替えることで、移動や回転の基準を変更できます。
✅ この知識を活かせば、「回転したスプライトでも見た目を崩さず自然な操作感」を保てますよ!
合っていたようですね。空間依存の軸にすればいいという感じでしょうか。
指示に合った通りスクリプトを一部改変してみます。
transform.Translate(0, inputY * speed * Time.deltaTime, 0);
↓
transform.Translate(0, inputY * speed * Time.deltaTime, 0, Space.World);
これで動かしてみます。
上下キーの入力で垂直方向に動きました!
これで最初は適当に画面に置いただけの自機が
プレハブを持っていて当たり判定もある自機になったようです。
ゲームをやっているとプレイヤーキャラが動くのは当たり前ですが、自分で作って自分の入力で動いているとそれもまた楽しいですね。
Rigidbody2D を追加
自機の基本的な動きができたと思っていたのですが、後になってこれだと駄目だということが分かりました。
というのも敵の実装を進めているときに"敵が自機にぶつかった時にお互いが消滅する"というようなスクリプトを作ったのですが、
"敵が自機にめり込んで何も起きない"という現象が起きました。
これは自機が当たり判定自体は持っているものの、Rigidbody2D を持っていないため、物理エンジンによる衝突処理が行われていないことが原因とのこと。
transform(Transform.Translateやposition)だけで移動を実装すると、
見た目上はちゃんと動きますが、物理エンジンとの連携が取れず、さまざまな問題が発生します。
✅ Transformのみの移動:メリットとデメリット
分類 | 内容 |
---|---|
✅ メリット |
・シンプル:1行で移動できる ・軽量:物理演算が不要で処理が高速 |
❌ デメリット |
|
💡 補足
Unityでは、Rigidbody2D
を持つオブジェクトだけが物理演算やイベントの対象になります。
→ プレイヤーや敵、弾など移動+衝突が重要なものには Rigidbody2D
をつけて、velocity
や MovePosition
を使うのがベストです。
✅ Transform だけで済ませるのは、「背景のスクロール」や「UI演出」など衝突が不要な移動に限るのがおすすめです。