Your suspicion is correct - before a new message is added check to see if you're scrolled to the bottom, then after adding the new message set the scroll position to maximum.
However there are two problems to deal with.
The first is detecting whether you're scrolled to the bottom. When scrolled all the way down, a scrollbar's
value is not equal to its
max_value is closer to
value plus the scroll container's height, so compare the
max_value minus the scroll container's
rect_size.y. I'm not sure if you'll have issues with margins or custom theme settings, so this might need some tweaking.
The other problem is that the scroll container is not updated on the same frame as when the message is added, so be sure to wait a frame before attempting to set the scrollbar's value. One way to do this is to wait for the SceneTree's
In the following example I have a ScrollContainer named
scroll_box and inside of that a VBoxContainer named
func add_message(message: String) -> void:
var scroll_bar = scroll_box.get_v_scrollbar()
var should_auto_scroll = ((scroll_bar.max_value - scroll_box.rect_size.y) - scroll_bar.value) <= 0
var label = Label.new()
label.text = message
scroll_bar.value = scroll_bar.max_value