3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【uGUI】 UI要素のサイズを別UI要素と一致させるスクリプト

Last updated at Posted at 2020-03-24

背景

UI要素のサイズ(RectTransform.sizeDelta)を別UI要素に追従させ、見た目上で一致させたい

  • 一致させる対象が直接の親の場合
    • Stretch指定でOK
  • 一致させる対象が子かつ子の数が1つの場合

上記の様なヒエラルキーや要素数に依存しないコンポーネントが欲しかったので自作しました
また、Inspector上でのサイズ変更を不可にしました

UISizeFitter

using UnityEngine;

[ExecuteInEditMode, RequireComponent(typeof(RectTransform))]
public class UISizeFitter : MonoBehaviour
{
    [SerializeField] RectTransform _target;

    RectTransform _selfRect;
    Vector3 _cachedTargetLossyScale;
    Vector2 _cachedTargetSizeDelta;
    Vector3 _cachedSelfLossyScale;
    bool _isDirty = true;

    void UpdateDirty()
    {
        if (_cachedTargetSizeDelta == _target.sizeDelta &&
            _cachedTargetLossyScale == _target.lossyScale &&
            _cachedSelfLossyScale == _selfRect.lossyScale)
        {
            return;
        }

        _cachedTargetSizeDelta = _target.sizeDelta;
        _cachedTargetLossyScale = _target.lossyScale;
        _cachedSelfLossyScale = _selfRect.lossyScale;

        _isDirty = true;
    }
    void AdjustSize()
    {
        if (!_isDirty)
        {
            return;
        }

        if (_selfRect.lossyScale.x != 0 && _selfRect.lossyScale.y != 0)
        {
            _selfRect.sizeDelta = _cachedTargetSizeDelta * _cachedTargetLossyScale / _selfRect.lossyScale;
        }
        _isDirty = false;
    }

    // Layout Groupみたいに「Some values driven by 〜」とInspector上の編集を禁止する
    void LockRectTransformProperty()
    {
        DrivenRectTransformTracker dt = new DrivenRectTransformTracker();
        dt.Clear();
        dt.Add(this, _selfRect, DrivenTransformProperties.SizeDelta | DrivenTransformProperties.Scale);
    }

    void FitSize()
    {
        if (_target == null)
        {
            return;
        }

        UpdateDirty();

        AdjustSize();
    }

    void Awake()
    {
        _selfRect = GetComponent<RectTransform>();
        _selfRect.transform.localScale = Vector2.one;

        LockRectTransformProperty();
    }

    void Start()
    {
        FitSize();
    }

    void Update()
    {
        FitSize();
    }
}

補足

常に追従させたかったのでUpdateで実行していますが、負荷的に問題になったり、動的に変更しないのであればStartの一度のみ実行するのが良いと思います
また、 lossyScale がUnity側でキャッシュしているのか毎回計算しているのかが不明だったため、とりあえずComponent側でキャッシュしていますがUnity側で毎回計算している様だと比較時の負荷が若干気になります
_cached〜でキャッシュしているのは比較の方がコピーより高速だろうという考えの下です

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?