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
#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
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
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);
}