Another way to do it is to just use a plain array and then create get set methods. I feel that it is simpler, and you also get rid of the object overhead that c++ classes and structs generate, especially in UE4 since they have custom adorn data as well. This helps with stuff like cache performance and might make a difference if it represents some data that you access very often. The biggest advantage I feel is of course that it is more straight forward. The downside is that you need to add in some more effort if you want to be able to use the index operator, but if you just encapsulate it nicely in a class that is pretty easy to achieve anyways
You basically just create one array like so:
//The matrix is laid out sequentially in memory,
UPROPERTY() //Don't forget to make the array a UPROPERTY if you are storing stuff that could get GCd!
FORCEINLINE void SetUObjectToMatrix(UObject* NewObject, FIntVector Location)
//Location.Z * UObjectMatrixDimensions.X * UObjectMatrixDimensions.Y walks us one XY block at a time
//Location.Y * UObjectMatrixDimensions.X Then walks us to the correct line in the XY block we want
//And then we just walk Location.X forward to the element we want.
UObjectsMatrix[Location.Z * UObjectMatrixDimensions.X * UObjectMatrixDimensions.Y + Location.Y * UObjectMatrixDimensions.X + Location.X] = NewObject;
FORCEINLINE UObject* GetUObjectFromMatrix(FIntVector Location)
return UObjectsMatrix[Location.Z * UObjectMatrixDimensions.X * UObjectMatrixDimensions.Y + Location.Y * UObjectMatrixDimensions.X + Location.X];
And for the ctor in your cpp you can do something like:
AMyActor::AMyActor(const FObjectInitializer& ObjectInitializer)
UObjectMatrixDimensions = FIntVector(10, 10, 10);
UObjectsMatrix.SetNumZeroed(UObjectMatrixDimensions.X * UObjectMatrixDimensions.Y * UObjectMatrixDimensions.Z);
SetUObjectToMatrix(NULL, FIntVector(0, 4, 9));
I didn’t add any bound checking to the inlined functions right now since that might be controlled by your invariants anyways. And if they aren’t, it’s easy enough to add yourself
Like I mentioned above, it might of course also be a good idea to make this into its own (template) class if you decide to use it.