スポンサーリンク
Unity C#・スクリプト実装

【Unity】背景を無限スクロールさせる方法|2Dゲームで使える簡単実装を初心者向けに解説

Unity C#・スクリプト実装

ランニングゲームやシューティングゲームを作っていると、「背景をずっと動かして、ステージが続いているように見せたい」と思う場面があります。

ただ、Unityで背景を無限スクロールさせようとすると、最初は少し迷いやすいです。

  • 背景画像は何枚用意すればいいのか
  • どの座標まで動かしたら戻せばいいのか
  • 背景の切れ目や隙間をどう防ぐのか
  • スクリプトをどこに付ければいいのか

特に、背景を本当に無限に生成しようとすると、処理が複雑になったり、不要なオブジェクトが増えたりしやすくなります。

2Dゲームの背景スクロールなら、まずは複数枚の背景を並べて、画面外に出たものを反対側へ戻す方法から覚えるのがおすすめです。

この方法を使えば、少ないオブジェクトで背景が続いているように見せられます。縦スクロールのシューティングゲームや、横スクロールのランナーゲームにも応用しやすいです。

ここでは、背景を動かす基本の考え方から、配置手順、C#スクリプト、隙間が出たときの確認ポイントまで、実装でつまずきやすい部分を順番に整理していきます。

全くUnityを触ったことがないという方はコチラの記事から見てみて下さい!


Unityで背景を無限スクロールさせる方法

Unityで背景を無限スクロールさせるなら、背景画像を複数枚並べて動かし、画面外に出た背景を反対側へ戻す方法が扱いやすいです。

たとえば縦スクロールの2Dシューティングなら、背景を上・中央・下のように3枚並べます。その3枚を下方向へ動かし続けて、一番下まで移動した背景を上側へ戻します。

見た目としては背景がずっと流れているように見えますが、実際には同じ背景オブジェクトを何度も再利用しています。

今回作る無限スクロール背景

今回の実装では、次のような構成を想定します。

  • 2Dゲーム用の背景画像を使う
  • 背景オブジェクトを3枚配置する
  • 背景をY方向にスクロールさせる
  • 一定位置まで移動したら上側へ戻す
  • スクロール速度はInspectorから調整できるようにする

最初から複雑な仕組みにする必要はありません。まずは「動かす」「画面外に出たら戻す」の2つに分けて考えると、かなり理解しやすくなります。

背景3枚ループ方式がおすすめな場面

背景3枚ループ方式は、同じ背景が連続して流れるタイプのゲームに向いています。

向いているゲーム理由
縦スクロールシューティング背景が一定方向へ流れ続けるため
ランナーゲームステージが続いているように見せやすいため
シンプルな2Dアクション背景演出だけを軽く追加しやすいため

一方で、背景ごとに違う地形やギミックを生成したい場合は、この方法だけでは足りないことがあります。その場合は、背景スクロールではなく、ステージ生成やオブジェクトプールを使う設計を考えるとよいです。

今回使用するサンプルコード

まずは、背景を下方向へ動かして、一定位置まで来たら上へ戻す基本コードです。

using UnityEngine;

public class BackGround : MonoBehaviour
{
    [SerializeField] private float speed = 1f;

    private void Update()
    {
        transform.position -= new Vector3(0f, Time.deltaTime * speed, 0f);

        if (transform.position.y <= -19.17f)
        {
            transform.position = new Vector3(transform.position.x, 19.17f, transform.position.z);
        }
    }
}

-19.17f19.17fの数値は、使う背景画像のサイズや配置によって変わります。自分のプロジェクトでそのまま合わない場合は、背景の高さに合わせて調整してください。




背景を無限スクロールさせる仕組み

背景の無限スクロールは、背景を新しく作り続ける仕組みではありません。

基本は、画面外に出た背景を反対側へ移動させて、同じ背景を何度も使い回します。これにより、プレイヤーから見ると背景がずっと続いているように見えます。

画面外へ出た背景を再利用する

たとえば背景を下方向へスクロールさせる場合、背景のY座標が一定値より下がったら、その背景を上側へ戻します。

