compiler error : type must be a UCLASS, USTRUCT or UENUM

Hi all,

I have created 3 classes :

  • MyNodeClass
  • MySegmentClass
  • InfrastructureGraphManager

There was a circular dependancy between MyNodeClass and MySegmentClass, which i solved by using a forward declaration. But the compiler failed and reported :

“…/InfrastructureGraphManager.h Error: Unrecognized type ‘MyNodeClass’ - type must be a UCLASS, USTRUCT or UENUM”

=>


UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = data)
	TArray< MyNodeClass *> Nodes; 

Here is my code :

**
MyNodeClass.h**


#pragma once

#include "CoreMinimal.h"

UENUM(BlueprintType) 
enum class NodeType : uint8
{
	...
};

UENUM(BlueprintType)
enum class SegmentType : uint8
{
	...
};


class  MySegmentClass; //forward declaration

class CITYBUILDER_API MyNodeClass
{
public:
	MyNodeClass();
	~MyNodeClass();

	FVector Location;
	MySegmentClass *  Segments[10];

};

**MyNodeClass.cpp **


#include "CityBuilder.h"
#include "MyNodeClass.h"

...



MySegmentClass.h


#pragma once

#include "CoreMinimal.h"


class CITYBUILDER_API MySegmentClass
{
public:
	MySegmentClass();
	~MySegmentClass();

	bool TwoWay; //sens unique ou double sens
	SegmentType type;

};


MySegmentClass.cpp


#include "CityBuilder.h"
#include "MyNodeClass.h"
#include "MySegmentClass.h"

...

InfrastructureGraphManager.h



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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "InfrastructureGraphManager.generated.h"

UCLASS()
class CITYBUILDER_API AInfrastructureGraphManager : public AActor
{
	GENERATED_BODY()
	
public:	
	AInfrastructureGraphManager();

protected:
	virtual void BeginPlay() override;

public:	
	virtual void Tick(float DeltaTime) override;

	MyNodeClass * CreateNode(FVector Location);
	void ConnectNodes(MyNodeClass * Nod1, MyNodeClass * Nod2, SegmentType SegType);
	void DeleteNode(MyNodeClass * Nod);
        MySegmentClass * CreateSegment(void);
	void DeleteSegment(MySegmentClass * Segm);

	 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = data)
	TArray<MyNodeClass*> Nodes;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = data)
	TArray<MySegmentClass*>  Segments; 

};

InfrastructureGraphManager.cpp


#include "CityBuilder.h"
#include "MySegmentClass.h"
#include "InfrastructureGraphManager.h"

...



What is causing the issue please ?

What do you think about using UCLASS?

You are missing the UCLASS (and the GENERATED_BODY) Macros.

Hi,

I already tried this and i get this error message when compiling :


.../MyNodeClass.h(1) : Error: No #include found for the .generated.h file - the .generated.h file should always be the last #include in a header
.../MySegmentClass.h(1) : Error: No #include found for the .generated.h file - the .generated.h file should always be the last #include in a header

Ok the compiler wants me to write classes that look like classes inherited from Actor or Uobject. But why not generic classes ? Since MyNodeClass and MySegmentClass are supposed to only store data ? Why can’t i solve my circular dependency with generic classes ?

Unreal doesn’t use “normal” C++ but a kind of custom version of C++. UObject is supposed to be the base class of every class you make.

You can use standard C++, but it is not recommended, because you would have to implement a custom memory management.
When deriving from UObject, Unreal does the Memory Management (i.e Garbage Collection) for you.

Thanks you very much. Ok from now i’ll create an Actor child class whenever i just have to store data

You may use UObject instead of AActor.

I got it working but I did replace the getGameMode in my test. It had problems compiling with the static gamemode variable

Instead of setting and getting I just call get

.h

UFUNCTION()
static AAPj_013_VerticalCppGameModeBase* GetGameMode(UWorld* world);

.cpp

AAPj_013_VerticalCppGameModeBase* UBlueprintFunctionLibraryTArray::GetGameMode(UWorld* world)
{
    AAPj_013_VerticalCppGameModeBase* GMode = Cast< AAPj_013_VerticalCppGameModeBase>(UGameplayStatics::GetGameMode(world));
    return GMode;
}

I just pass in GetWorld() to the static function and I get valid results on all of the actors in the level of type AProgressEvent it prints them out with their x values :slight_smile:

If the static var on your end works then by all means use it. Just wanted you to know, zero crashes and seems to fit what you were looking for

P.S

The beginplay in the progressEvent cpp

void AProgressEvent::BeginPlay()
{
	Super::BeginPlay();

	AAPj_013_VerticalCppGameModeBase* gpb = UBlueprintFunctionLibraryTArray::GetGameMode(GetWorld());
	gpb->AddProgressEvent(this, GetActorLocation().X);
}