I’m trying to set up what I thought would be simple: every time a character from my game spawns in the map, their character data, encapsulated in some struct FCharacterSheet, gets moved from a list of inactive NPCs to active ones, and vice versa. I was under the impression you could store structs in arrays, but I get an error every time I try to run .Add(), .Contains(), or .Remove() with my struct as the argument. Am I doing this wrong, or is it simply not possible to store structs the way I’m proposing?
USTRUCT()
struct FCharacterSheet{
GENERATED_USTRUCT_BODY()
UPROPERTY(BlueprintReadOnly)
FString name;
UPROPERTY(BlueprintReadOnly)
AActor* myActor;
UPROPERTY(BlueprintReadOnly)
float health;
UPROPERTY(BlueprintReadOnly)
float stamina;
};
UPROPERTY(VisibleAnywhere)
TArray<FCharacterSheet> InactivePool; //Characters not currently spawned in the world
UPROPERTY(VisibleAnywhere)
TArray<FCharacterSheet> ActivePool; //Characters not currently spawned in the world
void UPopulationManager::MakeInactive(FCharacterSheet character){
if (!InactivePool.Contains(character)){
InactivePool.Add(character);//Adds character to inactive pool
ActivePool.Remove(character); //Removes character from active pool
}
}
void UPopulationManager::MakeActive(FCharacterSheet character){
if (!ActivePool.Contains(character)){
ActivePool.Add(character);//Adds character to active pool
InactivePool.Remove(character); //Removes character from inactive pool
}
}
I’m using TArrays of structs without any problems. Are you declaring the USTRUCT inside a UCLASS? Perhaps moving the struct definition outside of the class helps.
That’s weird, I’m not… the declaration is in my .h just under the #includes, and before the UCLASS declaration, and the functions I quoted are from the .cpp .
The error is really hard to decipher, this is the entire thing:
Info c:\users\username\documents\unreal projects\projectname\source\ projectname \PopulationManager.h(37) : see reference to class template instantiation ‘TArray<FCharacterSheet,FDefaultAllocator>’ being compiled
Info C:\Program Files (x86)\Epic Games\4.8\Engine\Source\Runtime\Core\Public\Containers\Array.h(1965) : error C2678: binary ‘==’ : no operator found which takes a left-hand operand of type ‘FCharacterSheet’ (or there is no acceptable conversion)
Info C:\Program Files (x86)\Epic Games\4.8\Engine\Source\Runtime\Engine\Classes\Sound/DialogueWave.h(36): could be ‘bool operator ==(const FDialogueContextMapping &,const FDialogueContextMapping &)’
Info C:\Program Files (x86)\Epic Games\4.8\Engine\Source\Runtime\Engine\Classes\Sound/DialogueTypes.h(56): or ‘bool operator ==(const FDialogueContext &,const FDialogueContext &)’
Info C:\Program Files (x86)\Epic Games\4.8\Engine\Source\Runtime\Engine\Classes\Engine/StaticMesh.h(209): or ‘bool operator ==(const FMeshSectionInfo &,const FMeshSectionInfo &)’
Info C:\Program Files (x86)\Epic Games\4.8\Engine\Source\Runtime\Engine\Classes\Engine/SkeletalMesh.h(514): or ‘bool operator ==(const UMaterialInterface &,const FSkeletalMaterial &)’
Info C:\Program Files (x86)\Epic Games\4.8\Engine\Source\Runtime\Engine\Classes\Engine/SkeletalMesh.h(513): or ‘bool operator ==(const FSkeletalMaterial &,const UMaterialInterface &)’
Info C:\Program Files (x86)\Epic Games\4.8\Engine\Source\Runtime\Engine\Classes\Engine/SkeletalMesh.h(512): or ‘bool operator ==(const FSkeletalMaterial &,const FSkeletalMaterial &)’
Info c:\program files (x86)\epic games\4.8\engine\source\runtime\rhi\public\RHIResources.h(179): or ‘bool operator ==(const FRHIUniformBufferLayout &,const FRHIUniformBufferLayout &)’
Info C:\Program Files (x86)\Windows Kits\8.1\include\shared\guiddef.h(192): or ‘bool operator ==(const GUID &,const GUID &)’
Info while trying to match the argument list ‘(FCharacterSheet, const FCharacterSheet)’
Info C:\Program Files (x86)\Epic Games\4.8\Engine\Source\Runtime\Core\Public\Containers\Array.h(1961) : while compiling class template member function ‘int32 TArray<FCharacterSheet,FDefaultAllocator>::Remove(const FCharacterSheet &)’
Info C:\Filepath\Source\ProjectName\PopulationManager.cpp(35) : see reference to function template instantiation ‘int32 TArray<FCharacterSheet,FDefaultAllocator>::Remove(const FCharacterSheet &)’ being compiled
These are the two lines from my project it references:
PopulationManager.h (37):
TArray<FCharacterSheet> InactivePool; //Characters not currently spawned in the world
PopulationManager.cpp(35):
InactivePool.Remove(character); //Removes character from active pool
Huh, I’ve never run into this before… what exactly does the “bool operator ==” section accomplish, does this need to be specific to the data structure of the struct?
Maybe previously you never called TArray.Contains with a custom struct before? The function “bool operator==(const FMyStruct& lhs, const FMyStruct& rhs);” defines when two instances of FMyStruct are equal It needs a function body too. Since TArray.Contains uses == internally, it must exist. Here is how I defined it for my struct FVector2i, which stores 2D integer coordinates:
Oh, that is cool. There is no need to compare every value if you don’t need to, right? So if I have a data-heavy object I could theoretically give each one a unique int32 GUID, and test for equality across the whole struct by comparing that one value in my function?
Does this look right to you? UE is crashing when I try to compile it. These are both from a component UCharacterData, which is where FCharacterSheet is declared and defined:
CharacterData.h:
#pragma once
#include "CharacterData.generated.h"
USTRUCT()
struct FCharacterSheet{
GENERATED_USTRUCT_BODY()
UPROPERTY(BlueprintReadOnly)
FString name;
// int age;
UPROPERTY(BlueprintReadOnly)
AActor* myActor;
UPROPERTY(BlueprintReadOnly)
float health;
UPROPERTY(BlueprintReadOnly)
float stamina;
UPROPERTY(BlueprintReadOnly)
float maxHealth;
UPROPERTY(BlueprintReadOnly)
float maxStamina;
float height;
float weight;
};
bool operator==(const FCharacterSheet& lhs, const FCharacterSheet& rhs);
UCLASS()
class PROJECTNAME_API UCharacterData : public UMorpheme
{
GENERATED_BODY()
public:
UCharacterData();
// a bunch of unrelated decs follow
}
When I compile, it runs for a while, then UE consistently crashes. I pasted the crashlog before, but heck if I can see what the problem is from its contents:
Edit: I think it must’ve been a weird residual error from the original problem: I “fixed” it by commenting everything in the class out, compiling successfully, then uncommenting and recompiling. Nothing changed, but it works now
Unknown exception - code 00000001 (first/second chance not available)
I can’t decipher that either. I see a hot reload in there, does the crash only happen after hot reloading? I just keep in mind that hot reloading isn’t perfect yet and can cause crashes.
I think that must be the root of the problem- maybe for some reason it was trying to hot reload the version without the bool== function (which also crashed)? In any event it works perfectly now, I really appreciate your time- I had no idea that you could customize a struct’s equality check like that.