流れとしては、次のようになります。

  1. 背景を3枚、縦に並べる
  2. すべての背景を下方向へ動かす
  3. 一番下まで移動した背景を上側へ戻す
  4. 同じ処理を繰り返す
画面外へ出た背景を再利用する解説スクリーンショット

このとき大切なのは、「どこまで下がったら戻すか」と「どこへ戻すか」です。この2つの座標が背景画像の高さと合っていないと、隙間が見えたり、背景が急に飛んだように見えたりします。

背景の枚数は画像サイズで決める

今回の例では背景を3枚使いますが、必ず3枚でなければいけないわけではありません。

背景画像がカメラの表示範囲より十分に大きい場合は2枚でも成立することがあります。逆に、画像が小さかったり、カメラの表示範囲が広かったりする場合は、3枚以上必要になることもあります。

状態判断
スクロール中に隙間が見えない背景枚数と配置はおおむね問題なし
背景の切れ目が一瞬見える背景同士の間隔やリセット位置を見直す
背景が足りず画面外が見える背景枚数を増やすか画像サイズを調整する

最初は3枚で作ると、上・中央・下の位置関係が見えやすく、調整もしやすいです。動作確認で問題がなければ、そのまま使って大丈夫です。




背景を無限スクロールする実装手順

ここからは、実際に背景を無限スクロールさせる手順を見ていきましょう。

今回の方法は、背景画像を複数枚並べて同じスクリプトを付けるだけなので、Unity初心者でも取り組みやすい構成です。

背景画像をインポートする

まずは背景として使用する画像を用意します。

背景がループする仕組みなので、画像の上下(または左右)が自然につながるシームレスな画像を選ぶと違和感が出にくくなります。

画像を用意したら、UnityのProjectウィンドウへドラッグ&ドロップしてインポートしてください。

2Dゲームの場合は、InspectorでTexture Typeが「Sprite (2D and UI)」になっていることも確認しておきましょう。

背景オブジェクトを3枚配置する

次に、背景画像をHierarchyへ配置します。

背景オブジェクトを3枚配置するスクリーンショット

配置した背景を選択した状態で、Ctrl + Dを押して複製し、合計3枚用意します。

今回は次のような配置を例にします。

  • 背景A:Y = 19.17
  • 背景B:Y = 0
  • 背景C:Y = -19.17

この数値はサンプル画像に合わせた例です。

実際には背景画像の高さによって変わるため、自分の画像サイズに合わせて調整してください。

背景同士が途切れないように配置する

背景を配置するときは、上下の画像がぴったり接するように並べます。

このとき少しでも隙間があると、スクロール中に背景の切れ目が見えてしまいます。

Sceneビューを拡大しながら確認し、背景同士が正しくつながっているかチェックしましょう。

プロジェクトによっては、わずかに重なるように配置したほうが隙間対策になる場合もあります。

スクリプトを作成して背景にアタッチする

Projectウィンドウで右クリックし、以下の手順でスクリプトを作成します。

  1. Create
  2. C# Script
  3. 名前を「BackGround」に変更

作成したスクリプトを開き、サンプルコードを入力します。

保存したら、作成したスクリプトを背景A・背景B・背景Cのすべてにドラッグ&ドロップしてください。

1枚だけに付けるのではなく、スクロールさせる背景すべてに同じスクリプトを設定します。

スクロール速度を調整する

スクリプトをアタッチすると、InspectorにSpeed項目が表示されます。

この値を変更すると背景の移動速度を調整できます。

  • 0.5:ゆっくり流れる
  • 1.0:標準的な速度
  • 3.0以上:高速スクロール

実際にゲームを再生しながら調整するのがおすすめです。

ランナーゲームなら少し速め、落ち着いた雰囲気のゲームなら遅めに設定すると、ゲーム全体の印象に合わせやすくなります。

もし背景だけでなくキャラクターや敵も動くゲームなら、背景速度とのバランスも確認しておくと自然な見た目になります。




サンプルコードを初心者向けに解説

