37
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Unity】モバイルゲームを全画面で全機種対応させる

Last updated at Posted at 2023-02-20

○はじめに

前回、固定解像度で各機種対応させましたが、黒い帯だったり狭いゲーム画面だったり、ちょっとダサいので、今回は全解像度に対応させて、全画面かつ全機種でプレイできるようにします

前回の記事↓

○実行結果

こんな感じになります。
UIは機種に応じて場所を変化し、ゲームオブジェクトは画面内に収まるようにしています。
また、UIがiPhone12などの上部分のやつ(ノッチ)に隠れないような設定もしています。

mobile_aspect_2.gif

また、実機で試してみると、ちゃんとノッチを避けてUIが配置されています。(色々あって上のGifとは構成が異なってます。ややこしくてすいません)

android_全画面.jpg

●リポジトリ

リポジトリです。Androidを持っている方は、ぜひ実機テストしてみてください。
※Unityバージョンは2021.3.8f1です。
インストールするのが面倒な方は、DeviceSimulatorを別途でインポートしてください。

○説明

●範囲内に収めるカメラ

CameraコンポーネントのorthographicSizeを機種の解像度に合わせて動的に変更しています。
現在の画面のアスペクト比と目標のアスペクト比から、orthographicSizeを求めます。

目標のアスペクト比:目標アス比のときのカメラサイズ = 現在のアスペクト比:orthographicSize

アスペクト比は、縦の解像度/横の解像度 で求まります。

image.png

●UI

RectTransformanchorを、解像度とDeviceSimulatorのSafeAreaから求めます。
(DeviceSimulatorをインポートする必要があります。)

image.png

●Canvas

CanvasコンポーネントのRenderTypeScreenSpace - Cameraにして、Unityを再起動すると、SafeAreaanchoredPosition(LeftとかRight)がすべてNaNと表示されてしまいます。

image.png

シーン切り替えによって解消します。随時バグ修正します。
(原因や対処法があればぜひコメントくださいませ…!!)

また、CanvasScalerコンポーネントは、ScaleWitfhScreenSizeに設定して、ReferenceResolutionに目的の解像度を設定してください。

image.png

○コード

●CameraResizer

機種に合わせてorthographicSizeを変更します。

[ExecuteAlways]
public class CameraResizer : MonoBehaviour
{
    [SerializeField] Vector2 targetResolution;
    [SerializeField] float targetOrthographicSize = 5;

    Camera camera;

    private void Start()
    {
        camera = GetComponent<Camera>();
    }

    private void Update()
    {
        ResizeCameraOrthographicSize();
    }

    void ResizeCameraOrthographicSize()
    {
        var currentResolution = new Vector2(Screen.width, Screen.height);
        var targetAspect = targetResolution.x / targetResolution.y;
        var currentAspect = currentResolution.x / currentResolution.y;

        if (currentAspect >= targetAspect) {
            camera.orthographicSize = targetOrthographicSize;
            return;
        }

        var orthoGraphicSize = targetOrthographicSize * (targetAspect / currentAspect);
        camera.orthographicSize = orthoGraphicSize;
    }
}

Point💡

  • [ExecuteAlways]属性で、再生していなくても更新処理をします。
  • targetRatio:targetCameraSize = currentRatio:size(比例式)でorthographicSizeを求めます。(ここ↓)
.cs
var size = (targetCameraSize * currentRatio) / targetRatio;

●SetSafeArea

RectTramsformanchorを変更します

SetSafeArea.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteAlways,RequireComponent(typeof(RectTransform))]
public class SetSafeArea : MonoBehaviour
{
	RectTransform rect;

	private void Awake()
	{
		rect = GetComponent<RectTransform>();
	}

	private void Update()
	{
		if (UnityEngine.Device.SystemInfo.deviceType == DeviceType.Handheld) {
			var area = Screen.safeArea;
			var resolution = Screen.currentResolution;

			rect.sizeDelta = Vector2.zero;
			rect.anchorMin = new Vector2(area.xMin / resolution.width, area.yMin / resolution.height);
			rect.anchorMax = new Vector2(area.xMax / resolution.width, area.yMax / resolution.height);
		}

		else {
			rect.anchorMin = Vector2.zero;
			rect.anchorMax = Vector2.one;
		}
	}
}

Point💡

  • if文の箇所で、デバイスの種類がスマホだったら(Simulatorビューがアクティブだったら)実装するようにしています。(ゲームビューでもセーフエリアを適用すると、UI表示がおかしくなるため。)
    • その際、SystemInfonamespaceUnityEngine.Deviceにしないと、Editor上では正常に判定されません。(詳細)
  • SafeArea/解像度anchorを求めます。

○さいごに

Device Simulator、すごい便利です。
モバイルゲーム開発では必須といっても過言ではないかもですね!!!

また、UIについては、Androidに備わっている画面分割という機能にも対応しています。↓

HiroshiAbe.gif

折り畳みスマホの普及などで、画面分割機能は今後頻繁に使われそうなので、カメラについても画面分割に対応していきたいです。

●参考サイト

37
41
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
41

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?