[UnrealEngine5.0.2][Windows11]で確認
UE5のサンプルTopDownテンプレートが、Androidだとタッチした箇所に移動しなかった。
タッチした方向には移動します。
調査して対応してみました。
C++版で確認しています。プロジェクト名はTopDownTestにしています。
TopDownTestPlayerController.h
FVector HitTouchLocation; を追加。
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Templates/SubclassOf.h"
#include "GameFramework/PlayerController.h"
#include "TopDownTestPlayerController.generated.h"
/** Forward declaration to improve compiling times */
class UNiagaraSystem;
UCLASS()
class ATopDownTestPlayerController : public APlayerController
{
GENERATED_BODY()
public:
ATopDownTestPlayerController();
/** Time Threshold to know if it was a short press */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input)
float ShortPressThreshold;
/** FX Class that we will spawn when clicking */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input)
UNiagaraSystem* FXCursor;
protected:
/** True if the controlled character should navigate to the mouse cursor. */
uint32 bMoveToMouseCursor : 1;
// Begin PlayerController interface
virtual void PlayerTick(float DeltaTime) override;
virtual void SetupInputComponent() override;
// End PlayerController interface
/** Input handlers for SetDestination action. */
void OnSetDestinationPressed();
void OnSetDestinationReleased();
void OnTouchPressed(const ETouchIndex::Type FingerIndex, const FVector Location);
void OnTouchReleased(const ETouchIndex::Type FingerIndex, const FVector Location);
private:
bool bInputPressed; // Input is bring pressed
bool bIsTouch; // Is it a touch device
float FollowTime; // For how long it has been pressed
FVector HitTouchLocation; // PlayerTickで保存する
};
TopDownTestPlayerController.cpp
PlayerTickに Hit.Location を HitTouchLocation に保存する処理を追加。
OnSetDestinationReleased に HitTouchLocation を 参照する処理を追加。
OnTouchReleasedで bIsTouch = false; を下へずらす。
今回は暫定対応ですが、本格的に対応するなら bIsTouch の代わりにフラグを別に用意する等の対応をしたがほういいかも。
// Copyright Epic Games, Inc. All Rights Reserved.
#include "TopDownTestPlayerController.h"
#include "GameFramework/Pawn.h"
#include "Blueprint/AIBlueprintHelperLibrary.h"
#include "NiagaraSystem.h"
#include "NiagaraFunctionLibrary.h"
#include "TopDownTestCharacter.h"
#include "Engine/World.h"
#include "Kismet/KismetSystemLibrary.h"
ATopDownTestPlayerController::ATopDownTestPlayerController()
{
bShowMouseCursor = true;
DefaultMouseCursor = EMouseCursor::Default;
}
void ATopDownTestPlayerController::PlayerTick(float DeltaTime)
{
Super::PlayerTick(DeltaTime);
if(bInputPressed)
{
FollowTime += DeltaTime;
// Look for the touch location
FVector HitLocation = FVector::ZeroVector;
FHitResult Hit;
if(bIsTouch)
{
GetHitResultUnderFinger(ETouchIndex::Touch1, ECC_Visibility, true, Hit);
#if 0 // FollowTimeやタッチした座標を表示する。
{
// UKismetSystemLibrary::PrintString(this, "C++ Hello World!", true, true, FColor::Cyan, 2.f);
FString Str = FString::SanitizeFloat(FollowTime);
UKismetSystemLibrary::PrintString(this, Str, true, true, FColor::Green, 5.f);
FString Str2 = FString::SanitizeFloat(Hit.Location.X) + FString(" ") + FString::SanitizeFloat(Hit.Location.Y) + FString(" ") + FString::SanitizeFloat(Hit.Location.Z);
UKismetSystemLibrary::PrintString(this, Str2, true, true, FColor::Green, 5.f);
}
#endif
HitTouchLocation = Hit.Location; // Released時に使うために保存する。
}
else
{
GetHitResultUnderCursor(ECC_Visibility, true, Hit);
}
HitLocation = Hit.Location;
// Direct the Pawn towards that location
APawn* const MyPawn = GetPawn();
if(MyPawn)
{
FVector WorldDirection = (HitLocation - MyPawn->GetActorLocation()).GetSafeNormal();
MyPawn->AddMovementInput(WorldDirection, 1.f, false);
}
}
else
{
FollowTime = 0.f;
}
}
void ATopDownTestPlayerController::SetupInputComponent()
{
// set up gameplay key bindings
Super::SetupInputComponent();
InputComponent->BindAction("SetDestination", IE_Pressed, this, &ATopDownTestPlayerController::OnSetDestinationPressed);
InputComponent->BindAction("SetDestination", IE_Released, this, &ATopDownTestPlayerController::OnSetDestinationReleased);
// support touch devices
InputComponent->BindTouch(EInputEvent::IE_Pressed, this, &ATopDownTestPlayerController::OnTouchPressed);
InputComponent->BindTouch(EInputEvent::IE_Released, this, &ATopDownTestPlayerController::OnTouchReleased);
}
void ATopDownTestPlayerController::OnSetDestinationPressed()
{
// We flag that the input is being pressed
bInputPressed = true;
// Just in case the character was moving because of a previous short press we stop it
StopMovement();
}
void ATopDownTestPlayerController::OnSetDestinationReleased()
{
// Player is no longer pressing the input
bInputPressed = false;
// If it was a short press
if(FollowTime <= ShortPressThreshold)
{
// We look for the location in the world where the player has pressed the input
FVector HitLocation = FVector::ZeroVector;
FHitResult Hit;
if (bIsTouch)
{
// タッチの場合、Releaseされた後だとHit.Locationは(0.0f, 0.0f, 0.0f)となるので、
//GetHitResultUnderFinger(ETouchIndex::Touch1, ECC_Visibility, true, Hit);
//HitLocation = Hit.Location;
// PlayerTickで保存しておいたのものを使う。
HitLocation = HitTouchLocation;
}
else
{
GetHitResultUnderCursor(ECC_Visibility, true, Hit);
HitLocation = Hit.Location;
}
// We move there and spawn some particles
UAIBlueprintHelperLibrary::SimpleMoveToLocation(this, HitLocation);
UNiagaraFunctionLibrary::SpawnSystemAtLocation(this, FXCursor, HitLocation, FRotator::ZeroRotator, FVector(1.f, 1.f, 1.f), true, true, ENCPoolMethod::None, true);
}
}
void ATopDownTestPlayerController::OnTouchPressed(const ETouchIndex::Type FingerIndex, const FVector Location)
{
bIsTouch = true;
OnSetDestinationPressed();
}
void ATopDownTestPlayerController::OnTouchReleased(const ETouchIndex::Type FingerIndex, const FVector Location)
{
// bIsTouch = false;
OnSetDestinationReleased();
bIsTouch = false; // OnSetDestinationReleased()でHitTouchLocationを参照させるため、ここへずらす。
// 今回は暫定対応ですが、本格的に対応するならフラグを別に用意する等の対応をしたがほういいかも。
}
