yumeの日記: Unity制作 メデューサ・ゲーム #10 2
●テキスト描写シーン
いわゆるアドベンチャーゲーム(というかゲーム全般か)風の、下半分くらいにテキストボックスがあり、そこに3行程度のテキストが流れるあれ。
話してる人のイラストがでっかくでたらギャルゲー風かな。そんなイラストどこから用意するのかわからんけど。
まぁいいや。それで、公式曰く、UnityのUIは画面上でどういう風にスケールさせるかを決められる。
例えばボタンやテキストのサイズはそのままで、画面上の位置だけを動かすこともできれば、テキストサイズそのものを変えることもできるらしい。
だとすると、前回作ったメニューもこの比率変更に対応しなきゃな。今回のゲームはパソコン向けなので、1920x1080を基準に考えていく。
現代の日本語の文字はすべて正方形に収まるように作られている。ある文章を横組で読むとき、読みやすいとされる長さは20文字程度、長くて30文字という説がある。ウィンドウは横に長いので、30文字以上も入れることはできるが、ここでは最大30文字としよう。
一文字の大きさを40pt(=40px)とすれば、一行に収まる行長は40*30=1200pxだ。書籍の組版では、行間は行長が長ければ長いほど多くとる必要があるとされる。30文字なら行送り200%がよいだろう。しかしここでは3行だけだから、行を拾い違えることもないだろう。となればそこまで長くとる必要はないだろう。行送り175%で70ptとする。ルビを使うならもう少し欲しいが、まぁいいか。
画面の横幅はそれでもまだ720も余裕がある。テキストを箱の上に乗せ、箱とテキストの余白を充分にとってもまだ余る。つまりやろうと思えばテキストボックスの横に顔画像(RPGでよくあるアレ)を置いたり、名前を置いたりとかもできるわけだ。今回は単に余白のままにしておく。
そうすると、レイアウトとしてはだいたいこんな感じになる(これはillustratorで作ったラフ)。
かなりハイコントラストな組み合わせだが、フルHDフルスクリーン24インチのモニターで、50cm程度の距離から見る場合、少し文字が大きすぎる。
小さい画面ならこれでもよさそうだが、80%程度の大きさでもよさそうだ。ここでは90%の36pxとしておく。となると36*30=1080pxでよいことになる。
ところが、この設定どおりの数値をUnityに入力しても、いまいち計算通りにならない。なんでだよ。
Font Size 40は40pxではないのか。 Line Spacingは何を基準に1なんだろう。勝手に文字詰めなどしている様子でもない。うーむ。
ふとGame画面をエディタ上で拡大縮小すると、文字列が30文字納まるはずのところが、29だったり31だったりにずれている。
Unityのエディタ上の画面解像度は、実際にそこに表示されている解像度で処理されているのか。まぁ例えば実際に書きだしたゲーム本体を、このサイズで遊べばこう見える、という感じだろう。
となると、ここで想定したフルHD解像度を入力して、実際の表示は小さいけどUnityにはフルHDだと思い込んでもらう方式ならどうだろう。
はたしてうまくいった。ただ行間は相変わらず基準がわからない。行送り175%はだいたい1.2か1.21くらいでうまくいった。公式を読んでも何を基準に1なのかさっぱりわからない。まぁいいか。
それと、禁則処理はどうなってるんだろう。Qiita @ma_sh曰く、Unityに禁則処理はないので何らかの対処が必要なようだ。両端揃えもできれば導入したい。まぁあとにしておこう。
次はテキストをRPGみたいに1文字ずつ表示するやつだ。Console Adventureでまぁ同じ仕組みを作ったし、その前はGameMaker Studio 2でも作っていたので、なんとなく作り方は見えている。
基本的な考え方はだいたい:
構造は:
・TextWindow全体の親にあたるCanvasオブジェクトTextWindow
・テキストウィンドウの枠にあたるImageオブジェクト TextWindowBox
・UI Textオブジェクト BodyText
処理の基本の流れは:
・TextWindowにTextOutputコンポーネントをつけておく
・なんとかしてTextOutputに「読ませたいテキスト」を渡す
・TextOutputが受け取ったテキストから、時間経過ごとに1文字ずつ足していくString OutputStringを用意
・OutputStringをTextOutputに渡す。
追加したい流れは:
・テキストが表示されきっていないとき、クリックとかエンターとか押すとテキストを一斉に表示する。
・すべてのテキストが表示されているとき、クリックとかエンターとか押すと次のテキストor命令を要求する。
・次のテキストがあるならそれを表示、何らかの命令があるなら命令を実行(テキスト終了とか選択肢とか)。
あとなんかでっかいイラストを表示するとか、そういうのはインライン命令文みたいなのを定義すればいいかな。
まずは基本の流れを作ろう。
まずはBodyTextのTextコンポーネントのtext変数が必要だ。
ここで初めて気づいたが、いちいちオブジェクトを取得しなくても、中のコンポーネントだけに用事があるなら、例えば:
public Text bodyTextString;
などとしておけば、Unity上から直接コンポーネントを指定できるみたいだ。これならオブジェクトをいちいち探したり指定しなくてよい。どうせコンポーネント(のtext変数)にしか用はないのだ。
考えてみれば、コンポーネントもGameObjectと同じくひとつのクラスなわけだから、そりゃそうだという感じだ。
というわけでbodyTextString.text(ややこしい名前だ)にアクセスできる。
・Start関数で、outputTextにテキスト(今回は仮テキスト)を読み込ませる
・Update関数で、経過時間をチェックし、前回の表示から0.5秒を超えたら int charCountを+1する。
・bodyTextString.text = outputText[charCount]
あとテキストをファイルかなんかから読み込む方法も必要だろう(テキストをコードの中に直接書くのは大変だし……)。先にざっと調べておく。
https://qiita.com/Eureka/items/716f4f52b4106419dbec
https://note.com/macgyverthink/n/n83943f3bad60
といったところで今日はここまで。時間やば。
横画面なら (スコア:0)
>今回のゲームはパソコン向けなので、1920x1080を基準に考えていく
今どきUnityで携帯向け横画面アプリ作る場合も、ベースは1920x1080で作りますね
でCanvasScalerとか便利なものがあるので使います
あとUnityエディタbuild targetがAndroidとかiOSになっていると
Gameウィンドウの左上で端末解像度切り替えができるので便利です
ポイント (スコア:0)
1ポイント = 1/72インチ https://ja.wikipedia.org/wiki/%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88 [wikipedia.org]
Windowsの標準DPI = 96DPI = 96PPI
つまり、標準DPIの環境だと1ポイント = (72/96)ピクセル = 0.75ピクセル
なんだけど、Unityでもそれが通用するかは分からないし、
スケーリングもどうなってるか知らない。