カメラ・背景の設定をしよう

Last-modified: Tue, 02 May 2023 21:01:37 JST (360d)
Top > カメラ・背景の設定をしよう

はじめに

ひつじを動かそう その2の続きです。
前回はひつじの動きを完成させましたが、
今回はカメラ・背景の設定を行ってゲーム画面での見え方を改良していきます。

 

カメラ・背景の設定

 

今回は、

・ゲーム画面の解像度・アスペクト比の調整
・背景の挿入
・カメラのサイズの調整
・カメラ・背景のひつじへの追従の実装

  を行います。

 

ゲーム画面の解像度・アスペクト比の調整

 

ゲーム画面の解像度アスペクト比を調整していきます。
解像度とは縦横のピクセル数、アスペクト比とは縦横の長さの比のことです。
Unity ではこれらの設定が初期では「FreeAspect」という、
各デバイスの画面や Window の大きさにあった形で自動調整される設定になっています。

 

今回のゲームではアスペクト比(画面の縦横比)を16:9にします。

 

Game > FreeAspect > 16:9Aspect をクリック、でできます。

 
FreeAspect.png
 
16-9Aspect.png
 

背景を作る

 

今のままだと背景がブルーバックで味気ないので背景画像を作ります。

 

#download(background.jpg)

 

この画像をダウンロードして、これまでと同様に Assets にドラッグ&ドロップします。
他のオブジェクトと画像のピクセルを揃えるため、Inspector から PixelsPerUnit の数値を 100 から 32 に変更してください。
画像の設定はこれだけです。次はこの画像をゲームオブジェクトにします。
カメラと背景は一緒に動いて欲しいので、背景のゲームオブジェクトはカメラの子要素にします。
(子要素のゲームオブジェクトは、親要素の移動に追従するため。)
Assets にある背景画像を Hierarchy の MainCamera の上にドラッグ&ドロップします。

 
子要素.png
 

これで背景画像はカメラの子要素としてゲームオブジェクト化されます。

 

背景の画像を MainCamera に追加

 

次に、背景を他のオブジェクトより後ろに表示されるようにします。
オブジェクトの表示される順番はレイヤーで調節します。
背景を選択し Inspector > Layer をクリックし、
出てきたメニューから一番下 Add Layer をクリックし Tags & Layers のメニューを出します。
メニューから Sorting Layers で + を押し BackGround のレイヤーを追加し、
Layer0 になるようにドラッグして並べ替えます。
できたら、background の Inspector に戻り、
SpriteRenderer > Additional Setting > Sorting Layers を BackGround に変更します。

 

カメラのサイズを調整する

 

このままでは、背景画像とカメラの大きさが揃わず、
背景画像がはみ出す、あるいはブルーバックが見えてしまいます。
しかし、背景画像は既に他のオブジェクトと解像度を合わせているため引き延ばしたくありません。
そこで、カメラの大きさを背景画像に揃えます。
カメラの大きさは Inspector > Camera > Size から変更できます。
アスペクト比 16:9 におけるカメラの Size は、デフォルトは 5 で解像度 1706.66...×320 となります。
背景画像の解像度が 384×216 なので、比を取って 3.375 (216px/320px × 5) を指定してあげます。
これで、カメラと背景画像の大きさが揃います。

 

カメラ・背景をひつじに追従するように設定する

 

最後に、ひつじがカメラの外に出て行ってしまわないように、
カメラがひつじに追従するようにしたいと思います。
追従には様々な方法がありますが(子要素にするなど)、今回は汎用性の高い、スクリプトを用いた方法で実装します。

 

MainCamera を選択し、AddComponent > New Script からスクリプトを追加します。
スクリプト名は「MoveCamera」などとしておきます。
スクリプトを書く前に追従の仕様を考えておきます。
スクリプトでの実装なのでいくらでもこだわることはできますが、ここでは最も単純な仕様

・ひつじがカメラの中心に来るように追従する

とします。

 

この仕様を実現するには、

処理1 ひつじの座標を取得する
処理2 カメラの座標を取得したひつじの座標と同じにする

のような処理を毎フレーム行うことが考えられます。

 

ひつじの座標を取得するには、まずはひつじのゲームオブジェクトを取得する必要がありますが、
Find() の処理には時間がかかるため、Update() で毎フレーム Find() を使っていると動作がもたつきます。
そこで、Start() の時に一回だけ Find() して、private 変数にひつじのゲームオブジェクトの参照先を保存しておきます。

 
  1. // 略
  2.  
  3. public class MoveCamera : MonoBehaviour
  4. {
  5.     //ひつじの参照先を保存しておく変数
  6.     private GameObject sheep;
  7.  
  8.     void Start()
  9.     {
  10.         // ひつじのゲームオブジェクトを取得し保存用の変数に代入
  11.         sheep = GameObject.Find("hitsuji_dot");
  12.     }
  13.  
  14.     //略
  15.  
  16. }

ここまでの考えを実際にスクリプトに書きました。
次に、ひつじのゲームオブジェクトから座標を取り出し、カメラの座標をそれと同じにします。
この処理は毎フレーム行いたいので、Update() の中に書きます。
座標は Transform コンポーネントの position で管理されています。

transform は GetComponent で取得しなくても、GameObject.transform のように参照できる特別なコンポーネントです。
もちろん、前回のように GetComponent を使ってアクセスすることもできます。

 

これでも動きそうですが、このまま実行すると画面に何も表示されなくなります。
この原因は、3Dで考えるとわかります。作っているのは2Dゲームですが、Unity のカメラは2Dのゲーム画面を z 方向から俯瞰しています。
プリントを上から撮影しているのと同じです。映すものとカメラが同じ場所にあっては、なにも表示されないのも納得。
ひつじを中心に映すには、ひつじと x, y 座標を同じにして、z 座標を上にずらします。

 
  1. public class MoveCamera : MonoBehaviour
  2. {
  3.  
  4.     // 略
  5.  
  6.     void Update()
  7.     {
  8.         // ひつじの座標を取得
  9.         Vector3 pos = sheep.transform.position;
  10.         // ひつじの座標のままだと 俯瞰して見られないので、z座標を-10だけずらす
  11.         this.transform.position = pos + new Vector3(0.0f, 0.0f, -10f);
  12.     }
  13. }

これでカメラの追従の完成です。