Dear Friends at Epic,
I am trying to make a UPROPERTY 2D array in a USTRUCT
It did not seem to want to compile, below I have my current code as well as my ideal code
the overal data structure is a relationship of distances between all types of creatures
so each creature needs to know its relation to all other creatures
thus I’d like to use a 2D array
//~~~~~~~~~~~~~~~~~~~~~~
// AI Measurements
//updated via client function, not repped
USTRUCT()
struct FAIMeasurements
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
float SkeletonBaseZDiff[CREATURE_MAX];
UPROPERTY()
float WarriorBaseZDiff[CREATURE_MAX];
UPROPERTY()
float PotentialBaseZDiff[CREATURE_MAX];
FAIMeasurements()
{
for (int32 v = 0; v < CREATURE_MAX; v++ )
{
SkeletonBaseZDiff[v] = 0;
WarriorBaseZDiff[v] = 0;
PotentialBaseZDiff[v] = 0;
}
}
};
#could be this
//~~~~~~~~~~~~~~~~~~~~~~
// AI Measurements
//updated via client function, not repped
USTRUCT()
struct FAIMeasurements
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
float AllMeasurements[CREATURE_MAX][CREATURE_MAX];
FAIMeasurements()
{
for (int32 v = 0; v < CREATURE_MAX; v++ )
for (int32 b = 0; b < CREATURE_MAX; b++ )
{
AllMeasurements[v][b] = 0;
}
}
};
Thanks!
My work around to this within blueprint (which is still valid here) is to use a singular array but do the math yourself for each row/column. Lets for arguments sake say the array is [5][5] in size which makes 25 individual entires so you make a single array of that total length and every 5 entries you flip a row/column counter.
Thats a great idea Daniel!
Thanks for sharing 
I would still like to know from Epic why 2 D arrays are not implemented if that is actually so,
but I will definitely be using your work around Daniel if they are not implementable 
Thanks!
Rama
I dont see why they shouldnt be since its a feature of c++, its probably more to do with the UProperty side of things in that theres no way to edit a multidimensional array from within the editor. There is a type called a blackboard so Im not certain if thats meant to be what we use for complex table arrays.
You can use a two dimensional array that is not a UProperty with no ill effects - but yeah, it’s the nature of UProperties that prevents you from using a two dimensional array, much like it was a problem in UnrealScript too. It’s probably something to do with how reflection / garbage collection is handled and that not supporting nested pointers.
Thanks for the info Luke!
I will leave this open as a request to Epic to consider 2 D arrays, not sure what the complexity of this request is but it’s worth trying 
Rama
Supporting 2D arrays in UPROPERTYs would be a considerable amount of work, and I’m not sure there are enough benefits to justify the work required, since you can get the functionality of Arrays of Arrays in other ways.
You could “linearize” the array like Daniel mentioned and do the math yourself for each row/column, and even write some helper functions for that.
You can also have arrays of USTRUCTs which themselves contain arrays. I did this myself for TranslationDataObject:
USTRUCT()
struct FTranslationChange
{
GENERATED_USTRUCT_BODY()
public:
/** The changelist of this change */
UPROPERTY(Category=Translation, VisibleAnywhere)
FString Version;
/** Date of this change */
UPROPERTY(Category=Translation, VisibleAnywhere)//, meta=(DisplayName = "Date & Time"))
FDateTime DateAndTime;
/** Source at time of this change */
UPROPERTY(Category=Translation, VisibleAnywhere)
FString Source;
/** Translation at time of this change */
UPROPERTY(Category=Translation, VisibleAnywhere)
FString Translation;
};
USTRUCT()
struct FTranslationContextInfo
{
GENERATED_USTRUCT_BODY()
public:
/** The key specified in LOCTEXT */
UPROPERTY(Category=Translation, VisibleAnywhere)
FString Key;
/** What file and line this translation is from */
UPROPERTY(Category=Translation, VisibleAnywhere)
FString Context;
/** List of previous versions of the source text for this context */
UPROPERTY(Category=Translation, VisibleAnywhere)
TArray Changes;
};
USTRUCT()
struct FTranslationUnit
{
GENERATED_USTRUCT_BODY()
public:
/** The localization namespace for this translation */
UPROPERTY(Category=Translation, VisibleAnywhere)
FString Namespace;
/** Original text from the source language */
UPROPERTY(Category=Translation, VisibleAnywhere)
FString Source;
/** Translations */
UPROPERTY(Category=Translation, EditAnywhere)
FString Translation;
/** Contexts the source was found in */
UPROPERTY(Category=Translation, VisibleAnywhere)
TArray Contexts;
/** Whether the changes have been reviewed */
UPROPERTY(Category=Translation, EditAnywhere)
bool HasBeenReviewed;
};
/**
* Just a wrapper for the struct with real data in it.
*/
UCLASS(hidecategories=Object, MinimalAPI)
class UTranslationDataObject : public UObject
{
GENERATED_UCLASS_BODY()
public:
/** List of items that need translations */
UPROPERTY(Category=Translation, EditAnywhere)
TArray Untranslated;
/** List of items that need review */
UPROPERTY(Category=Translation, EditAnywhere)
TArray Review;
/** List of items whose translation is complete */
UPROPERTY(Category=Translation, EditAnywhere)
TArray Complete;
};
Thank you for the info and the code sample Joe!


Rama
#Thank You Joe
Joe’s Idea turned out to be perfect for my algorithms 
//2D Array Workaround
USTRUCT()
struct FAIMeasurementData
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
float Data[CREATURE_MAX];
FAIMeasurementData(){}
};
USTRUCT()
struct FAIMeasurements
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
FAIMeasurementData BaseZDiff[CREATURE_MAX];
FAIMeasurements(){}
};
Yup this is the same method I used to use to get multidimensional arrays in UScript
I guess now though with c++ it can be made alittle cleaner using the constructors to make accessor wrappers. Eg.
MyArray.subAr_A
MyArray.subAr_A.subAr_B
can be made into
MyArray.subAr.A
MyArray.subAr.B
Which does make it easier later on, especially if they are dynamic lengths and youre using the lengths. for Eg.
MyArray.subAr_A.length
MyArray.subAr_A.subAr_B.length
Is alittle bit obscure its one of the things I always had trouble with in UScript from a code neatness and easier readability perspective.
Yea the C++ is soooooo nice 

Rama