Global Data Access, Data Storage Class Accessible From Any CPP or BP Class During Runtime!

Overview Author: Rama (talk) Dear Community, Here is a way that Epic recommend to store data you need in a globally accessible way! Let's say you have an array of classes, item classes, tree classe...

Updated over 4 years ago Edit Page Revisions

Overview

Author: Rama (talk)

Dear Community,

Here is a way that Epic recommend to store data you need in a globally accessible way!

Let's say you have an array of classes, item classes, tree classes, whatever, and you need to access this array or add to it from many different CPP or BP classes!

With the help of the Epic-supplied Engine singleton class you can add to a globally accessible data storage during runtime, as well as set default properties to access during runtime.

Important Design Consideration

I caution you not to use this class for doing calculations of any kind!

Remember any class could be accessing this data at any time and overwriting the contents!

Use this class simply to store data like lists of common textures, common materials, common projectile blueprints, creature BP classes you want to access anytime so you can spawn them, etc.

This is globally accessible data so its contents cannot be relied on for precise or time-sensitive calculations :)

This global storage is ideal however for storing lists/arrays of classes or data that do not change during runtime.

Easy to Set Defaults in Editor

Additinally, via the setup I am showing you below, you can easily edit this global default data inside the editor!

This makes creating a set of references to various project assets very easy to do!

The CPP Base Class

SolusDataSingleton.h

/*

   By Rama

*/
#pragma once

#include "SolusDataSingleton.generated.h"

UCLASS(Blueprintable, BlueprintType)
class USolusDataSingleton : public UObject
{
    GENERATED_BODY()
public:
        USolusDataSingleton(const FObjectInitializer& ObjectInitializer);

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Solus Data Singleton")
    TArray<UClass*> SolusTreeBlueprints;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Solus Data Singleton")
    UTexture2D* SolusT2D;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Solus Data Singleton")
    FVector SolusEssentialVector;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Solus Data Singleton")
    FString SolusCoreFilePath;
};

SolusDataSingleton.cpp

/*

   By Rama

*/
#include "Solus.h"
#include "SolusDataSingleton.h"
USolusDataSingleton::USolusDataSingleton(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer)
{ 
    SolusCoreFilePath = "E:/Solus";
    
    SolusEssentialVector = FVector(9000,0,0);
}

The BP of the CPP Class

[[File:../d26ilriwvtzlb.cloudfront.net/1/18/NewBPDataSingleton.jpg]]

Easily Set Default Values Any Time!

[[File:../d3ar1piqh1oeli.cloudfront.net/8/8b/DataSingleton_setdefaultseasily.jpg/900px-DataSingleton_setdefaultseasily.jpg]]

Project Settings->Engine->General

Make sure to use your BP of the CPP base class!

Then you change the values / add to dynamic arrays, any time in your defaults, and the changes will be up to date when you use the instance during game time!

(4.9 update: This is hidden, use the eye icon -> show advanced settings to see it!) [[File:../d26ilriwvtzlb.cloudfront.net/3/3a/DataSingleton_projectsettings.jpg]]

Function Library To Access Anywhere in BP

SolusDataSingletonLibrary.h

/*
   Solus Data Singleton Library
   
   by Rama

*/

#pragma once

//Data Singleton Class
#include "SolusDataSingleton.h"

#include "SolusDataSingletonLibrary.generated.h"

//note about UBlueprintFunctionLibrary
// This class is a base class for any function libraries exposed to blueprints.
// Methods in subclasses are expected to be static, and no methods should be added to the base class.

UCLASS()
class SOLUS_API USolusDataSingletonLibrary : public UBlueprintFunctionLibrary
{
    GENERATED_BODY()
public:
    USolusDataSingletonLibrary(const FObjectInitializer& ObjectInitializer);

    UFUNCTION(BlueprintPure,   Category="Solus Data Singleton")
    static USolusDataSingleton* GetSolusData(bool& IsValid);
    
};

SolusDataSingletonLibrary.cpp

/*
   Solus Data Singleton Library
   
   by Rama

*/
#include "Solus.h"
#include "SolusDataSingletonLibrary.h"
//////////////////////////////////////////////////////////////////////////
// USolusDataSingletonLibrary

USolusDataSingletonLibrary::USolusDataSingletonLibrary(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer)
{ 
    
}

USolusDataSingleton* USolusDataSingletonLibrary::GetSolusData(bool& IsValid)
{
    IsValid = false;
    USolusDataSingleton* DataInstance = Cast<USolusDataSingleton>(GEngine->GameSingleton);
    
    if(!DataInstance) return NULL;
    if(!DataInstance->IsValidLowLevel()) return NULL;
    
    IsValid = true;
    return DataInstance;
}

Help My Project Wont Load Any More, Editor Just Crashes

If your Data Singleton class gets deleted misplaced or renamed in some unusual fashion, you can end up in situation where your project simply will not load!

There's an easy fix!

Just navigate to your Config/DefaultEngine.ini and remove the line related to your singleton class which is now missing

 [/Script/Engine.Engine]
 GameViewportClientClassName=/Script/Engine.GameViewportClient
 GameViewportClientClassName=/Script/Solus.SolusViewportClient
 LevelScriptActorClassName=/Script/Engine.LevelScriptActor
 LevelScriptActorClassName=/Script/Solus.SolusLevelScriptActor
 GameSingletonClassName=/Game/Rama/SolusDataSingletonBP.SolusDataSingletonBP_C  ;<-----

Accessing the Global Data Storage in Blueprints!

[[File:../d26ilriwvtzlb.cloudfront.net/2/2a/DataSingleTon_accessingviaBPlibrary.jpg]]

Conclusion

Now you know a place you can store data that can then be accessed from any BP or CPP class during game time!

Again I recommend you use it primarily for data that doesn't change during runtime, because any class could be editing the global data at any time during gametime :)

Enjoy!

Rama (talk)