Input Touch Events over Scroll Box doesn't check if a touch drag is released

I found an error input touch event in blueprint over scrollbox doesn’t check if a touch drag is released. Only check if a dragging released outside of the scrollbox. Get input touch state under the scroll box returns x y position only for the first touch and variables x y are not updated during drag. Please Help.

I hope someone has a solution for this.

I’m having the same problem. My camera controls are multi touch. But if my UMG has a ScrollBox, it stucks my controls as if one touch is always on the screen, because the ScrollBox doesn’t consume the “Pressed” event but does so with the “Released”. So, for the game, it’s like I’ve touched the screen and never let go.

Found this at Engine/Source/Runtime/Slate/Private/Widgets/Layout/SScollBox.cpp:825

FReply SScrollBox::OnTouchStarted(const FGeometry& MyGeometry, const FPointerEvent& InTouchEvent)
{    
	return FReply::Unhandled();
}

For the other two touch events (Moved/Ended), it always returns FReply::Handled().

I’ll try fixing it by making a custom ScrollBox in C++ extending from this class and UScrollBox. If this works, we won’t have to use the engine source code. I’m not used to the Slate part of UEC++, but this seems an easy fix.

If my fix works, I’ll post the code here. My project is already C++ so it’s not that much of a hassle, but for those who want to use Blueprint only, I tried many workarounds and none worked. :frowning:

C++ Dirty Fix

By extending the original SScrollBox and UScrollBox classes, it’s possible to override the method causing the problem and fix it.

Add these modules to Source/YourProjectName/YourProjectName.Build.cs, at PublicDependencyModuleNames

"SlateCore", "Slate", "UMG"

To YourProjectName.h, add

#include "Engine.h" // already on file
#include "SlateBasics.h" // add this line after that

Add these code files to fix the problem on the Slate ScrollBox widget:

SCustomScrollBox.h

#pragma once
#include "Widgets/Layout/SScrollBox.h"

/**
 * Fixes ScrollBox bug of not registering TouchStarted event
 */
class YOURPROJECTNAME_API SCustomScrollBox : public SScrollBox
{
public:
	virtual FReply OnTouchStarted(
		const FGeometry& MyGeometry,
		const FPointerEvent& InTouchEvent) override;
};

SCustomScrollBox.cpp

#include "MineSweeper.h"
#include "SCustomScrollBox.h"

FReply SCustomScrollBox::OnTouchStarted(const FGeometry& MyGeometry, const FPointerEvent& InTouchEvent)
{
	return FReply::Handled();
}

To be able to use the fixed Slate widget in UMG, also extend the UScrollBox class and override the method that creates the Slate widget to use our custom class.

CustomScrollBox.h

#pragma once
#include "UMG.h"
#include "Components/ScrollBox.h"
#include "CustomScrollBox.generated.h"

/**
 * Fixes ScrollBox bug of not registering TouchStarted event
 */
UCLASS()
class YOURPROJECTNAME_API UCustomScrollBox : public UScrollBox
{
	GENERATED_BODY()
protected:
	//~ Begin UWidget Interface
	virtual TSharedRef<SWidget> RebuildWidget() override;
	//~ End UWidget Interface
public:
#if WITH_EDITOR
	//~ Begin UWidget Interface
	virtual const FText GetPaletteCategory() override;
	//~ End UWidget Interface
#endif
};

CustomScrollBox.cpp

#include "MineSweeper.h"
#include "SCustomScrollBox.h"
#include "CustomScrollBox.h"

#define LOCTEXT_NAMESPACE "UMG"

TSharedRef<SWidget> UCustomScrollBox::RebuildWidget()
{
	MyScrollBox = SNew(SCustomScrollBox)
		.Style(&WidgetStyle)
		.ScrollBarStyle(&WidgetBarStyle)
		.Orientation(Orientation)
		.ConsumeMouseWheel(ConsumeMouseWheel);

	for (UPanelSlot* PanelSlot : Slots)
	{
		if (UScrollBoxSlot* TypedSlot = Cast<UScrollBoxSlot>(PanelSlot))
		{
			TypedSlot->Parent = this;
			TypedSlot->BuildSlot(MyScrollBox.ToSharedRef());
		}
	}
	return BuildDesignTimeWidget(MyScrollBox.ToSharedRef());
}

#if WITH_EDITOR
const FText UCustomScrollBox::GetPaletteCategory()
{
	return LOCTEXT("User Created", "User Created");
}
#endif

This CustomScrollBox will be found in the User Created category of the Palette in the UMG Editor as Custom Scroll Box.

As it’s a child of the original ScrollBox, you can safely replace ScrollBoxes and its variables in your Blueprints. Easily replace existing ScrollBoxes in the Design mode by selecting the Custom Scroll Box in the Palette then right clicking on the current ScrollBox in the hierarchy and selecting Replace With…>Custom Scroll Box. The only drawback is that you’ll lose any customization done in the replaced ScrollBox’s Details panel (Style, Visibility etc).

Don’t forget to replace YOUPROJECTNAME_API in the code by your project’s API.

1 Like

Hi, RVillani
I’ve found a solution for my case in blueprint, my menu animation is 0.5 second long so I simply use sequence node and delay for a 0.5 seconds and it works perfect for my particular situation in other cases your approach maybe better. It will be good if Epic fix scrollbox functionality.

I found many errors on scrollbox working on my project but I wont lose time explaining in details. Project is ready and I hope to start open beta next month on PlayMarket. Take a look and say what you think.
link text

link text

Hi RVillani,

I’m trying to implement the SCustomScrollBox that inherit from SScrollBox, but I can’t find it. I mean, I can find the class in the project but when I try to create a class from it it doesn’t appear in the panel of UE where you create the class.

Also I’m not sure if I understand the all the code that I have to add to this new custom classes, Can you post the code of the two classes you’ve made?

Don’t try to extend it in the editor. I believe it doesn’t show slate classes. Create an object class or something and replace the imports, class name etc with the code in my post.