From 32f4c6a27827eac28d274d26c68a729835126b5a Mon Sep 17 00:00:00 2001 From: Maximilian Fajnberg Date: Sun, 16 Jan 2022 21:19:34 +0100 Subject: [PATCH] small changes to pathfinding; plan to fix bad performance --- AdventureMap.cpp | 36 +++++++++++++++++++++++++++-------- AdventurePlayerController.cpp | 27 ++++++++++++++++++++++++++ AdventurePlayerController.h | 14 ++++++++++++++ 3 files changed, 69 insertions(+), 8 deletions(-) diff --git a/AdventureMap.cpp b/AdventureMap.cpp index 5fbaf18..b2a1488 100644 --- a/AdventureMap.cpp +++ b/AdventureMap.cpp @@ -118,44 +118,64 @@ TArray AAdventureMap::FindPathAStar(AHexTile* Start, AHexTile* Goal) TArray Priorities; Priorities.Init(Start, 1); - Goal->CameFrom = Start; - // Editing Hex->CameFrom pointers, i.e. chaining Hexes - while (Priorities.IsValidIndex(0)) + while (!Priorities.IsEmpty()) { AHexTile* Current = Priorities[0]; Priorities.RemoveAt(0); - if (*Current == *Goal) { break; } + if (*Current == *Goal) + { + // UE_LOG(LogTemp, Warning, TEXT("Goal found!")); // debug + break; + } // Expanding the Frontier for (AHexTile* Next : Neighbors(Current)) { - int32 NewCost = Current->CostSoFar + Next->MoveCost; + int32 NewCost = Current->CostSoFar + Next->MoveCost; + + // UE_LOG(LogTemp, Warning, TEXT("Cost calculated.")); // debug + if (!Priorities.Contains(Next) || NewCost < Next->CostSoFar) { + // UE_LOG(LogTemp, Warning, TEXT("New candidate found.")); // debug + Next->CostSoFar = NewCost; int32 NewPrio = NewCost + Next->Distance(Goal); // Adjust the Priority Queue if (Priorities.Contains(Next)) { Priorities.Remove(Next); } - for (AHexTile* Hex : Priorities) + for (AHexTile* Hex : Priorities) // at this point Priorities is empty, need to make sure it's not. { int32 OldPrio = Hex->CostSoFar + Hex->Distance(Goal); int32 Index; Priorities.Find(Hex, Index); + // UE_LOG(LogTemp, Warning, TEXT("Comparing priorities...")); // debug + if (OldPrio > NewPrio) - { + { Priorities.Insert(Next, Index); Next->CameFrom = Current; + + // UE_LOG(LogTemp, Warning, TEXT("Looks promising!")); // debug + break; } if (Index == Priorities.Num() - 1 && OldPrio <= NewPrio) { Priorities.Emplace(Next); Next->CameFrom = Current; + + // UE_LOG(LogTemp, Warning, TEXT("Low prio added")); // debug + + break; } } + if (Priorities.IsEmpty()) + { + Priorities.Emplace(Next); + } } } } @@ -169,5 +189,5 @@ TArray AAdventureMap::FindPathAStar(AHexTile* Start, AHexTile* Goal) } Algo::Reverse(Path); - return Path; // currently always length of 1 + return Path; } diff --git a/AdventurePlayerController.cpp b/AdventurePlayerController.cpp index 56f926a..34fc26e 100644 --- a/AdventurePlayerController.cpp +++ b/AdventurePlayerController.cpp @@ -13,4 +13,31 @@ AAdventurePlayerController::AAdventurePlayerController() PrimaryActorTick.bCanEverTick = true; PrimaryActorTick.bStartWithTickEnabled = true; +} +void AAdventurePlayerController::BeginPlay() +{ + Super::BeginPlay(); + World = GetWorld(); +} + +void AAdventurePlayerController::SetupInputComponent() +{ + // Always call this. + Super::SetupInputComponent(); + + // This is initialized on startup, you can go straight to binding + InputComponent->BindAction("LeftClick", IE_Pressed, this, &AAdventurePlayerController::AdvClick); +} + +void AAdventurePlayerController::AdvClick() +{ + FHitResult Hit; + GetHitResultUnderCursor(ECollisionChannel::ECC_Vehicle,false,Hit); + + if (IsValid(Hit.GetActor())) + { + AHexTile* HitHex = (AHexTile*)Hit.GetActor(); + // MapRef->FindPathAStar(CurrentHex, HitHex); // this would currently cause a crash... + UE_LOG(LogTemp, Warning, TEXT("%d"), HitHex->Index); + } } \ No newline at end of file diff --git a/AdventurePlayerController.h b/AdventurePlayerController.h index 682fd59..f8cb075 100644 --- a/AdventurePlayerController.h +++ b/AdventurePlayerController.h @@ -23,5 +23,19 @@ class FRAY_API AAdventurePlayerController : public APlayerController public: AAdventurePlayerController(); + UPROPERTY() + UWorld* World; + UPROPERTY() + AAdventureMap* MapRef; + UPROPERTY() + AHexTile* SpawnHex; + UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Runtime") + AHexTile* CurrentHex; + +protected: + virtual void BeginPlay() override; + virtual void SetupInputComponent() override; + public: + void AdvClick(); };