2022年6月23日木曜日

UE5のTopDownがAndroidでタッチした箇所に移動しない

[UnrealEngine5.0.2][Windows11]で確認

UE5のサンプルTopDownテンプレートが、Androidだとタッチした箇所に移動しなかった。

タッチした方向には移動します。


調査して対応してみました。

C++版で確認しています。プロジェクト名はTopDownTestにしています。


TopDownTestPlayerController.h
FVector HitTouchLocation; を追加。

  1. // Copyright Epic Games, Inc. All Rights Reserved.
  2.  
  3. #pragma once
  4.  
  5. #include "CoreMinimal.h"
  6. #include "Templates/SubclassOf.h"
  7. #include "GameFramework/PlayerController.h"
  8. #include "TopDownTestPlayerController.generated.h"
  9.  
  10. /** Forward declaration to improve compiling times */
  11. class UNiagaraSystem;
  12.  
  13. UCLASS()
  14. class ATopDownTestPlayerController : public APlayerController
  15. {
  16. GENERATED_BODY()
  17.  
  18. public:
  19. ATopDownTestPlayerController();
  20.  
  21. /** Time Threshold to know if it was a short press */
  22. UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input)
  23. float ShortPressThreshold;
  24.  
  25. /** FX Class that we will spawn when clicking */
  26. UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input)
  27. UNiagaraSystem* FXCursor;
  28.  
  29. protected:
  30. /** True if the controlled character should navigate to the mouse cursor. */
  31. uint32 bMoveToMouseCursor : 1;
  32.  
  33. // Begin PlayerController interface
  34. virtual void PlayerTick(float DeltaTime) override;
  35. virtual void SetupInputComponent() override;
  36. // End PlayerController interface
  37.  
  38. /** Input handlers for SetDestination action. */
  39. void OnSetDestinationPressed();
  40. void OnSetDestinationReleased();
  41. void OnTouchPressed(const ETouchIndex::Type FingerIndex, const FVector Location);
  42. void OnTouchReleased(const ETouchIndex::Type FingerIndex, const FVector Location);
  43.  
  44. private:
  45. bool bInputPressed; // Input is bring pressed
  46. bool bIsTouch; // Is it a touch device
  47. float FollowTime; // For how long it has been pressed
  48.  
  49. FVector HitTouchLocation; // PlayerTickで保存する
  50. };


