Download

How to properly include Header created by me into my project?

I’ve created a .h called WormHelperFunctions.h which is stored under Worm/Source/Worm folder inside my project and added the
#include “WormHelperFunctions.generated.h” line as instructed by a random topic online (though I have no “WormHelperFunctions.generated.h” file anywhere).
I’ve clicked Worm.uproject and did GenerateVisualStudio Project Files.
I’ve did #include “WormHelperFunctions.h” from my Pawn class generated from inside the engine, in the hope that this enable me to see those functions from inside the player blueprint editor.
But I’m getting an error when I compile, my .h and the error are both below.
Help please :slight_smile:

.h:


#pragma once
#include "Engine/World.h"
#include "Classes/Kismet/KismetSystemLibrary.h"
#include "WormGameMode.h"
#include "WormHelperFunctions.generated.h"

//Given a position in the world, returns [row][column]ID inside the GridSlotsOccupiedMap grid.
//FVector(0.f,0.f,0.f) is the center inside the 2D Array, the 2DArray is expected to have and ODD number of elements.
UFUNCTION(BlueprintPure, Category = "Grid")
void WorldLocationToGridID(AWormGameMode* GameMode, FVector Location, int& Row, int& Column)
{
    int RowMiddleID = (GameMode->GridHeight / GameMode->GridBlockSize) / 2;
    int ColumnMiddleID = (GameMode->GridWidth / GameMode->GridBlockSize) / 2;
    int GridBlockSize = GameMode->GridBlockSize;
    //------------------------------------------

    Row = -Location.Z / GridBlockSize + RowMiddleID;
    Column = Location.X / GridBlockSize + ColumnMiddleID;
}


//Display red wireframe cubes at the occupied position in the grid marked inside GridSlotsOccupiedMap
UFUNCTION(BlueprintCallable, Category = "Debug")
void DebugMarkOccupiedBlocks(AWormGameMode* GameMode)
{
    TArray<TArrayBool> GridSlotsOccupiedMap = GameMode->GetGridSlotsOccupiedMap();
    int GridWidth = GameMode->GridWidth;
    int GridHeight = GameMode->GridHeight;
    int GridBlockSize = GameMode->GridBlockSize;
    int XMiddleID = (GridWidth / GridBlockSize) / 2;
    int YMiddleID = (GridHeight / GridBlockSize) / 2;
    //-----------------------------------------------

    for (int row = 0; row < GridSlotsOccupiedMap.Num(); row++)
    {

        for (int column = 0; column < GridSlotsOccupiedMap[0].BoolRow.Num(); column++)
        {
            float X = (-XMiddleID + column) * GridBlockSize;
            float Z = (YMiddleID - row) * GridBlockSize;
            FVector Center = FVector(X, 50.f, Z + GridBlockSize/2);

            if (GridSlotsOccupiedMap[row][column])
            {
                UE_LOG(LogTemp, Warning, TEXT("Block%i]%i] is occupied"), row, column)
                    UKismetSystemLibrary::DrawDebugBox(GetWorld(),
                                                       Center, FVector(5.7f, 5.7f, 5.7f),
                                                       FColor::Red, FRotator::ZeroRotator, 0.f, 0);
            }
        }
    }
}

Error:

Ok, solved, the answer is to create the c++ class in the engine and inherit from UBlueprintFunctionLibrary xD

I prepare demo for u, but it’s late. Just for other guys:)

header:

#pragma once

#include “CoreMinimal.h”
#include “Kismet/BlueprintFunctionLibrary.h”
#include “BPFuncDemoLib.generated.h”

/**
*
*/
UCLASS()
class BPCPPINTEROPDEMO_API UBPFuncDemoLib : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category = “UBPFuncDemoLib”)
static void CallableFuncTest();

UFUNCTION(BlueprintPure, Category = “UBPFuncDemoLib”)
static bool PureFuncTest();
};

cpp:

#include “BPFuncDemoLib.h”

#include “Engine.h”

void UBPFuncDemoLib::CallableFuncTest()
{
if (nullptr != GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Green, TEXT(“Call CallableFuncTest()”));
}
}

bool UBPFuncDemoLib::PureFuncTest()
{
if (nullptr != GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Green, TEXT(“Call PureFuncTest()”));
}

return true;
}

Thanks anyway unvirtual, I appreciate :slight_smile:

Actually I’m having a second problem, maybe you know how to solve that, I’ll aks :smiley:

Below is my .h and .cpp, and the first function is making Unreal Engine Crash.
the line


AWormGameMode* GameMode = static_cast<AWormGameMode*>(World->GetAuthGameMode());

is the breaking point, actually after it, when I try to access one of the public member variables like for example in the line below where I call GameMode->GridHeight, the code breaks, Unreal crash and I have no idea why :S
Any guess? :confused:

WormHelperFunctions.h:


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Classes/Kismet/KismetSystemLibrary.h"
#include "WormGameMode.h"
#include "WormHelperFunctions.generated.h"

/**
 *
 */
UCLASS()
class WORM_API UWormHelperFunctions : public UBlueprintFunctionLibrary
{
    GENERATED_BODY()

