テンケイ的ブログ

unityでVRコンテンツを作りたい人のブログです

LayoutGroupの子要素のpositionを正しく参照できない

自作ゲームを作っているときにUIのpositionが思うように参照できず解決に時間がかかったので備忘録として残す

問題のシーン

現在選択されているUIを下のように黄色い枠で囲もうとしたところ 予想.PNG

実行時はこのようにずれてしまう 実際.PNG

コードは以下のようになっている。選択したいUIと同じpositionに黄色い枠を移動しているだけ

private void Start()
    {
        select.rectTransform.position = currentGauge.rectTransform.position;
    }

構成はこんな感じ CyrinderにはLayoutGroupがついている。SelectをCyrinderの子要素であるRedやGreenの位置に動かしたい

オブジェクト構成.PNG

Cyrinder構成.PNG

参考になった記事

unityのフォーラムで同じような症状についてやりとりしていた

https://forum.unity.com/threads/positions-of-ui-elements-under-vertical-layout-group.266775/

どうやらLayoutGroupなどのUI関係のコンポーネントの位置計算はフレームの最後に働くためにstart時は正しいpositionを参照できないとのこと       そこでUpdate中に黄色い枠を動かしてみると 正常.PNG

正しく動いた

解決法

しかし最初の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を参照できるようになった