ScrollRect.LateUpdate is undoing my attempts to manually scroll it

Here’s my situation: I have an object with a ScrollView, which holds an object called OutputText that has a Text component and a ContentSizeFitter. I periodically add text to this Text component, the ContentSizeFitter should make the object larger to accommodate all the text, and then I can scroll it with an associated scroll bar. This all works perfectly.

What I also do, is attempt to scroll the ScrollView to the bottom after I add some text. To do this, I grab the scrollRect, and set scrollRect.verticalNormalizedPosition to 0. This doesn’t work, in a variety of inconsistent and annoying ways. (This is in a function called ScrollWindowToBottom, which I’ll refer to below.)

Sometimes, when I set this value to 0, immediately querying it returns 1. Okay - I guess the content isn’t big enough for the scroll rect yet, so the only legitimate value is 1. But if you’re going to give me a numeric property I can set, I expect it to equal exactly what I set it to. If it can’t do that then it probably shouldn’t be exposed as a property. At the end of the frame, ScrollRect.LateUpdate moves the scrollbar, which I attach a callback to, seeing that both the scrollbar value and the scrollRect position are now 0. So, is this a property that can only be meaningfully queried at the end of the frame? Who knows.

The next call to ScrollWindowToBottom, after not filling the view yet, leaves everything in place - scrollrect verticalNormalizedPosition and scrollbar position both zero. Great.

Then, as soon as the text grows too big for the scrollRect, it breaks. Everything is still at zero before, during, and immediately after my ScrollWindowToBottom call. Then UnityEngine.UI.ScrollRect:LateUpdate is called, decides something, then moves my scrollbar back to 1 and scrollRect.verticalNormalizedPosition back to 1. So it’s at the top of the window.

I add more text: and now it has no idea what it’s doing. Scrollbar value and Scrollrect positions started as 1 (the top), I set verticalNormalizedPosition to zero (and this time it does change immediately). Further calls to ScrollWindowToBottom within that frame seem to go without a hitch. The scrollbar reported position is wrong but hopefully that’ll change when it spots where the ScrollRect now is. But at the end of the frame… I get 2 calls from UnityEngine.UI.ScrollRect:LateUpdate updating the scrollbar. The first reports that the scrollbar and scrollrect are still at zero. Great. The second has moved them both to 0.61, cutting off the bottom few lines of my text.

I repeat this one more time, and the pattern repeats - I get to set verticalNormalizedPosition to zero, it respects that, then at the end of the frame, instead of moving the scrollbar to match the position I asked for, it does something to change the layout and scrolls to a point where the bottom handful of lines are missing. Whenever I add lines it seems to keep the bottom few lines out of view. Sometimes it’s 4 lines, sometimes it’s 9, sometimes it’s 11. I can’t see how this relates to any other variable.

Why does it do this? I’m studying the code for ScrollRect.cs to try and work out what sort of layout it is doing, but can’t work out what or why it is changing things. I’ve tried changing the scrollbar position instead of, and as well as, the scroll rect, with the same exact behaviour in both cases.

Maybe this is some weird interaction with anchors or pivots, but I have no way of knowing because that system is far too complex, especially when you throw resizing objects into the mix. Is there something specific I should be looking out for?

Okay… looks like if I set the pivot on the text object to be bottom left instead of top left, then it seems to get the location right. Otherwise, it’s changing the layout each frame so that…something… is offset from something else. Who knows what.

Unfortunately if I set the pivot to the bottom left instead of the top left, then it looks wrong when the content is too small - it gets aligned to the bottom left.

What I want is for it to work the normal way, ie. how this text box I’m typing into now works - content fills up from top left to bottom right, but when it is too big, it scrolls down so you can see the new content that is added…

I’m having a similar issue to Kylotan.

ie. Wanting to add an item to the end of a scrollable list, then use ‘verticalNormalizedPosition’ to move the Scroll Rect to the bottom, to show the new item. But it does seem like it was not actually moving the Scroll Rect within the Update?

However - just wanted to say that your tip of “setting the pivot to the bottom left instead of the top left” appears to have solved the problem for me

Thanks.