Problem Importing a Struct

Hi there. I have 2 UStructs in question here. First, I have a struct named FCombatant. This struct doesn’t currently have any errors in it and is used multiple times across multiple files just fine. However, when I try importing it to another struct FTurnInfo, when compiling, the debugger throws the error: “Unrecognized type ‘FCombatant’ - type must be a UCLASS, USTRUCT, or UENUM.” The strange thing is that I’m using my FCombatant in multiple places, of which, none are throwing this error and furthermore, my import for FCombatant in FTurnInfo isn’t underlined as if there’s an error. Any guidance would be greatly appreciated!

USTRUCT(BlueprintType)
struct ARCANUMGENESIS_API FCombatant
{
	GENERATED_BODY()

	FCombatant()
	{
	}

	FCombatant(AUnitBase* A, float Initiative)
	{
		Unit = A;
		InitiativeAttribute = Initiative;
	}

	UPROPERTY(BlueprintReadWrite)
	AUnitBase* Unit;

	UPROPERTY(BlueprintReadWrite)
	float InitiativeAttribute;
	
	void UpdateInitiative()
	{
		InitiativeAttribute = Unit->GetAttributes()->GetInitiative();
	}
};
USTRUCT(BlueprintType)
struct ARCANUMGENESIS_API FTurnInfo
{
	GENERATED_BODY()

	UPROPERTY(BlueprintReadOnly)
	bool bIsTurn;

	UPROPERTY(BlueprintReadOnly)
	TEnumAsByte<ETurnType> Type;

	/** This will be nullptr if this is a non-combat turn. */
	UPROPERTY(BlueprintReadOnly)
	TArray<FCombatant> TurnSequence;

	FTurnInfo(){}

	FTurnInfo(bool IsTurn, ETurnType TType, TArray<FCombatant>& Sequence)
	{
		bIsTurn = IsTurn;
		Type = TEnumAsByte<ETurnType>(TType);
		TurnSequence = Sequence;
	}
	
};

Possibly a dumb question. I don’t know how you plan to use it.
Should that be FCombatant*

Using a pointer may just get you past the compiler error. Any use of a class/struct needs to be understood by the compiler.

So I’m using FCombatant as a representation of / container for a unit that is in battle. I’m making a turn-based game, and so this struct provides the necessary info I’d need for that battling unit easily and readily.

Honestly, I didn’t think of trying a pointer because I think I always got an error when making any struct a pointer. All my other uses of FCombatant, where this error isn’t present, never uses a pointer. However, if I can actually use pointers with structs and that’s best practice, that makes a lot more sense to me.

I do have similar code:

UCLASS()
class UPlayerData : public UObject
{
    GENERATED_BODY()

private:

    UPROPERTY()
    UPlayerProfile* PlayerProfile;

    UPROPERTY()
    UGameData* GameData;

    UPROPERTY()
    bool IsDirty;

    UPROPERTY()
    TArray<FAchievement> Achievements;

    UPROPERTY()
    TArray<FInventoryItem> Inventory;
    :
}

I am looking to see how FAchievement and FInventoryItem are included. I suspect it may be through my inclusion of GameData.h or other file.

It turns out that both are defined in a single file:

USTRUCT()
struct FAchievement
{
    GENERATED_BODY()

public:

    UPROPERTY()
    EAchievement Achievement;

    UPROPERTY()
    uint32 Count;

    FAchievement() : Achievement(EAchievement::QuickShot), Count(0) {}
    FAchievement(EAchievement achievement, uint32 count) : Achievement(achievement), Count(count) {}
};

USTRUCT()
struct FInventoryItem
{
    GENERATED_BODY()

public:

    UPROPERTY()
    EInventoryItem Item;

    UPROPERTY()
    uint32 Count;

    FInventoryItem() : Item(EInventoryItem::QuickTrigger), Count(0) {}
    FInventoryItem(EInventoryItem item, uint32 count) : Item(item), Count(count) {}
};

For completeness sake. I have PlayerData.h

#pragma once
#include "../Common/Common.h"
#include "PlayerProfile.h"
#include "GameData.h"
#include "UObject/Object.h"
:
:

GameData.h includes another file:

#pragma once

#include "LevelScore.h"
#include "UObject/Object.h"
#include "GameData.generated.h"
:
:

And LevelScore includes WaveScore which is where the two USTRUCT’s are defined:

#pragma once
#include "WaveScore.h"
:

WaveScore.h has:

#pragma once
#include "UObject/Object.h"
#include "WaveScore.generated.h"

USTRUCT()
struct FAchievement
{
:
}

USTRUCT()
struct FInventoryItem
{
:
}

I appreciate all the information! I currently have FCombatant defined in its own Combatant.h file. I know that the import for Combatant.h is valid (since it’s used in multiple other places besides this one place that’s throwing the error). So based on what you showed here, it’s all pretty much similar, which makes this error all the more confusing for me.

you can’t have it in another file. UHT needs to see the definition. What you are getting is not a compilation error but an error from the unreal header tool.

So to clarify: FCombatant must be defined above FTurnInfo in the same file.

Combatant.h is included in TurnInfo.h or reached via another include?

From Visual Studio you should be able to right-mouse click on the filename and select “Go to Document ”

I tried adding some functions into a struct just as you have did and it did not like the functions in the struct i had to take them out and put the functions in my cpp file. Not sure if this is effecting yours, but it did in mine.

Hi there. Is this only the case for structs embedded in other structs? Because I do have FCombatant being used in other classes perfectly fine. It’s only a problem when I include it in another struct, such as FTurnInfo.

statement rings a bell. It’s been some time since I’ve messed with this part of my code. I will say my two UStruct’s above do have constructors though.

Also, looking through numerous files there are constructor’s and the archive operator:

friend FArchive& operator<<(FArchive& ar, UGameScore& data) { . . . }

I appreciate all the replies! I think what I’m going to try is moving all gameplay structs into one file, which should resolve the importing issue.

Out of curiosity what versions are you using (UE4, VisualStudio)?

Personally, I would keep things as they are at the moment.
By chance do you have in TurnInfo.h:

#pragma once
#include "Combatant.h"

Save the change to disk.
Give intellisense a few moments to recognize the change and right-mouse on “Combatant.h” and select “Go to Document Combatant.h”

As a matter of policy I make sure Visual Studio can find the include. Sometimes that is a battle itself.
If your includes are in the same directory VS should find it.

Aslo, another change may be needed:

	UPROPERTY(BlueprintReadWrite)
	class AUnitBase* Unit;

	void UpdateInitiative()
	{
		//  optional protection
		if (Unit)
		{
			InitiativeAttribute = Unit->GetAttributes()->GetInitiative();
		}
	}

@
I made a struct for betting odds and added the functions into it, So i just would have to call the struct and what ever function. The compiler told me that was a no no. Said to take the function out of the structure. So i did and it fixed my struct problem i was having. Also noticed, if i try to save off the pri or the controller into a struct as a reference to the player, it does not like that either, had to take that out also. Would be nice to save a players reference to use later from the struct, but i can not seem to get that to work. Either it is the way i am doing it or it just can not be done? I can not get it to work.