ひとりでのアプリ開発 - fineの備忘録 -

ひとりでアプリ開発をするなかで起こったことや学んだことを書き溜めていきます

20220329162023

Unity - 2D:背景の作り方、ループのさせ方、カメラをキャラクターに追従させる -

初めに

 今回は、背景の設定方法やキャラクターに動きに合わせて背景を自動でループさせる方法について、まとめます。

準備

 背景として使う画像を事前に用意しましょう。
 本記事では、次のAssetに入っている背景画像を使用します。

assetstore.unity.com

 Asset Storeからダウンロードし、インポートすれば使えるようになります。Asset Storeの使い方は次の記事をご覧ください。

fineworks-fine.hatenablog.com

注意点

 用意する背景画像の縦横比は操作画面と等しくなるようにしておきましょう。

背景の設定方法

 背景の設定方法は次の通りです。

  • Canvasの子オブジェクトとして、Imageを作成する

 Hierarchyで右クリック→UI→Imageをクリック

  • CanvasのRender ModeをScreen Space - Camera - に変更する


  • Render CameraにMain Cameraをドラッグ&ドロップする

  • Imageに背景となる画像をドラッグ&ドロップする

  • Imageのサイズを合わせる

 Imageのサイズを合わせましょう。少なくとも画面サイズよりは大きくしましょう。


 これで、背景を設定できました。ノベルゲームなどキャラクターが動かないゲームであれば、これでよいでしょう。

キャラクターが動く場合

 キャラクターが動く場合、背景を動かす必要があります。いくつか方法がありますので、まとめておきます。キャラクターを操作できるようにする方法については、こちらの記事をご覧ください。

fineworks-fine.hatenablog.com
fineworks-fine.hatenablog.com
fineworks-fine.hatenablog.com

背景はうごかさない場合

 Main Cameraをキャラクターの子オブジェクトにします。すると、キャラクターは常に画面中央にきます。背景はキャラクターに合わせて動くため、画面上では背景に変化はありません。

背景をループさせる場合

 背景をループさせて、キャラクターの動きに合わせて背景が動いて見えるようにします。

  • 背景をSpriteとして、生成する(Imageとしてもできますが、次でアタッチするスクリプトを少し修正する必要があります)
  • 次のスクリプトを作成し、背景にアタッチする
using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// 【背景のコントロール用クラス】
///     背景は3枚、カメラから見切れたら回り込む
/// </summary>
public class BackGroundController : MonoBehaviour {

    // 背景の枚数
    public int spriteCount = 1;  //Insprctorから手入力できます
    // 背景が回り込み
    float rightOffset = 1.6f;  //微調整してください
    float leftOffset = -0.6f;  //微調整してください

    Transform bgTfm;
        SpriteRenderer mySpriteRndr;
        float width;

        void Start () {
            bgTfm = transform;
            mySpriteRndr = GetComponent<SpriteRenderer>();
            width = mySpriteRndr.bounds.size.x;
        }


        void Update () {
            // 座標変換
            Vector3 myViewport = Camera.main.WorldToViewportPoint(bgTfm.position);

            // 背景の回り込み(カメラがX軸プラス方向に移動時)
            if (myViewport.x < leftOffset) {
                bgTfm.position += Vector3.right * (width * spriteCount);
            }
            // 背景の回り込み(カメラがX軸マイナス方向に移動時)
            else if (myViewport.x > rightOffset) {
                bgTfm.position -= Vector3.right * (width * spriteCount);
            }
        }
    }
  • 背景の数を複製して増やし、Sprite Countの数字を入力する

 今回は3枚に複製しました。

  • 各背景がぴったりくっつくように移動させる
  • 背景の描画順を変える

 場合によっては、背景が他のオブジェクトの前に来ていることがあります。描画順を変えて一番後ろに表示されるようにします。
 Sprite RendererのOrder in Layerで描画順を設定できます。数字が大きいほうが前、小さいほうが後ろに表示されます。

  • キャラクターが中心に来るように、Main Cameraに次のスクリプトをアタッチし、キャラクターを取得する

 今回は、背景をスクリプトから処理するため、Main Cameraの子オブジェクトにしないほうがよいです。そのため、カメラがキャラクターを追従するように次のスクリプトをMain Cameraにアタッチします。

using UnityEngine;
using System.Collections;

public class CameraWork : MonoBehaviour {

    // 変数の定義
    private Transform target;
    public GameObject Player;  //Inspectorから取得してください

    // シーン開始時に一度だけ呼ばれる関数
    void Start(){
        // 変数にPlayerオブジェクトのtransformコンポーネントを代入
        target = Player.transform;
    }

    // シーン中にフレーム毎に呼ばれる関数
    void Update () {
        // カメラのx座標をPlayerオブジェクトのx座標から取得y座標とz座標は現在の状態を維持
        transform.position = new Vector3(target.position.x, transform.position.y, transform.position.z);
    }
}

 今回のスクリプトでは、キャラクターに合わせてy軸方向には画面が動きません。場合に合わせてスクリプトを修正しましょう。

  • 実行しながらBackGroundControllerのOffsetを微調整する

 Spriteのサイズや背景の初期位置によって、Offsetを微調整する必要があります。(transformを変える瞬間が画面に移り、点滅します。)数値を変えて問題なく動くように調整します。

  • 完成

最後に

 背景の作り方やループのさせ方とキャラクターに合わせてカメラを追従させる方法を解説いたしました。キャラクター、背景、Tilemapによりかなり横スクロールアクションゲームに近づいたのではないでしょうか。あとは、敵キャラや装飾、ゴールなどを追加すればひとまず完成といってよいと思います。