What is the best way to deal with alot of References.

Hi, iam converting a project from bp to c++, now iam wondering what the best way is to deal with like StaticMesh references. I dont like the idea of hardcoding them into the source files. Can someone help me creating something like a collection where i for example can use an ID to get my reference (StaticMesh’/bla/bla’)

like a stringtable :slight_smile:

thanks in advance.

UDataAsset is what you’re looking for. It’s a simple asset with the only goal to be easily created and store data references. Here’s a basic example:

struct FMeshData

	UPROPERTY( Category=MeshData, EditDefaultsOnly )
	FName MeshKey;

	UPROPERTY( Category=MeshData, EditDefaultsOnly )
	UStaticMesh* Mesh;

class UMyGameMeshData : public UDataAsset

	UPROPERTY( Category=MeshData, EditDefaultsOnly )
	TArray<FMeshData>		Meshes;

	UFUNCTION( Category=MeshData, BlueprintCallable )
	UStaticMesh* GetMesh( const FName& MeshKey )
		for( const MeshData& : Meshes )
			if( MeshData.MeshKey == MeshKey )
				return MeshData.Mesh;

		return nullptr;

This will give you an expandable array which you can edit as an asset, then store that asset where you need to access these meshes. To create a data asset type, go in the Miscellaneous section, pick Data Asset, and you’ll get to choose from all the data asset types in a list.


Hey just a tip it may be a good idea to make sure the data only is created once for etch game session.
If you have a lot of data stored this helps with memory consumtion.

I did this my self last week, after reading the tutorial by Rama.
Idea is that you have the data in the singelton class and a Globaly accessible methods to get the data.
Here is the link.

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

I’d advise against that unless it actually is global data. Loading a bunch of static meshes (and their dependencies) for no other reason than to “only create them once” is wasteful on memory, and that’s the sort of thing you’re better off trying to keep under control from the start. In fact, I’d have written my sample using TAssetPtrs instead of direct pointers, but dynamically loading TAssetPtrs is a tough pill to swallow when you’re just getting started.

Am not sure am following ?
Just to explain what i did was to create some data tabels e.g: for in game items.
And the tabels include A StringRefrence to a blueprint or a Asset Pointer to anything from Icon/ Texture to sound.
In my Item base class the correct values are set dependent on Item ID set in the derived BP.

Now this is data that needs to be available for the entier game session, and will not change.
Are you saying is better to have the data several places instead of making sure its only created once and is available anywhere?

Both my example and Rama’s that you linked earlier use hard UAsset pointers. This means for instance that loading a UDataAsset with an array of UTexture2D* will in turn load all these textures, unnecessarily keeping things in memory that might not be needed. Your wording (“only is created once”) strongly hints that this “load everything” behaviour is what you intended.

FStringAssetReference and TAssetPtr, on the other hand, do not automatically load the associated asset. The asset reference will “be available for the entire game session”, yes, but the asset itself will not be loaded automatically, avoiding potentially unneeded memory usage. So keeping a data asset containing only these is fine as it won’t waste memory. But loading these assets on demand, as I mentioned in my previous post, is more complicated so I didn’t want to introduce that in my example.

Basically just trying to limit myself to the scope of OP’s question (managing references, not loading them). :slight_smile:

Basically i want 1 spot in my code where i can go and change the model texture sound and whatsoever references so that i can access them in my code as keywords. Thought about 1 big header with alot of const’s

You could also use #define/macros.
Allthough Camilles proposal (TAssetPtrs) is better, imo.