Vertical Scroll Spills Over into Horizontal Scroll in ScrollContainer

Godot Version

4.2.2

Question

I have a ScrollContainer with a child control that is larger in both X and Y. What I would expect (and want to enforce) is that the scroll wheel scrolls up and down only, and then the horizontal scroll bar can be dragged to scroll left and right.

What I am finding is that the scroll wheel initially scrolls up and down, but once I get to the bottom of my container, the mouse wheel scrolling spills over into the horizontal and scrolls right. Similarly when I then scroll up on the wheel, the container scrolls up until I hit the top, and it then scrolls to the right.

Is there a way that I can limit the scroll wheel to only effecting the vertical scrolling of the container while still allowing manual (drag) scrolling in the horizontal?

on the scroll container, add this script

extends ScrollContainer

signal wheel_up
signal wheel_down

func _gui_input(event):
	if event is InputEventMouseButton and event.is_pressed():
		if event.button_index == MOUSE_BUTTON_WHEEL_UP :
			wheel_up.emit()
			get_tree().get_root().set_input_as_handled()
		elif  event.button_index == MOUSE_BUTTON_WHEEL_DOWN :
			wheel_down.emit()
			get_tree().get_root().set_input_as_handled()

now you handle the wheel_up and wheel_down signal by basic .connect from the other script to scroll up and down as you wish how many pixel, can also add checking for the scroll, to not pass limit something.

@export var the_scroll_container: ScrollContainer
var current_scroll_amount: float = 0.0

func _ready():
	the_scroll_container.wheel_up.connect(_on_wheel_scroll_up)
	the_scroll_container.wheel_down.connect(_on_wheel_scroll_down)

func _on_wheel_scroll_up():
	current_scroll_amount -= 100.0
	current_scroll_amount = max(current_scroll_amount, 0.0)
	animate_scroll()

Thanks! I think your solution was a little over-complicated for what I needed, and didn’t quite address separating the vertical/horizontal scrolling, but I was able to take what you gave and reduce down to this script on the ScrollContainer which does exactly what I need:

extends ScrollContainer

func _gui_input(event:InputEvent) -> void:
	if event is InputEventMouseButton and event.is_pressed():
		if event.button_index == MOUSE_BUTTON_WHEEL_UP :
			if scroll_vertical <= 0:
				get_tree().get_root().set_input_as_handled()
		elif  event.button_index == MOUSE_BUTTON_WHEEL_DOWN :
			var child:Container = get_child(0)
			if scroll_vertical >= max(0, child.get_rect().size.y - get_rect().size.y):
				get_tree().get_root().set_input_as_handled()

it’s basically the same but exposing the signal instead for other controller script to use

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.