Stretched RectTransform initialisation?

Hey everyone!

I’m making my own LayoutSelfController component that’s basically a Content Size Fitter, but with a smooth transition on resize. I’m running into a funny problem, however.

I’ve made a little test panel containing 3 Images arranged with a Vertical Layout Group. The parent object also contains my custom controller. Everything sizes properly in the inspector so the parent object resizes to be of dimensions padding + elements sizes + spacing. I have also added the necessary DrivenRectTransformTracker to ensure the driven values of the RectTransform don’t get serialized.
Lastly, I’ve set the parent RectTransform’s anchors to stretch mode.
However, when I start the scene in play mode, SetLayoutHorizontal and Vertical are called multiple times (before Awake or Start), and within these when I try to calculate the desired dimensions I get completely wrong values, resulting in immediate resizing that I don’t want.
On a first cycle, my target values are calculated to be 0 (which should be the same dimensions as I got at edit time instead), while my current values are calculated to be wildly overblown (beyond the parent’s dimensions. Example: 820 width on a canvas with width 480).
On the second cycle, the values are calculated correctly.
I have tried making a little “lock mechanism” to stop the SetLayout functions from doing anything until Start has called, and while that does fix the problem of the target values being calculated as 0, the current values are still the same overblown values at first.
Why are these values so wrong?

Below is the code I use for calculating the Target Width (same for height, just different method calls).

    private float GetTargetWidth()
    {
        switch (horizontalFit)
        {
            case ContentSizeFitter.FitMode.Unconstrained:
                return CalculateRectSize(_rect, 0);
            case ContentSizeFitter.FitMode.MinSize:
                return LayoutUtility.GetMinWidth(_rect);
            case ContentSizeFitter.FitMode.PreferredSize:
            default:
                return LayoutUtility.GetPreferredWidth(_rect);
        }
    }

And here is the code I use for calculating the Current Sizes (axis = 0 for horizontal, 1 for vertical).

    private float CalculateRectSize(RectTransform rect, int axis)
    {
        var anchor = (rect.anchorMax - rect.anchorMin)[axis];
        var sDelta = rect.sizeDelta[axis];
        var bounds = RectTransformUtility.CalculateRelativeRectTransformBounds(rect.parent);
        return anchor == 0 ? sDelta : (bounds.size[axis] * anchor) + sDelta;
    }

Thanks in advance!

I have found a workaround for this problem, though it is rather hacky.
After a lot of searching around for alternatives to calculate a RectTransform’s size that all ended up being flukes (seriously, what’s up with that Unity?) I deduced that on the first frame of a scene, RectTransforms being affected by Layouting are simply unreliable.
A key hint for this was that when I disabled my element at edit time and activated it at runtime later in the scene’s lifetime, the element did not resize if it already had the proper dimensions.
My solution is to simply keep track of the amount of ticks have passed in the element’s lifetime, and if a resize is triggered during the first 2 ticks, it applies that resize immediately instead of the animated resize. Any resize triggers that happen after these two ticks will animate as normal.
Basically:

int _ticks

void Update()
{
    _ticks++;
}

void SetLayoutHorizontal()
{
    if(_ticks < 2)
    {
        //Immediate resize with RectTransform.SetSizeWithCurrentAnchors
    }
    else
    {
        //Start an animated resize calling RectTransform.SetSizeWithCurrentAnchors over multiple frames
    }
}

For now, this works, but as I said before this is incredibly hacky and I’d rather have an answer as to why calculating a RectTransform’s dimensions (or bounds, as seen in my opening post code) is so inaccurate in the first update loop and how to work more neatly with it.