見出し画像

【Unity】一目でわかる! カメラの複数アスペクト比対応3D(全7パターン)

こんにちは、鈴木ジョンです。
今回は、カメラの複数アスペクト比対応についてまとめたので公開します。

今回の記事は、3D用のカメラを対象にしています。
(カメラのProjectionの設定がPerspective)

2D用のカメラ(Orthographic)は次回の記事で。
簡単にできる! カメラの複数アスペクト比対応2D(全7パターン)

はじめに

パターンごとに比較画像とサンプルコードを用意しました。サンプルコードはカメラにアタッチするなどして使ってください。すべて9:16をベースのアスペクト比としています。

 

【デフォルト】 高さ固定+幅可変

画像1

どの端末でも高さ方向の表示量は同じです。アスペクト比によって、幅方向の表示量が増減します。

デフォルトなのでスクリプトは必要ありません。

 

幅固定+高さ可変

画像2

どの端末でも幅方向の表示量が同じです。アスペクト比によって、高さ方向の表示量が増減します。

public Camera camera;
public float baseWidth = 9.0f;
public float baseHeight = 16.0f;

void Awake()
{
    // 幅固定+高さ可変
    var scaleWidth = (Screen.height / this.baseHeight) * (this.baseWidth / Screen.width);
    this.camera.fieldOfView = Mathf.Atan(Mathf.Tan(this.camera.fieldOfView * 0.5f * Mathf.Deg2Rad) * scaleWidth) * 2.0f * Mathf.Rad2Deg;
}

 

ベース維持

画像3

どの端末でもベースの9:16の範囲は必ず見えます。アスペクト比によっては、上下もしくは左右の表示量が増えます。

public Camera camera;
public float baseWidth = 9.0f;
public float baseHeight = 16.0f;

void Awake()
{
    // ベース維持
    var scaleWidth = (Screen.height / this.baseHeight) * (this.baseWidth / Screen.width);
    var scaleRatio = Mathf.Max(scaleWidth, 1.0f);
    this.camera.fieldOfView = Mathf.Atan(Mathf.Tan(this.camera.fieldOfView * 0.5f * Mathf.Deg2Rad) * scaleRatio) * 2.0f * Mathf.Rad2Deg;
}

 

アスペクト比固定

画像4

どの端末でも9:16の領域が必ず見えます。アスペクト比によっての見え方の違いはなく、範囲外は見えません。

public Camera camera;
public float baseWidth = 9.0f;
public float baseHeight = 16.0f;

void Awake()
{
    // アスペクト比固定
    var scale = Mathf.Min(Screen.height / this.baseHeight, Screen.width / this.baseWidth);
    var width = (this.baseWidth * scale) / Screen.width;
    var height = (this.baseHeight * scale) / Screen.height;
    this.camera.rect = new Rect((1.0f - width) * 0.5f, (1.0f - height) * 0.5f, width, height);
}

 

高さ固定+幅上限あり

画像5

どの端末でも高さ方向の表示量は同じです。アスペクト比によっては、幅方向の表示量は減りますが、範囲外が見えることはありません。

public Camera camera;
public float baseWidth = 9.0f;
public float baseHeight = 16.0f;

void Awake()
{
    // 高さ固定+幅上限あり
    var scale = Mathf.Min(Screen.height / this.baseHeight, Screen.width / this.baseWidth);
    var width = (this.baseWidth * scale) / Screen.width;
    this.camera.rect = new Rect((1.0f - width) * 0.5f, 0, width, 1.0f);
}

 

幅固定+高さ上限あり

画像6

どの端末でも幅方向の表示量が同じです。アスペクト比によっては、高さ方向の表示量は減りますが、範囲外が見えることはありません。

public Camera camera;
public float baseWidth = 9.0f;
public float baseHeight = 16.0f;

void Awake()
{
    // 幅固定+高さ上限あり
    var scale = Mathf.Min(Screen.height / this.baseHeight, Screen.width / this.baseWidth);
    var height = (this.baseHeight * scale) / Screen.height;
    this.camera.rect = new Rect(0, (1.0f - height) * 0.5f, 1.0f, height);

    var scaleWidth = (Screen.height / this.baseHeight) * (this.baseWidth / Screen.width);
    var scaleRatio = Mathf.Min(scaleWidth, 1.0f);
    this.camera.fieldOfView = Mathf.Atan(Mathf.Tan(this.camera.fieldOfView * 0.5f * Mathf.Deg2Rad) * scaleRatio) * 2.0f * Mathf.Rad2Deg;
}

 

フィット

画像7

範囲内が常に表示されます。常に幅方向か高さ方向のどちらかにフィットするため、範囲外が見えることはありません。

アスペクト比以外の端末では幅方向か高さ方向のどちらかの表示量が減ります。

public Camera camera;
public float baseWidth = 9.0f;
public float baseHeight = 16.0f;

void Awake()
{
    // フィット
    var scaleWidth = (Screen.height / this.baseHeight) * (this.baseWidth / Screen.width);
    var scaleRatio = Mathf.Min(scaleWidth, 1.0f);
    this.camera.fieldOfView = Mathf.Atan(Mathf.Tan(this.camera.fieldOfView * 0.5f * Mathf.Deg2Rad) * scaleRatio) * 2.0f * Mathf.Rad2Deg;
}

 

最後に

以上、7パターンのカメラの複数アスペクト比対応についてのまとめでした。
少ないコードで対応できるので設定自体は難しくはありませんが、計算式がちょっと複雑なので、ぜひコピペして使ってください。

パターンごとに見え方が違ってくるので、開発しているものに合わせて適切なものを選んで使ってください。


最後までご一読ありがとうございました。
もしよかったらフォロー、スキ、コメントで応援の方とプロフィール欄からTwitterのフォローをお願いします。

この記事が気に入ったらサポートをしてみませんか?