[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を参照させるため、ここへずらす。 // 今回は暫定対応ですが、本格的に対応するならフラグを別に用意する等の対応をしたがほういいかも。 }