初めまして、普段同人ゲームを作っているにーあいです。
UnrealEngineでパッケージ化するときのキリリッって音、ちょっとびくってなりませんか?僕はなります。
画面サイズを取得したい!!!!!!
ちょっと凝ったUIを作ろうと思ったらおそらくどこかで画面サイズを取得したくなる日がやってくると思います。
たとえば、任意のAnchor配置でwidgetの位置とかを取ってきたい場合にはもう画面サイズが必須なんじゃないのってそんな感じです。
なお、画面サイズとはEditorでのviewportやパッケージ化したあとのWindowのサイズを指すこととします。
さらに、本記事はド初心者が見つけた解決策をとりあえずまとめたものです。用語とかもあんまりよくわかっていないので、もし間違い等見つけられましたらご教授いただけますと幸いです。
基本的な画面サイズの取得のしかた
Qiitaってスクショをそのままペーストできて便利ですね。
画面サイズを取ってくるときは、このいずれかのノードを使うことになると思います。
Get Viewport Sizeからは画面の縦横サイズがピクセル数で取れます。これをScreen to Viewportでviewport座標系?に変換できます。
下のGet Viewport Widget Geometryは名前の通り、Viewportにあるwidgetのgeometryを取ってきます。Geometryって幾何学ですからね、サイズ以外にも位置とかこれらに準ずる情報を持っていそうです。
これからGet Local SizeかGet Absolute Sizeすればviewport座標系が取得できます。
(二つあるってことはそれぞれにメリットデメリットあるはずなんですが、正直どっちがいいのかはよくわかってません。また問題が生じたときに検証します……)
しかし!!!!!!
ある条件下だと画面サイズを取得することができないんです!!!!
EventConstructでは画面サイズが取れない!(と思った方がよさそう)
ここまでの内容だと、ググるかBluePrintEditorで右クリックしてノードを調べてたらそのうちたどり着けます。僕もノード眺めてたらなんか見つけました。
しかし(二回目)!!!!!!
widgetの初期位置を保存しておきたい場合など、最初に画面サイズを取得したい場合にはこれらをEventConstructに繋いで使いたくなりますが、無理です!!!!!
これが本題です。
少なくとも、先ほど紹介した方法は二つともEventConstructにつないだ状態では画面サイズ0か-nan(ind)を返します。
Editorから選択ビューポートで実行すると普通に取得できるのですが、スタンドアロンやパッケージ化した後だとちゃんとした値を返してくれません。(と思った方がよさそう)というのはそういうことです。
解決方法
一応、1フレーム目で画面サイズを取る方法があります。
EventTickに繋ぐ
これです。
様々検証したところ、PreEventConstructやEventConstructをはじめとして、UnityでのAwakeやStartメソッドに相当するタイミングではどの場合でも画面サイズが取れないのですが、それ以降になるとどういうわけだか取ってこれます。
この例では毎Tick画面サイズの変化を調べています。
PreTickResolutionは名前の通り、前Tickでの解像度というかサイズを保存しているVector2D型の変数です。
これの初期値を(0,0)にしておくことで、1フレーム目(や画面サイズが変化したタイミング)セット:PreTickResolutionから実行ピンを伸ばせば起動時に実行したかったこともできるというおしゃれ仕様。
もちろん、次のようにすれば本当に1フレーム目だけ実行することも可能。
ただしIsFirstTimeはデフォルト値をFalseにしておきましょう。
さいごに
結局、EventConstructでは画面サイズを取ってこれないからEventTickを使おうという話でした。もしEventConstructで取ってこれるのであれば毎Tick無駄な判定をかますという悲しいことをしなくてすむのに……