TopDownTestPlayerController.cpp
PlayerTickに Hit.Location を HitTouchLocation に保存する処理を追加。
OnSetDestinationReleased に HitTouchLocation を 参照する処理を追加。
OnTouchReleasedで bIsTouch = false; を下へずらす。
今回は暫定対応ですが、本格的に対応するなら bIsTouch の代わりにフラグを別に用意する等の対応をしたがほういいかも。

  1. // Copyright Epic Games, Inc. All Rights Reserved.
  2.  
  3. #include "TopDownTestPlayerController.h"
  4. #include "GameFramework/Pawn.h"
  5. #include "Blueprint/AIBlueprintHelperLibrary.h"
  6. #include "NiagaraSystem.h"
  7. #include "NiagaraFunctionLibrary.h"
  8. #include "TopDownTestCharacter.h"
  9. #include "Engine/World.h"
  10.  
  11. #include "Kismet/KismetSystemLibrary.h"
  12.  
  13. ATopDownTestPlayerController::ATopDownTestPlayerController()
  14. {
  15. bShowMouseCursor = true;
  16. DefaultMouseCursor = EMouseCursor::Default;
  17. }
  18.  
  19. void ATopDownTestPlayerController::PlayerTick(float DeltaTime)
  20. {
  21. Super::PlayerTick(DeltaTime);
  22.  
  23. if(bInputPressed)
  24. {
  25. FollowTime += DeltaTime;
  26.  
  27. // Look for the touch location
  28. FVector HitLocation = FVector::ZeroVector;
  29. FHitResult Hit;
  30. if(bIsTouch)
  31. {
  32. GetHitResultUnderFinger(ETouchIndex::Touch1, ECC_Visibility, true, Hit);
  33. #if 0 // FollowTimeやタッチした座標を表示する。
  34. {
  35. // UKismetSystemLibrary::PrintString(this, "C++ Hello World!", true, true, FColor::Cyan, 2.f);
  36. FString Str = FString::SanitizeFloat(FollowTime);
  37. UKismetSystemLibrary::PrintString(this, Str, true, true, FColor::Green, 5.f);
  38. FString Str2 = FString::SanitizeFloat(Hit.Location.X) + FString(" ") + FString::SanitizeFloat(Hit.Location.Y) + FString(" ") + FString::SanitizeFloat(Hit.Location.Z);
  39. UKismetSystemLibrary::PrintString(this, Str2, true, true, FColor::Green, 5.f);
  40. }
  41. #endif
  42. HitTouchLocation = Hit.Location; // Released時に使うために保存する。
  43. }
  44. else
  45. {
  46. GetHitResultUnderCursor(ECC_Visibility, true, Hit);
  47. }
  48. HitLocation = Hit.Location;
  49.  
  50. // Direct the Pawn towards that location
  51. APawn* const MyPawn = GetPawn();
  52. if(MyPawn)
  53. {
  54. FVector WorldDirection = (HitLocation - MyPawn->GetActorLocation()).GetSafeNormal();
  55. MyPawn->AddMovementInput(WorldDirection, 1.f, false);
  56. }
  57. }
  58. else
  59. {
  60. FollowTime = 0.f;
  61. }
  62. }
  63.  
  64. void ATopDownTestPlayerController::SetupInputComponent()
  65. {
  66. // set up gameplay key bindings
  67. Super::SetupInputComponent();
  68.  
  69. InputComponent->BindAction("SetDestination", IE_Pressed, this, &ATopDownTestPlayerController::OnSetDestinationPressed);
  70. InputComponent->BindAction("SetDestination", IE_Released, this, &ATopDownTestPlayerController::OnSetDestinationReleased);
  71.  
  72. // support touch devices
  73. InputComponent->BindTouch(EInputEvent::IE_Pressed, this, &ATopDownTestPlayerController::OnTouchPressed);
  74. InputComponent->BindTouch(EInputEvent::IE_Released, this, &ATopDownTestPlayerController::OnTouchReleased);
  75.  
  76. }
  77.  
  78. void ATopDownTestPlayerController::OnSetDestinationPressed()
  79. {
  80. // We flag that the input is being pressed
  81. bInputPressed = true;
  82. // Just in case the character was moving because of a previous short press we stop it
  83. StopMovement();
  84. }
  85.  
  86. void ATopDownTestPlayerController::OnSetDestinationReleased()
  87. {
  88. // Player is no longer pressing the input
  89. bInputPressed = false;
  90.  
  91. // If it was a short press
  92. if(FollowTime <= ShortPressThreshold)
  93. {
  94. // We look for the location in the world where the player has pressed the input
  95. FVector HitLocation = FVector::ZeroVector;
  96. FHitResult Hit;
  97.  
  98. if (bIsTouch)
  99. {
  100. // タッチの場合、Releaseされた後だとHit.Locationは(0.0f, 0.0f, 0.0f)となるので、
  101. //GetHitResultUnderFinger(ETouchIndex::Touch1, ECC_Visibility, true, Hit);
  102. //HitLocation = Hit.Location;
  103. // PlayerTickで保存しておいたのものを使う。
  104. HitLocation = HitTouchLocation;
  105. }
  106. else
  107. {
  108. GetHitResultUnderCursor(ECC_Visibility, true, Hit);
  109. HitLocation = Hit.Location;
  110. }
  111.  
  112. // We move there and spawn some particles
  113. UAIBlueprintHelperLibrary::SimpleMoveToLocation(this, HitLocation);
  114. UNiagaraFunctionLibrary::SpawnSystemAtLocation(this, FXCursor, HitLocation, FRotator::ZeroRotator, FVector(1.f, 1.f, 1.f), true, true, ENCPoolMethod::None, true);
  115. }
  116. }
  117.  
  118. void ATopDownTestPlayerController::OnTouchPressed(const ETouchIndex::Type FingerIndex, const FVector Location)
  119. {
  120. bIsTouch = true;
  121. OnSetDestinationPressed();
  122. }
  123.  
  124. void ATopDownTestPlayerController::OnTouchReleased(const ETouchIndex::Type FingerIndex, const FVector Location)
  125. {
  126. // bIsTouch = false;
  127. OnSetDestinationReleased();
  128. bIsTouch = false; // OnSetDestinationReleased()でHitTouchLocationを参照させるため、ここへずらす。
  129. // 今回は暫定対応ですが、本格的に対応するならフラグを別に用意する等の対応をしたがほういいかも。
  130. }

ジオメトリスクリプト(Geometry Script)の学習

  [UnrealEngine5.5.3][Windows11]で確認  全般・基本 【UE5】エディターで編集できるGeometry Toolを作成する 【UE5】UE5のアニメーションに関する新機能をサクッと試せるサンプルを公開しました! コリジョンを使う時 DynamicM...