Announcement

Collapse
No announcement yet.

Problem with generating a grid for A* algorithm

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Problem with generating a grid for A* algorithm

    Hello. I'm having problems with generating a grid made out of nodes (GridNode). I have a GridNode actor, which has some variables inside. In my Grid.h I included GridNode.h and declared it as AGridNode* GridNode. As well, I made TMap called Grid, to pair FIntPoint (gridIndex) with AGridNode*. Now, I made a function called SetNodeData to initialize values inside GrindNode, and to pass(.add) this info into the TMap, along with the gridIndex as the first argument. This function is then used in CreateGrid function, which has a nested for loop, where the collision check happens and the calculations for location and index are made and passed into the SetNodeData function. From here, when testing the grid, UE crashes. Now, I pretty sure this is a pointer issue, but I just can't solve it.

    GridNode.h
    Code:
    #include "CoreMinimal.h"
    #include "GameFramework/Actor.h"
    #include "GridNode.generated.h"
    
    UCLASS()
    class ASTAR_API AGridNode : public AActor
    {
        GENERATED_BODY()
    
    public:    
        // Sets default values for this actor's properties
        AGridNode();
        UPROPERTY()
        bool bWalkable;
        UPROPERTY()
        FVector WorldPosition;
        UPROPERTY()
        FIntPoint GridIndex;
        UPROPERTY()
        int32 GCost;
        UPROPERTY()
        int32 HCost;
    
        UPROPERTY()
        AGridNode* Parent;
        UFUNCTION()
        int32 FCost() { return GCost + HCost; }
    
    protected:
        // Called when the game starts or when spawned
        virtual void BeginPlay() override;
    
    public:    
        // Called every frame
        virtual void Tick(float DeltaTime) override;
    
    };
    Grid.h
    Code:
        
        typedef FIntPoint FGridNodeCoord;
    
        AGridNode* GridNode = nullptr;
        void SetNodeData(FVector worldPos, FGridNodeCoord gridIndex, bool isWalkable);
        // Structs and TMap
        struct FSphereTraceReturn SphereTraceReturn;
        TMap< FGridNodeCoord, AGridNode*> Grid;
    Grid.cpp
    Code:
    void AGrid::CreateGrid()
    {
        for (int32 x = 0; x <= FMath::RoundToInt((GridWorldSize.X / NodeDiameter) -1); x++)
        {
            for (int32 y = 0; y <= FMath::RoundToInt((GridWorldSize.Y / NodeDiameter) -1); y++)
            {    
                bool bIsWalkable;
    
                FGridNodeCoord GridIndexTemp = FGridNodeCoord(x, y);
                FVector WorldPoint = (GridBottomLeft()
                    +
                    (SceneComponent->GetRightVector() * ((x * (NodeDiameter * 2)) + NodeDiameter))
                    +
                    (SceneComponent->GetForwardVector() * ((y * (NodeDiameter * 2)) + NodeDiameter)));
    
    
                // Trace to ground channel
                MySphereTrace(false, WorldPoint, ECollisionChannel::ECC_GameTraceChannel1);
    
                if (SphereTraceReturn.HitSomething == true) // Check if it was hit with ground.
                {
                    //DrawDebugBox(InWorld, WorldPoint, FVector(20, 20, 20), FColor::Red, true, 100000, 0, 5);
                    // Trace to obstacle channel
                    MySphereTrace(false, WorldPoint, ECollisionChannel::ECC_GameTraceChannel2);
    
                    if (SphereTraceReturn.HitSomething==true) // Check if there was an bbstacle hit
                    {
                        // Checking on hits actor is AObstacle
                        auto obstacle = Cast<AObstacle>(SphereTraceReturn.Actor);
    
                        if (obstacle)
                        {
                            obstacle->GridPtr = this; // Sets himself to Obstacle's Grid Pointer
    
                            bIsWalkable = !(SphereTraceReturn.HitSomething);
    
                            SetNodeData(WorldPoint, GridIndexTemp, bIsWalkable);
                        }
                    }
                    else // If Hits Ground, but no Obstacle.
                    {
                        bIsWalkable = (SphereTraceReturn.HitSomething);
                        SetNodeData(WorldPoint, GridIndexTemp, bIsWalkable);
                    }
                }        
                else // If it doesn't hit anything on the Ground Channel.
                {
                    bIsWalkable = (SphereTraceReturn.HitSomething);
                    SetNodeData(WorldPoint, GridIndexTemp, bIsWalkable);
                }
            }
        }
    }
    
    void AGrid::SetNodeData(FVector worldPos, FGridNodeCoord gridIndex, bool isWalkable)
    {
    
        GridNode->WorldPosition = worldPos;
        GridNode->GridIndex = gridIndex;
        GridNode->bWalkable = isWalkable;
    
        Grid.Add(gridIndex, GridNode);
    
    }
    Last edited by reeson46; 02-26-2020, 07:46 AM.
Working...
X