なかなかUnityを使う機会がなかったので、Unity 4.6から導入されたUIもさわっていなかったのだけど、ようやく機会がおとずれたので勉強しながら使ってみました。
作っていたのはメッセージウィンドウで、短いメッセージならそのメッセージの長さに合わせてウィンドウの幅を狭めて、長いメッセージの場合には幅に上限を設けて改行する、という動作にしたかった。
そこで、LayoutElement の flexibleWidth(と flexibleHeight)でその要素の最大サイズを指定するのかなと思ってやってみたらそうじゃなかった。
例えば VerticalLayoutGroup と HorizontalLayoutGroup を使って
1 2 3 4 5 |
+-------+ | A | +-------+ | B | C | +-------+ |
というようなレイアウトを組んで、Aの幅が100, BとCの幅が25だった場合、2番目の行の幅が50あまる。
flexibleWidthというのは、このあまった50をどういう配分でBとCに振り分けるか、その重みを指定するプロパティなのだ。
なのでBのflexibleWidthもCのflexibleWidthも共に1ならばともに幅が25ずつ加算されて幅が50になる。
BのflexibleWidthが0でCのflexibleWidthが1ならば、Cの幅だけ50加算され、Bの幅が25, Cの幅が75になるという具合。
というわけで、flexibleWidthは今の用途には全然関係ないことがわかった。じゃあどうするのか?フォーラムのこのスレッドが参考になったんだけど、基本的に最大サイズを指定するにはレイアウトグループを使うらしい。
レイアウトグループ(HorizontalLayoutGroupとかVerticalLayoutGroup)の子供の要素のサイズは親のレイアウトグループのサイズが上限になるようです。
でもここでもハマりポイントが。Content Size Fitterはこの上限値を無視してしまうのです。
例えば、
1 2 3 |
WindowSizeCap(HorizontalLayoutGroup) +- MessageWindow(Image + HorizontalLayoutGroup + Content Size Fitter) +- Text |
という具合に作った場合、Message WindowのContent Size FitterでHorizontal FitをPreferred Sizeにしてしまうと、Textの長さがWindowSizeCapの幅を越えても改行されずにMessageWindowの幅がTextの幅になってしまう。
よく見るとインスペクタービューにちゃんと警告が出るんですけどね・・・
最初はサイズの上限の指定方法がわからず、WindowSizeCapを後からつけたために、Content Size Fitterでハマってしまったのかもしれない。
MessageWindow につけている HorizontalLayoutGroup が Content Size Fitter と似たような役割を持って、ImageのサイズをTextのサイズに合わせてくれるので、実際Content Size Fitterは必要ない。
結局、
1 2 3 |
WindowSizeCap(HorizontalLayoutGroup + Content Size Fitter) +- MessageWindow(Image + HorizontalLayoutGroup) +- Text |
という構成にすればうまく行きました。
WindowSizeCap の Content Size Fitter はサイズの上限を幅だけにして、高さには上限を持たせないようにするためにつけてあります(Horizontal FitはUnconstrainedでVertical FitだけPreferred Sizeにする)。また、いずれの HorizontalLayoutGroup もChild Force Expandをオフにしてあります。