背景を無限スクロールさせるコードは短いですが、いくつか大切な考え方が入っています。

特に見ておきたいのは、Time.deltaTimetransform.positionif文による座標リセットです。

Time.deltaTimeを使う理由

Time.deltaTimeは、前のフレームから今のフレームまでにかかった時間を表す値です。

背景を動かすときにTime.deltaTimeを使うと、パソコンやスマホの処理速度が違っても、できるだけ同じような速さで動かしやすくなります。

transform.position -= new Vector3(0f, Time.deltaTime * speed, 0f);

もしTime.deltaTimeを使わずに毎フレーム同じ量だけ動かすと、フレームレートが高い環境では速く動き、低い環境では遅く動く可能性があります。

transform.positionで背景を移動する

transform.positionは、ゲームオブジェクトの位置を表します。

今回のコードでは、Y方向の値を少しずつ減らして、背景を下へ動かしています。

transform.position -= new Vector3(0f, Time.deltaTime * speed, 0f);

new Vector3(0f, Time.deltaTime * speed, 0f)の真ん中の値がY方向です。

つまり、X方向とZ方向は動かさず、Y方向だけを変えています。

横スクロールにしたい場合は、YではなくX方向を動かします。

transform.position -= new Vector3(Time.deltaTime * speed, 0f, 0f);

このように、移動させる軸を変えるだけで、縦スクロールにも横スクロールにも応用できます。

if文で背景を上へ戻す

背景が一定位置まで下がったら、if文で判定して上側へ戻します。

if (transform.position.y <= -19.17f)
{
    transform.position = new Vector3(transform.position.x, 19.17f, transform.position.z);
}

この処理がないと、背景は下へ移動し続けて、いずれ画面から消えてしまいます。

無限スクロールに見せるためには、画面外へ出たタイミングで自然に反対側へ戻すことが大切です。

座標リセット値は固定ではない

サンプルコードでは、-19.17fまで下がったら19.17fへ戻しています。

ただし、この数値はすべてのプロジェクトで使える固定値ではありません。

背景画像の高さ、カメラの表示範囲、SpriteのPixels Per Unitなどによって、ちょうどよい値は変わります。

判断の目安は、スクロール中に背景の隙間が見えず、ループした瞬間も不自然に見えないことです。

  • 背景が早く戻りすぎる場合:リセットする下側の値をもう少し下げる
  • 背景が遅く戻りすぎる場合:リセットする下側の値をもう少し上げる
  • 戻った位置に隙間がある場合:上側の戻し先を調整する

数値だけを覚えるより、「背景の高さに合わせて戻す」と考えると、別の画像を使うときにも対応しやすくなります。




背景の繋ぎ目や隙間を防ぐコツ

背景の無限スクロールは実装自体よりも、「ループしていることが分からない自然な見た目」を作るほうが難しい場合があります。

コードが正しく動いていても、背景の切れ目や隙間が見えると違和感が出てしまいます。

ここでは、実際によくある問題と対策を紹介します。

背景画像はシームレス素材を使う

無限スクロールでは、背景が何度も繰り返し表示されます。

そのため、画像の上下が自然につながるシームレスな背景を使うことが重要です。

例えば、空や宇宙空間、雲、森などの背景は比較的ループさせやすいです。

反対に、大きな建物や特徴的なオブジェクトが配置された背景は、同じ模様が繰り返されていることが目立ちやすくなります。

背景画像を選ぶ際は、画像の上端と下端が自然につながるかを確認しておきましょう。

背景同士を少し重ねて配置する

背景をぴったり配置したつもりでも、実行すると細い線のような隙間が見えることがあります。

これは画像サイズや描画時の誤差が原因になることがあります。

そのような場合は、背景同士をほんの少しだけ重ねて配置すると改善することがあります。

例えば、本来19.17離して配置するところを、19.15や19.16程度に調整して確認してみてください。

ただし、重ねすぎると今度は背景が二重に見える場合があるため、少しずつ調整するのがおすすめです。

Order in Layerで描画順を調整する

