Download

Working with touchpad in BP - how ?

I know that the touchpad on Gear VR is basically a mouse (or used to be at least). So single click is easy to deal with :slight_smile:

How do I work with horizontal and vertical swipes ? (if it’s mouse, then it would be X and Y axes, which I assume I need to map in the Input section of Project Settings; but how to determine bounds/positive/negative axes?!)

Thanks

Here is the C++ version of that using InputTouch. I will probably post that on the wiki on the next few days.
I’am sure that i have a blueprint version somewhere as well, but the C++ version is optimized and tweaked.

VrPlayerController.h



UCLASS()
class GEARVRGAME_API AVrPlayerController : public APlayerController
{
	GENERATED_BODY()
	
public:

	AVrPlayerControllerBase();

	//Touchpad
	virtual bool InputTouch(uint32 Handle, ETouchType::Type Type, const FVector2D& TouchLocation, FDateTime DeviceTimestamp, uint32 TouchpadIndex) override;

	UFUNCTION(BlueprintImplementableEvent, meta = (Category = "GearVR", DisplayName = "GearVR Touchpad Press"))
	void TouchPadPress();

	UFUNCTION(BlueprintImplementableEvent, meta = (Category = "GearVR", DisplayName = "GearVR Touchpad Release"))
	void TouchPadRelease();

	UFUNCTION(BlueprintImplementableEvent, meta = (Category = "GearVR", DisplayName = "GearVR Touchpad Backward"))
	void TouchPadBack();

	UFUNCTION(BlueprintImplementableEvent, meta = (Category = "GearVR", DisplayName = "GearVR Touchpad Forward"))
	void TouchPadForward();

	UFUNCTION(BlueprintImplementableEvent, meta = (Category = "GearVR", DisplayName = "GearVR Touchpad Down"))
	void TouchPadDown();

	UFUNCTION(BlueprintImplementableEvent, meta = (Category = "GearVR", DisplayName = "GearVR Touchpad Up"))
	void TouchPadUp();

	UFUNCTION(BlueprintImplementableEvent, meta = (Category = "GearVR", DisplayName = "GearVR Touchpad Cancel"))
	void TouchPadCancel();

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float MinTouchDist;

	ETouchIndex::Type TouchIndex;
	float LastTouchPressTime;	
	bool bHasSwiped;
	bool bIsValidSwipe;
	bool bIsTouchPressed;
	FVector2D TouchStart;
	FVector2D TouchEnd;

};


VrPlayerController.cpp



AVrPlayerController::AVrPlayerController()
{
	MinTouchDist = 70.0;
}

bool AVrPlayerController::InputTouch(uint32 Handle, ETouchType::Type Type, const FVector2D& TouchLocation, FDateTime DeviceTimestamp, uint32 TouchpadIndex)
{
	if (PlayerInput == NULL)
		return false;

	bool bResult = false;
	UWorld* World = GetWorld();

	bResult = PlayerInput->InputTouch(Handle, Type, TouchLocation, DeviceTimestamp, TouchpadIndex);

	const ETouchIndex::Type FingerIndex = ETouchIndex::Type(Handle);

	if (FingerIndex != ETouchIndex::Touch1)
		return false;

	//Clear
	if (World->TimeSeconds - LastTouchPressTime > 0.5)
	{
		bIsValidSwipe = false;
	}

	if (Type == ETouchType::Began)
	{
		TouchIndex = FingerIndex;

		bIsValidSwipe = true;
		bHasSwiped = false;
		bIsTouchPressed = true;
		TouchStart = TouchLocation;
		LastTouchPressTime = World->TimeSeconds;

		TouchPadPress();
	}

	if (Type == ETouchType::Moved && TouchIndex == FingerIndex)
	{
		if ( bIsTouchPressed && (TouchStart - TouchLocation).Size() >= MinTouchDist )
		{
			if (!bHasSwiped && bIsValidSwipe)
			{
				FVector2D TouchDir = (TouchStart - TouchLocation);

				if (FMath::Abs(TouchDir.X) > FMath::Abs(TouchDir.Y))
				{
					if (TouchDir.X > 0)
					{
						TouchPadForward();
					}
					else
					{
						TouchPadBack();
					}
				}
				else
				{
					if (TouchDir.Y > 0)
					{
						TouchPadUp();
					}
					else
					{
						TouchPadDown();
					}
				}
			}
			else
			{
				if (!bHasSwiped)
				{
					TouchPadCancel();
				}
			}

			bHasSwiped = true;
		}
	}
	
	if (Type == ETouchType::Ended && TouchIndex == FingerIndex)
	{
		bIsTouchPressed = false;

		if (!bHasSwiped)
		{
			TouchPadRelease();
		}
	}

	return bResult;
}



Thanks, but unfortunately I don’t do C++ :frowning:

If it was a plugin that allows using BP for input, it would be cool :slight_smile:

Here’s the BP solution I used:

It works for registering the swipe on release

Alright, I was hoping to avoid using touch at all (since in Unity mouse input is used for touchpad, I figured it would be nice to get away with that on UE4 too), but it’s not happening :confused:
@aussieburger: In what way do you use enums in your setup and why ?

That is just so I can store whether it was: left / right / up / down swipe in a variable and can use it later in whatever function you then want to use. Where you see those enums print the enum to the screen and you’ll see the correct ‘label’ depending on the direction of your swipe :slight_smile:

I see. So basically instead of using 4 different vars you use 1 enum, correct?

Do you call custom event “Handle Swipe Input” at the end of the flow ?

How did you determine the delta of finger movement across the touchpad? (I assume empirically)

Thanks