Using UGameInstance for ID storage

What is wrong

I am trying to use a UGameInstance to store ID’s of items. These ID’s are stored in a helper class that is a child of UObject. However, when I try to use the UGameInstance class, I get a duplicate symbols error.

What I am doing

I used Rama’s tutorial, “Game Instance, Custom Game Instance For Inter-Level Persistent Data Storage”, which is very informative on setting up the UGameInstance class, but less so on using it.

My Relevant classes consist of:

UOncomingGameInstance.h

#pragma once

#include "Engine/GameInstance.h"
#include "ItemRegistry.h"
#include "OncomingGameInstance.generated.h"

/**
 * 
 */
UCLASS()
class ONCOMINGPREALPHA_API UOncomingGameInstance : public UGameInstance
{
	GENERATED_UCLASS_BODY()
	
public:
    UOncomingGameInstance();
    
    UItemRegistry* ItemRegistry;
	
};

UOncomingGameInstance.cpp

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

#include "OncomingPreAlpha.h"
#include "Item/NULLItem.h"
#include "OncomingGameInstance.h"

UItemRegistry* ItemRegistry = NewObject<UItemRegistry>();

UOncomingGameInstance::UOncomingGameInstance(const FObjectInitializer& ObjInit) : Super(ObjInit) {
    UWorld* world = GetWorld();
    if (world) {
        AItem* Item = Cast<AItem>(world->SpawnActor(ANULLItem::StaticClass()));
        
        ItemRegistry->AddToRegistry(Item, "NULL");
    }
}

ItemRegistry.h

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

#pragma once

#include "Object.h"
#include "ItemRegistry.generated.h"

/**
 * 
 */
UCLASS()
class ONCOMINGPREALPHA_API UItemRegistry : public UObject
{
	GENERATED_BODY()
	
public:
    
    bool AddToRegistry(class AItem* Item, FString ID);
    AItem* GetID(FString ID);
    
    TMap<FString, class AItem*> Registry;
	
	
};

ItemRegistry.cpp

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

#include "OncomingPreAlpha.h"
#include "ItemRegistry.h"


bool UItemRegistry::AddToRegistry(class AItem* Item, FString ID) {
    if(Registry.Contains(ID)) {
        return false;
    }
    
    Registry.Add(ID, Item);
    
    return true;
}

AItem* UItemRegistry::GetID(FString ID) {
    if (Registry.Contains(ID)) return Registry[ID];
    else return Registry["NULL"];
}

What I have tried

Firstly, I looked into using singletons, eventually coming to the conclusion that they weren’t the best choice. I searched around for a while and found the UGameInstance class. I decided that it would be the best thing to use, I tried researching how to use it. Rama’s tutorial was the best (And only I could find).

After no success trying to get it working, I have come to post a question. I am probably trying to implement this in a stupid way, so I am open to suggestions on a different method.

I get the Duplicate Symbols error when I write the following:

#include UOncomingGameInstance.h

...

void AActorChild::BeginPlay() {
    Super::BeginPlay();
    
    UOncomingGameInstance* inst = Cast<UOncomingGameInstance>(GetGameInstance());
    if(inst) {
        GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Blue, inst->ItemRegistry->GetID("NULL")->GetName());
    
    }
}

Thanks for taking the time to read and reply. Sorry for the code dump.

Bump. I’m desperate for an answer.

Not sure whether this will help with what you want to do, but here is the way I use GameInstance to store stuff…

MyGameInstance.h:

UCLASS()
class MyGame_API UMyGameInstance : public UGameInstance
{
	GENERATED_BODY()
	UMyGameInstance(const class FObjectInitializer& PCIP);

public:
	static uint8 AReallyImportantInteger;
};

My GameInstance.cpp:

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

#include "MyGame.h"
#include "MyGameInstance.h"

uint8 MyGameInstance::AReallyImportantInteger = 255;

Then to access from whatever .cpp file needs to:

UMyGameInstance* VGI = Cast<UMyGameInstance>(GetGameInstance());
if (!VGI) {
//freak out here
   return;
}
VGI->AReallyImportantInteger = 0;

Hope that is of help.

Paste the logs here, maybe I can help…

answer has fixed my problem. Thanks for taking the time to read my question.

Thanks for the answer! Turns out I was forgetting to declare my initialiser in the header correctly.