        //Given a position in the world, returns [row][column]ID inside the GridSlotsOccupiedMap grid.
        //FVector(0.f,0.f,0.f) is the center inside the 2D Array, the 2DArray is expected to have and ODD number of elements.
        UFUNCTION(BlueprintPure, BlueprintCallable, Category = "Grid", meta = (WorldContext = "WorldContextObject"))
        static void WorldLocationToGridID(UObject* WorldContextObject, FVector Location, int& Row, int& Column);


    //Display red wireframe cubes at the occupied position in the grid marked inside GridSlotsOccupiedMap
    UFUNCTION(BlueprintCallable, Category = "Debug", meta = (WorldContext = "WorldContextObject"))
        static void DebugMarkOccupiedBlocks(AWormGameMode* GameMode, UObject* WorldContextObject);

};


WormHelperFunctions.cpp:


// Fill out your copyright notice in the Description page of Project Settings.

#include "WormHelperFunctions.h"
#include "Engine/World.h"

void UWormHelperFunctions::WorldLocationToGridID(UObject* WorldContextObject, FVector Location, int& Row, int& Column)
{
    UWorld* World = (UWorld*)WorldContextObject;
    AWormGameMode* GameMode = static_cast<AWormGameMode*>(World->GetAuthGameMode());
    if (GameMode->IsValidLowLevel())
    {
        int RowMiddleID = (GameMode->GridHeight / GameMode->GridBlockSize) / 2;
        int ColumnMiddleID = (GameMode->GridWidth / GameMode->GridBlockSize) / 2;
        int GridBlockSize = GameMode->GridBlockSize;
        ------------------------------------------

        Row = -Location.Z / GridBlockSize + RowMiddleID;
        Column = Location.X / GridBlockSize + ColumnMiddleID;
    }
}



void UWormHelperFunctions::DebugMarkOccupiedBlocks(AWormGameMode* GameMode, UObject* WorldContextObject)
{
    TArray<TArrayBool> GridSlotsOccupiedMap = GameMode->GetGridSlotsOccupiedMap();
    int GridWidth = GameMode->GridWidth;
    int GridHeight = GameMode->GridHeight;
    int GridBlockSize = GameMode->GridBlockSize;
    int XMiddleID = (GridWidth / GridBlockSize) / 2;
    int YMiddleID = (GridHeight / GridBlockSize) / 2;
    //-----------------------------------------------

    for (int row = 0; row < GridSlotsOccupiedMap.Num(); row++)
    {

        for (int column = 0; column < GridSlotsOccupiedMap[0].BoolRow.Num(); column++)
        {
            float X = (-XMiddleID + column) * GridBlockSize;
            float Z = (YMiddleID - row) * GridBlockSize;
            FVector Center = FVector(X, 50.f, Z + GridBlockSize / 2);

            if (GridSlotsOccupiedMap[row][column])
            {
                UE_LOG(LogTemp, Warning, TEXT("Block%i]%i] is occupied"), row, column)
                    UKismetSystemLibrary::DrawDebugBox(WorldContextObject->GetWorld(),
                                                       Center, FVector(5.7f, 5.7f, 5.7f),
                                                       FColor::Red, FRotator::ZeroRotator, 0.f, 0);
            }
        }
    }
}


I think this line: UWorld* World = (UWorld*)WorldContextObject;
Maybe world is nullptr, cause the problem.

my solution:

GameMode:




UCLASS(minimalapi)
class ABPCPPInteropDemoGameMode : public AGameModeBase
{
 GENERATED_BODY()

public:
 ABPCPPInteropDemoGameMode();

 int32 Num;
};






UCLASS()
class BPCPPINTEROPDEMO_API UBPFuncDemoLib : public UBlueprintFunctionLibrary
{
 GENERATED_BODY()
public:
 UFUNCTION(BlueprintCallable, Category = "UBPFuncDemoLib")
 static void CallableFuncTest();

 UFUNCTION(BlueprintPure, Category = "UBPFuncDemoLib")
 static bool PureFuncTest(UObject* WorldContextObject, int32& Num);
};






bool UBPFuncDemoLib::PureFuncTest(UObject* WorldContextObject, int32& Num)
{
 bool RV;

 if (nullptr == GEngine)
 {
  RV = false;
 }
 else
 {
  GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Green, TEXT("Call PureFuncTest()"));

  UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject);

  if (nullptr == World)
  {
   RV = false;
  }
  else
  {
   ABPCPPInteropDemoGameMode* GameMode = Cast<ABPCPPInteropDemoGameMode>( World->GetAuthGameMode() );

   if (nullptr == GameMode)
   {
    RV = false;
   }
   else
   {
    RV = true;
    Num = GameMode->Num;
   }
  }
 }

 return RV;
}



hope it works.

It was indeed a nullptr :stuck_out_tongue: Actually solved 40 min ago and then completely blanked out and forgot to update the topic x_x
Thanks for helping me unvirtual, hope I can help you back around the forum :slight_smile:

You’re welcome.:slight_smile: