# 【Unity】 WorldSpaceでもマルチ解像度対応したかった話 こんにちは、たかせです。カードゲーム作ってます。 ちょうど先日、テストプレイの様子をyoutubeに投稿しました。 https://twitter.com/BTF_TCG/status/1142807293085417473 声小さい方が僕なんですが、こう改めて視聴してみると実況に慣れてない感じがひしひしと伝わってきますね。もっと大きな声でとか、言葉選びは慎重にとか、反省点が多いです。 それはさておき、今回はマルチ解像度に対応する話です。 ## 背景 例えば今回のテストプレイを撮影したiPhoneXだと、以前までこんな風に表示されていました。 <img src="https://i.imgur.com/hti9ZTR.jpg" width="200px"/> <br><br><br><br><br><br> _人人人人人人人人_ > MPが見えない <  ̄Y^Y^Y^Y^Y^Y^Y^Y^ ̄ <br><br><br><br> UnityEditor上だとこんな感じ。  ちなみに横幅が広い端末だと青空が写り込んでしまう状況でした。  とりあえずぐぐった感じ、CanvasのRenderModeを`Screen Space Overray`か`Screen Space Camera`にすると解決できそうだとわかったんですが、BeyondTheFieldでは`WorldSpace`のRenderModeで開発を進めていたため、この方法は採用できませんでした。 <img src="https://i.imgur.com/X1IBRsR.png" width="300px"/> (`WorldSpace`によるUI設計には次の記事のような恩恵があるようです。そこまで詳しく把握できていないので説明は割愛しますが、今回はエンジニアの意地💪を見せたかったのもあり、`WorldSpace`のままマルチ解像度に対応する方針で修正を進めました) http://tsubakit1.hateblo.jp/entry/2016/02/22/233000 ## 修正方針 次の方針で修正することにしました。 - カメラに映る領域を2つのレイヤーに分ける - Screenレイヤー: 端末サイズに合わせて拡大/縮小するレイヤー - Contentレイヤー: 縦横比を維持したまま端末にちょうど収まるように拡大/縮小するレイヤー - ScreenレイヤーとContentレイヤーを適切にリサイズするスクリプトを作る  なお、前提条件は次のとおりです。 - CanvasのRenderModeは`WorldSpace` - カメラの位置とパラメータはゲーム中に**変化しない** - UIを正しく表示できるサイズが事前に**決まっている** 今回の例だと、表示したいUIは`1080 x 1920`で正しく表示できるように設計しています。 ## 先に修正結果 iPhoneXにおける見え方はこのようになりました。  また、冒頭で青空の写り込んでいた端末ではこのようになりました。  良かったこと - UIやエフェクトが画面外に表示されてしまう問題を解決できた - iPhoneXにおいて、UIをセーフエリア内に収めることが出来た - 修正が楽だった(1日) 良くないこと - 端末によっては、無駄な領域が生まれてしまう - iPhoneX以外でセーフエリア内に収まる保証がない 修正項目は次の2つだけで、UIの配置変更では表示崩れは起きなかったので比較的楽に修正を完了することが出来ました。 - Scene直下に配置していたUIに親を与える - スクリプトを1つ作成する `1080x1920`を想定していたとはいえ、Anchorやlocal属性による相対的な位置取りを意識して作成していたことが功を奏したと思います(例えば`540x960`のサイズでも表示崩れは起きなかった)。 また、偶然といえば偶然なのですが、iPhoneXにおけるPortrait表示においてセーフエリア対応もできてしまいました。**まだAppleへの審査には提出したことがない**のでなんとも言えないですが、`Width > Height`の状態がPortraitなセーフエリア持ちの端末が出てこない限りはこれで大丈夫...なはず...(リリース時にはLandscape状態を禁止する予定です) 楽に修正できた反面、褒められた修正ではないなぁ、という思いはあります。理想的なマルチ解像度対応を考えれば、それはその解像度で提供しうるUXを最大化することだと思うので、ゆくゆくはこの方針で再修正したいものです。 ## 修正方法 一応前提条件の確認です。 - CanvasのRenderModeは`WorldSpace` - カメラの位置とパラメータはゲーム中に**変化しない** - UIを正しく表示できるサイズが事前に**決まっている** これらの条件を満たさない場合は、他に良い修正方法がある可能性が高いのでご注意ください。この条件を満たしている場合でも他にいい方法があれば教えてほしいです🙇♂️ ### 1. ScreenレイヤーとContentレイヤーを作成する まずは、Scene直下にScreenレイヤーを配置します。ScreenレイヤーにはCanvas系の一式をアタッチし、RenderModeを`WorldSpace`に変更します。 ※開発しやすいようwidth, heightに初期値を与えていますが、この値は実行時にスクリプトによって書き換えられます  次に、Screenレイヤーの子供としてContentレイヤーを追加し、Anchorsを中心に、widthとheightを想定しているサイズに合わせます。 ※Contentレイヤーのwidth, heightはスクリプトによる書き換えはありません。代わりにscaleを書き換えます  最後に、Screenレイヤーの二人目の子供として背景画像を追加します。こちらの画像はAnchorsを両軸ともStretchにし、Screenレイヤーのサイズ変更を追従するようにしておきます。  ### 2. Contentレイヤーがちょうど収まるようにカメラを調整する カメラのパラメータを調整し、ViewPortのサイズとContentのサイズを一致させます。  <img src="https://i.imgur.com/L9fRYNX.png" width="200px"> ※SceneエディタのGizmosをONにすると、カメラのViewPortサイズを確認可能です。 ### 3. 各種レイヤーをリサイズするスクリプトをアタッチする `DynamicScreenView`というスクリプトを作成したので、これをスクリーンレイヤーにアタッチし、各種パラメータを設定します。 https://gist.github.com/niwatly/1616d794ddfc7a02bc504bb0eee65f6a.js  - ScreenRect: 手順1で作成したScreenレイヤーを設定します - ContentRect: 手順1で作成したContentレイヤーを設定します - SubContentRect: 後述します(設定しなくても動作します) - Cam: 手順2で調整したカメラを設定します ### 4. 完了! 後はContentレイヤーの中にUIを追加していくだけです。ここまで読んでくれてありがとうございます🥰 ### 5. Contentレイヤーが1つでは満足できないあなたに `DynamicScreenView`はz座標の異なる複数のContentレイヤーに対応しています。 使い方は、先程の説明にあった`SubContentRects`に追加するだけです。 <img src="https://i.imgur.com/gTQZaPi.png" width="500px">/ SubContentRectsに追加しない場合  SubContentRectsに追加する場合  ## 終わりに BeyondTheFieldはiPhoneXでも遊べる新作カードゲームです!!!(当たり前) https://twitter.com/BTF_TCG わりと手探りで修正を終わらせた感は否めないので、何か変な点があればご指摘いただけると幸いです。それではまたー!
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up