IE_Repeat Touch Input Bug in PIE, works fine in standalone build

Hey, Originally posted as a question in C++ forum but came to realize this is indeed a bug within the editor itself.

Before I begin, I should mention I have the “Use mouse for touch” option checked to true in the project settings → input settings.

What Happens

I bind the touch actions IE_Pressed, IE_Repeat and IE_Released to their respective callback methods within my PlayerController class, When playing in editor only the IE_Pressed and IE_Released methods ever get called IF I keep the mouse within the view-port. However, If I press the mouse down in the view-port, keep it held down and move it outside the view-port and release the button… When the cursor re-enters the view-port it will trigger the IE_Repeat callbacks (even with the mouse up) which, of course, is still incorrect behavior… However, from that point on-wards all 3 actions behave as expected (IE_Pressed triggers when you click the mouse button, IE_Repeat is called for as long as you keep the mouse button down and IE_Released is triggered when you let go of the mouse button.

Here is a video demonstrating this (the on-screen debug messages are printed from within “MyOnTouchHeld” (IE_Repeat) callback.


While this is an issue in the editor, the mouse/touch behavior works as intended in the standalone (windows x64 in this case) build.
Video of standalone behavior: - YouTube

Steps to Reproduce

  1. Press and hold mouse button down in editor view-port (notice no IE_Repeat actions are dispatched)
  2. Press and hold mouse button down
  3. Move mouse (with mouse button held down) outside of the view-port
  4. Release mouse button
  5. Move mouse back inside view-port (notice IE_Repeat actions being dispatched with the button up)
  6. Click Mouse button
  7. Hold Mouse Button and notice IE_Repeat correctly being dispatched

Additional Info

I have been trying to get this working for around 4 days now, even trying to per frame data from the Touches array from the PlayerInput instance stored in the player controller but that to only seems to update when the touch is pressed and not held (similar behavior as mentioned above).

EDIT:: Out of curiosity I put this into Blueprints, the exact same thing happens when I use the following node setup in my GameMode blueprint. Set this up, run the game and follow the steps to reproduce.

Source Code

I’ll paste the code so you can see what is going on.

Thanks,
Nick Cullen

TruckPlayerController.h

#include "GameFramework/PlayerController.h"
#include "TruckPlayerController.generated.h"

/**
 * 
 */
UCLASS()
class ANGRYICECREAMMOB_API ATruckPlayerController : public APlayerController
{
	GENERATED_BODY()

public:
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
	int32 TouchCount;		// Number of inputs given

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
	FVector2D ScreenSpaceLocation;	// Screen space of cursor

private:
	// Process ScreenSpaceLocation
	void ProcessInput();

public:
	// Constructor
	ATruckPlayerController();
	
	// Controller interface
	virtual void PlayerTick(float DeltaTime) override;		// Called per frame
	virtual void SetupInputComponent() override;			// Initial action callbacks

	// Action callbacks
	void MyOnTouchDown(const ETouchIndex::Type FingerIndex, const FVector Location);
	void MyOnTouchHeld(const ETouchIndex::Type FingerIndex, const FVector Location);
	void MyOnTouchUp(const ETouchIndex::Type FingerIndex, const FVector Location);

	UFUNCTION()
	void SetForwardTarget(FVector TargetWorldPos);
};

TruckPlayerController.cpp

#include "AngryIceCreamMob.h"
#include "TruckPlayerController.h"
#include "Truck.h"
#include "TruckMovement.h"

ATruckPlayerController::ATruckPlayerController()
{
	bShowMouseCursor = true;	// We always want to show mouse cursor
	bEnableClickEvents = true;
	bEnableTouchEvents = true;
	
	// Defaults
	TouchCount = 0;
}

void ATruckPlayerController::PlayerTick(float DeltaTime)
{
	Super::PlayerTick(DeltaTime);

	if (TouchCount > 0)
	{
		ProcessInput();
	}
}

void ATruckPlayerController::ProcessInput()
{
	
	// Get our world space hit result from input
	FHitResult HitResult;
	GetHitResultAtScreenPosition(ScreenSpaceLocation, CurrentClickTraceChannel, true, HitResult);

	// Only do if we hit something in the world
	if (HitResult.bBlockingHit)
	{
		if(TouchCount == 1)
			SetForwardTarget(HitResult.ImpactPoint);
	}
}

void ATruckPlayerController::SetupInputComponent()
{
	Super::SetupInputComponent();

	if (InputComponent)
	{
		InputComponent->BindTouch(EInputEvent::IE_Pressed, this, &ATruckPlayerController::MyOnTouchDown);
		InputComponent->BindTouch(EInputEvent::IE_Repeat, this, &ATruckPlayerController::MyOnTouchHeld);
		InputComponent->BindTouch(EInputEvent::IE_Released, this, &ATruckPlayerController::MyOnTouchUp);
	}
	
}

void ATruckPlayerController::MyOnTouchDown(const ETouchIndex::Type FingerIndex, const FVector Location)
{
	TouchCount++;
	ScreenSpaceLocation = FVector2D(Location.X, Location.Y);
	
}

void ATruckPlayerController::MyOnTouchHeld(const ETouchIndex::Type FingerIndex, const FVector Location)
{
	ScreenSpaceLocation = FVector2D(Location.X, Location.Y);
	FString str = "IE_Repeat ScreenSpaceLocation = " + ScreenSpaceLocation.ToString();
	print(str);
}

void ATruckPlayerController::MyOnTouchUp(const ETouchIndex::Type FingerIndex, const FVector Location)
{
	TouchCount--;
}

void ATruckPlayerController::SetForwardTarget(FVector TargetWorldPos)
{
	if (ATruck* Truck = Cast<ATruck>(GetPawn()))
	{
		if (UTruckMovement* Movement = Truck->GetTruckMovementComponent())
		{
			Movement->SetTargetPosition(TargetWorldPos);
		}
	}
}

I would like to add that I have worked around this by using GetHitResultUnderCursor in my Tick function! It works and correctly updates per frame :slight_smile:

I did however initially attempt to use GetHitResultUnderTouch but this was giving me the same issue as described earlier in editor. It would only result in the position stored when I first pressed the mouse button… Having set to use mouse as touch in the input settings, I would expect this to work in editor. As GetHitResultUnderTouch works fine in a standalone build :confused:

Thanks,
Nick

Hey -

The issue with the touch repeat event is a known issue (UE-29243) however we do not have a time frame of when this will be fixed.

Cheers