LayoutGroupの子要素のpositionを正しく参照できない
自作ゲームを作っているときにUIのpositionが思うように参照できず解決に時間がかかったので備忘録として残す
問題のシーン
現在選択されているUIを下のように黄色い枠で囲もうとしたところ
実行時はこのようにずれてしまう
コードは以下のようになっている。選択したいUIと同じpositionに黄色い枠を移動しているだけ
private void Start() { select.rectTransform.position = currentGauge.rectTransform.position; }
構成はこんな感じ CyrinderにはLayoutGroupがついている。SelectをCyrinderの子要素であるRedやGreenの位置に動かしたい
参考になった記事
unityのフォーラムで同じような症状についてやりとりしていた
https://forum.unity.com/threads/positions-of-ui-elements-under-vertical-layout-group.266775/
どうやらLayoutGroupなどのUI関係のコンポーネントの位置計算はフレームの最後に働くためにstart時は正しいpositionを参照できないとのこと そこでUpdate中に黄色い枠を動かしてみると
正しく動いた
解決法
しかし最初のUpdate時のみ動かすみたいなことはしたくない どうしたものかと調べたところ普通に公式リファレンスに書いてあった https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/class-RectTransform.html
You can work around this by creating a Start() callback and adding Canvas.ForceUpdateCanvases() method to it. This will force Canvas to be updated not at the end of the frame, but when that method is called.
つまりCanvas.ForceUpdateCanvas()を呼ぶことでCanvasのUpdateをフレームの最後ではなく即時にすることができるらしい
private void Start() { Canvas.ForceUpdateCanvases();//追加 select.rectTransform.position = currentGauge.rectTransform.position; }
これでstart時でも正しくpositionを参照できるようになった