sh1’s diary

プログラミング、読んだ本、資格試験、ゲームとか私を記録するところ

Unity スマートフォン(複雑なアスペクト比)対応とレスポンシブ UI の基本

この記事は、「medium - Building a Responsive UI (Unity)」の記事を個人的に意訳し、最後に補足を加えたものです。(正確な翻訳ではないし、画像も自分で試行錯誤の際に作り直しています。ご注意ください)1


Building a Responsive UI (Unity)

例を通じて、Unity のレスポンシブ UI を作成する方法を探ります。レスポンシブであるということは、UI が様々な画面サイズ・密度の変化に適切に対応することを意味します。


Canvas Setup(キャンバスの仕組み)

新しい 3D プロジェクトを作成して、Canvas を追加して、キャンバスの四隅に色付きのボタン(100 x 100 ピクセル)を四隅に設定します。

f:id:shikaku_sh:20200131183555p:plain:w400
四隅にボタンを設置した例

ウィンドウのサイズがリサイズされたときの最初の問題は、四隅の色付きのボタンが見切れることです。

これは、ゲームウィンドウに合わせて表示されているキャンバスの中心に対してアンカーされているために起こる問題です。たとえば、赤いボタンは中心からみて、左方向に 200 px 上方向に 125 px のところで固定されています。

f:id:shikaku_sh:20200131184050g:plain:w400
画面サイズによって、ボタンが見切れてしまう

Anchors

最初にやるべき修正(変更)点は、ボタンをキャンバスのそれぞれの角に固定することです。ボタンの Rect Transform コンポーネントを変更します。赤いボタンは、アンカーの設定を「左上」に切り替え、左上の隅から (75, -75) のところに配置します。

f:id:shikaku_sh:20200131184623p:plain:w600
アンカーの設定例

次(以下)からの問題は、ボタンがウィンドウ内で不釣り合いな大きさを占めることです。

f:id:shikaku_sh:20200131184203g:plain:w400
ボタンは見切れないもののサイズが変わらないから……(邪魔になる)

Canvas Scaler

ウィンドウに合わせてボタンを適切にスケーリングするには、キャンバスの Canvas Scaler コンポーネントを使用します。UI Scale Mode のデフォルト値 Constant Pixel Size から、Scale with Screen Size に変更します。

f:id:shikaku_sh:20200131184845p:plain:w400
Canvas の設定例

ボタンが相対的に小さく表示されているとすぐに気づきます。何が起こったのかを理解しましょう。

f:id:shikaku_sh:20200131184956g:plain:w400
相対的にボタンサイズが変化するようになった!

まず、Canvas Scalar のデフォルトの解像度が 800 x 600 であることに気づくでしょう。次に、Screen Match Mode のデフォルトの設定値が Width or Height で、Match のデフォルト値が「0」に設定されていることに気づくでしょう。(これは、あとでもうすこし説明します)

この構成だとボタンは、ウィンドウの横幅に基づいてスケーリングされます。

倍率 = ウィンドウの幅 / 800

(たとえば)ウィンドウの横幅が 400px だとします。すると「倍率」の値は  \frac{1}{2} なので、ボタンは 50 x 50 ピクセルで表示されます。(最初は 100 x 100 ピクセルだった)

ウィンドウの高さを変更しても、ボタンのサイズは影響しません。

これの問題は、もしも横にだけ広いウィンドウ (800 x 200) だったとき、ボタンはウィンドウに対して、またしても不釣り合いな大きさを占めます。

f:id:shikaku_sh:20200131185151g:plain:w400
横幅は GOOD だけど縦の高さは変わってない!

スケールの(私がわかる限りでは)完全な計算式は次のとおり。

// match の値域は (0.000 <= 設定値 <= 1.000)
倍率 = (ウィンドウの幅 / 800) * (1 - match の設定値) + 
       (ウィンドウの高さ / 800) * (match の設定値)

したがって、match の設定値を「0.5」にすることで、ボタンは、ウィンドウに対して(縦横共に)相対的に表示されました。

実際のところ、キャンバスのサイズ(スカラー)がウィンドウのアスペクト比とほぼ同じであるときに限って、match の設定値「0.5」は、レスポンシブ UI を利用するために、かなりよい値となります。

f:id:shikaku_sh:20200131185249g:plain:w400
思い通りのリサイズの感じになりました

World Space(補足的な内容)

キャンバスの設定値 Render ModeWorld Space に設定することで、UI を 3D 空間に配置します。

f:id:shikaku_sh:20200131185422p:plain:w400
Canvas Scaler はサポートされません。がんばるしか。

このモードでは、キャンバスの幅と高さを設定できます。この場合、800 x 600 ピクセルに設定します。(上と同じ)また、UI を他の 3D エレメントに合わせて UI を縮小するには、Rect TransformScale を「0.01」に設定します。(X, Y の両方とも)

興味深いことに、World Spaceレンダリングの間、キャンバスの Canvas Scaler はオプションをサポートしなくなりました。これは、以前のようにできなくなったことを意味します。が、同時に、幅と高さを完全にコントロールできるので、(そのため)レスポンシブはそれほど重要ではありません。

Conclusion(結論)

最後に、キャンバスが Screen Spaceレンダリングされるとき、Canvas Scalar を設定することでレスポンシブ UI を作成できることを学びました。

また、キャンバスを World Spaceレンダリングすると、UI をレスポンシブにする機能が失われることも学びました。しかし、この場合、幅と高さを完全にコントロールできます。

補足(ここの記事で追加した内容)

テラシュールブログ - uGUIのアスペクト比を固定する(修正版)」の記事では、Canvas Scalar の設定値 Screen Match ModeExpand に変更することで、絶対に見切れないコンテンツにするテクニックが紹介されています。

Unity Manual - Canvas Scaler の Expand の説明は次のとおり。

  • キャンバスの領域を水平・垂直方向に拡張します。キャンバスのサイズが参照よりも小さくなることはありません。2

参照というとキャンバスとの比較の対象物がわかりづらくなっていますが、こんな感じになります。

f:id:shikaku_sh:20200131185533g:plain:w400
2Dはこれでわりと問題なさそうですね……!

参考

UnityではじめるC# 基礎編

UnityではじめるC# 基礎編


  1. 著者にうまくない翻訳記事を公開している旨を連絡したいのですが、連絡先がなにもないどころか、最近は更新されていないので……。怒られたら記事を消します。

  2. Expand the canvas area either horizontally or vertically, so the size of the canvas will never be smaller than the reference.