背景がキャラクターより前に表示される場合は、Sprite Rendererの描画順を確認しましょう。

2Dゲームでは、Z座標だけで描画順が決まるとは限りません。

Sprite RendererのOrder in Layerが優先されることが多いためです。

背景のOrder in Layerを「-1」や「-10」などの小さい値に設定しておくと、プレイヤーや敵キャラクターより後ろに表示しやすくなります。

Layerや描画順について詳しく知りたい場合は、こちらの記事も参考になります。

スクロール中に確認すべきポイント

実装が終わったら、ゲームを再生して次のポイントを確認してみてください。

  • 背景の切れ目が見えていないか
  • 背景が一瞬消えていないか
  • ループした瞬間が分からないか
  • キャラクターより前に表示されていないか
  • スクロール速度がゲームに合っているか

特にループ位置は、実際に数十秒ほど動かして確認するのがおすすめです。

数回ループさせて違和感がなければ、背景の配置やリセット座標はおおむね適切だと判断できます。




背景スクロールでよくある失敗と対処法

背景スクロールがうまく動かないときは、コードだけでなく、背景の配置やInspector設定も一緒に確認すると原因を見つけやすいです。

ここでは、実装中によく起きる失敗をまとめます。

背景がループしない

背景が下へ流れたまま戻ってこない場合は、if文の条件を確認しましょう。

if (transform.position.y <= -19.17f)
{
    transform.position = new Vector3(transform.position.x, 19.17f, transform.position.z);
}

背景のY座標が-19.17fまで到達していない場合、この処理は実行されません。

確認するときは、Play中に背景オブジェクトを選択し、InspectorのPosition Yがどこまで下がっているかを見ると分かりやすいです。

背景に隙間ができる

スクロール中に背景の隙間が見える場合は、背景同士の配置間隔か、リセット後の戻し先が合っていない可能性があります。

  • 背景画像の高さと配置間隔が合っているか
  • 背景同士が少し離れていないか
  • リセット後のY座標が上側の位置に合っているか

まずはSceneビューで背景の端を確認し、必要なら少しだけ重ねて配置してみてください。

動きが速すぎる・遅すぎる

背景の速度が合わない場合は、InspectorのSpeedを調整します。

最初は1前後から試すと調整しやすいです。速すぎると背景の繰り返しが目立ちやすくなり、遅すぎるとゲームの動きと合わないことがあります。

プレイヤーや敵の移動速度と一緒に見ながら、自然に感じる速度を探してみましょう。

背景が表示されない

背景が見えない場合は、スクリプトではなく表示設定が原因になっていることもあります。

  • Sprite Rendererが有効になっているか
  • カメラの表示範囲内に背景があるか
  • Order in Layerが低すぎて別オブジェクトに隠れていないか
  • 背景オブジェクトのScaleが小さくなっていないか

特に、カメラ位置と背景のZ座標がずれていると、Sceneビューでは見えているのにGameビューでは表示されないことがあります。

表示まわりで詰まった場合は、こちらも参考になります。




まとめ

Unityで背景を無限スクロールさせるときは、背景を新しく作り続けるのではなく、画面外に出た背景を反対側へ戻して再利用します。

まずは、背景を3枚ほど並べて、同じスクリプトで一定方向へ動かす方法から試すと作りやすいです。

  • 背景画像を複数枚並べる
  • Time.deltaTimeを使って一定速度で動かす
  • 画面外に出た背景を反対側へ戻す
  • 背景の高さに合わせてリセット座標を調整する
  • 隙間や描画順をGameビューで確認する

特に大切なのは、サンプルコードの数値をそのまま覚えることではなく、「背景のサイズに合わせて戻す位置を決める」という考え方です。

背景の切れ目が見えず、ループした瞬間も自然に見えるなら、無限スクロールの基本はうまくできています。

慣れてきたら、横スクロールに変えたり、ランナーゲームの背景演出に使ったりして、自分のゲームに合わせて調整してみてください。

無限ランゲーム全体の作り方を知りたい場合は、こちらの記事も参考になります。


※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。

※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。

スポンサーリンク