uGUIのGridLayoutGroupがオートレイアウト対応してないので対応させるやつ書いた

#概要
GridLayoutGroupのCellSizeを自動調整します。

#使い方
GridLayoutGroupと同じオブジェクトに付与してください。
もしくは、付与した際に自動でGridLayoutGroupが連鎖的に付与されます。
なお、Constraintを何に設定するかで、調整項目が違うので注意。

- Flexible
    - CellSizeが完全に自動調整されます。事前入力値は無視します。
- FixedColumnCount
    - CellSizeのXを自動調整します。Yは事前入力値を継承。
- FixedRowCount
    - CellSizeのYを自動調整します。Xは事前入力値を継承。

```C#:AutoGridLayoutOverrider.cs
using UnityEngine;
using UnityEngine.UI;

namespace CustomUIParts
{
    /// <summary>
    /// UnityEngine.UI.GridLayoutGroup をAutoLayout仕様にする
    /// </summary>
    [RequireComponent(typeof(GridLayoutGroup))]
    public class AutoGridLayoutOverrider : MonoBehaviour
    {
        /// <summary>
        /// オートレイアウト対応するGridLayoutGroup
        /// </summary>
        [SerializeField] GridLayoutGroup grid = default;

        /// <summary>
        /// サイズ調整に使用するRectTransform
        /// </summary>
        RectTransform rect = default;

        #region サイズ変動要素の比較用キャッシュ
        // Grid内オブジェクトの個数
        int beforeChildCount;
        // RectTransformからのデータ
        float beforeWidth, beforeHeight;
        // GridLayoutGroupからのデータ
        Vector2 beforeCellSize;
        Vector2 beforeSpacing;
        GridLayoutGroup.Axis beforeAxis;
        GridLayoutGroup.Constraint beforeConstraint;
        int beforeConstraingCount;
        #endregion


        /// <summary>
        /// InspectorでのReset動作定義
        /// </summary>
        void Reset()
        {
            grid = GetComponent<GridLayoutGroup>();
        }

        /// <summary>
        /// Unityライフサイクル関数
        /// </summary>
        void Awake()
        {
            // サイズ調整の基準となるRectTransformを取得
            rect = GetComponent<RectTransform>();
            while (rect.rect.width == 0 && rect.rect.height == 0)
            {
                // Streach前提でサイズが取得できないときは、親・祖先オブジェクトに遡って取得しにいく
                rect = rect.transform.parent.GetComponent<RectTransform>();
            }
        }

        /// <summary>
        /// Unityライフサイクル関数
        /// </summary>
        void Update()
        {
            ResetLayoutSize();
        }

        /// <summary>
        /// レイアウトサイズ変更
        /// </summary>
        void ResetLayoutSize()
        {
            // レイアウト状態に変更が無ければスキップ
            bool skipFlag =
                beforeWidth == rect.rect.width &&
                beforeHeight == rect.rect.height &&
                beforeChildCount == grid.transform.childCount &&
                beforeSpacing.x == grid.spacing.x &&
                beforeSpacing.y == grid.spacing.y &&
                beforeAxis == grid.startAxis &&
                beforeConstraint == grid.constraint;

            // 幅固定指定の場合は、前回サイズから変更がないか追加チェック
            switch (grid.constraint) {
                case GridLayoutGroup.Constraint.FixedColumnCount:
                    skipFlag &= beforeCellSize.y == grid.cellSize.y;
                    skipFlag &= beforeConstraingCount == grid.constraintCount;
                    break;
                case GridLayoutGroup.Constraint.FixedRowCount:
                    skipFlag &= beforeCellSize.x == grid.cellSize.x;
                    skipFlag &= beforeConstraingCount == grid.constraintCount;
                    break;
            }

            if (skipFlag)
            {
                return;
            }

            // 何かしら状況が変わったのでレイアウト設定を変える

            float x = grid.cellSize.x;
            float y = grid.cellSize.y;

            switch (grid.constraint)
            {
                // x,y:ともに可変（領域全体を埋める）
                case GridLayoutGroup.Constraint.Flexible:
                    int childCount = grid.transform.childCount;
                    int i = 0;
                    while (Mathf.Pow(++i, 2) < childCount) { }

                    int tateNum, yokoNum;
                    if (Mathf.Pow(i, 2) == childCount)
                    {
                        tateNum = yokoNum = i;
                    }
                    else if (grid.startAxis == GridLayoutGroup.Axis.Horizontal)
                    {
                        yokoNum = i;
                        tateNum = childCount / i + (childCount % i != 0 ? 1 : 0);
                    }
                    else
                    {
                        // 縦方向優先に並べる動作は挙動が特殊
                        yokoNum = i;
                        if(childCount <= i * (i-1))
                        {
                            tateNum = childCount / i + (childCount % i != 0 ? 1 : 0);
                        }
                        else
                        {
                            tateNum = i;
                        }
                    }

                    x = (rect.rect.width - grid.spacing.x * (tateNum - 1)) / tateNum;
                    y = (rect.rect.height - grid.spacing.y * (yokoNum - 1)) / yokoNum;
                    break;

                // width のみ可変
                case GridLayoutGroup.Constraint.FixedColumnCount:
                    x = (rect.rect.width - grid.spacing.x * (grid.constraintCount - 1)) / grid.constraintCount;
                    break;

                // height のみ可変
                case GridLayoutGroup.Constraint.FixedRowCount:
                    y = (rect.rect.height - grid.spacing.y * (grid.constraintCount - 1)) / grid.constraintCount;
                    break;
            }
            beforeCellSize = grid.cellSize = new Vector2(x, y);

            // 更新処理スキップ判定用に諸々キャッシュ
            beforeChildCount = grid.transform.childCount;

            beforeWidth = rect.rect.width;
            beforeHeight = rect.rect.height;

            beforeSpacing = grid.spacing;
            beforeAxis = grid.startAxis;
            beforeConstraint = grid.constraint;
            beforeConstraingCount = grid.constraintCount;
        }
    }
}
```
### 変更ログ
2020/12/16
最初はUpdateにプラットフォーム依存処理を入れていたが、
別プラットフォームでビルドしたら反映されなかったので修正。