概要
特定の場所にオブジェクトを並べる時はHorizontalLayoutGroupやVerticalLayoutGroupなどを使いますが、並べられたオブジェクトのサイズをコード上で取得しようとしても0が返ってきて困ることってあると思います。
本文
まず、うまくいかなかった場合の状況を再現してみます。
BoxオブジェクトにはHorizontalLayoutGroupが付いてるので中にあるImageは横方向に並べられる状態になっています。さらにImageの高さはBoxの高さと同じになるように設定してあります。
ここで以下のようなコードを作成してImageにAddComponentしてもコンソールログにはImageの正しい高さは表示されず「0」と表示されてしまいます。
using UnityEngine;
using UnityEngine.UI;
public class SetSquare : MonoBehaviour
{
private void Start()
{
Image image = GetComponent<Image>();
float height = image.rectTransform.rect.height;
Debug.Log(height);
}
}
試しに以下のように書き換えてみると
using UnityEngine;
using UnityEngine.UI;
public class SetSquare : MonoBehaviour
{
private void Update()
{
Image image = GetComponent<Image>();
float height = image.rectTransform.rect.height;
Debug.Log(height);
}
}
ログには最初だけ0が表示されていますが、それ以降は正しく取得できていることが確認できます。
最初の1フレーム目だけ正しい値が取得できないことさえ気をつければちゃんと値を取得できることがわかりました。
以下はImageの高さを正しく取得して横幅に代入するサンプルコードです。
using UnityEngine;
using UnityEngine.UI;
public class SetSquare : MonoBehaviour
{
private void Start()
{
Image image = GetComponent<Image>();
// この一行を加えれば1フレームを待たずにすぐサイズを取得できるようになります。
Canvas.ForceUpdateCanvases();
float height = image.rectTransform.rect.height;
// 横幅に縦幅を指定する
image.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, height);
}
}
正しく取得した高さを使って正方形に変形することができました。
補足
同様のことを
LayoutRebuilder.ForceRebuildLayoutImmediate()
このメソッドでも出来るようです。上手くいかなかった場合はこちらも試してみてください!以下は実装例です。
using UnityEngine;
using UnityEngine.UI;
public class TitleController : MonoBehaviour
{
public Text titleText;
// Horizontal Layout Groupが付いてるオブジェクトのRectTransform
public RectTransform titleContainer;
public void SetTitle(string newText)
{
titleText.text = newText;
// レイアウト再構築
LayoutRebuilder.ForceRebuildLayoutImmediate(titleContainer);
}
}