うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【Unity】uGUI インスタンス生成時のサイズ反映を即座に行う

Unity では ContentSizeFitterHorizontalLayout などを利用した
自動レイアウトのインスタンス生成時にサイズを取得しても正しいサイズが取得できない

下記のコードの場合 sizeDelta は (0, 0) になる

using UnityEditor;
using UnityEngine;
 
public class SampleMonoBehaviour : MonoBehaviour
{
    [SerializeField]
    private SampleRect _resource;
 
    private void Start()
    {
        var samplerRect = Instantiate(_resource, transform);
        samplerRect.Text.text = "1234567890123456789";
        var rect = samplerRect.transform as RectTransform;
        Debug.Log(rect.sizeDelta); // 0, 0
    }
}

これは インスタンス生成後に Canvas の更新タイミングでサイズが確定するためであって

生成してから1フレーム後にサイズを調べると正しいサイズを取得することができる

   private void Start()
    {
        var samplerRect = Instantiate(_resource, transform);
        samplerRect.Text.text = "1234567890123456789";
        var rect = samplerRect.transform as RectTransform;
        EditorApplication.delayCall += () =>
        {
            Debug.Log(rect.sizeDelta); // 現在のサイズ
        };
    }

今回は Editor 上での動作確認のため EditorApplication.delayCall を利用したが

実際に 1フレーム待つためには、IEnumerator を利用する必要があり、ちょいと面倒

なので、1フレームも待たずにサイズ更新ができる Canvas.ForceUpdateCanvases(); を利用する

   private void Start()
    {
        var samplerRect = Instantiate(_resource, transform);
        samplerRect.Text.text = "1234567890123456789";
        var rect = samplerRect.transform as RectTransform;
        Canvas.ForceUpdateCanvases();
        Debug.Log(rect.sizeDelta);
    }

これで 1フレーム待たずにサイズを取得することができる