В Unreal Engine 4 двумерные массивы (массивы массивов) могут быть реализованы несколькими способами, в зависимости от ваших потребностей и типа данных, которые вы хотите хранить. Вот основные подходы:
1. Массив массивов TArray (наиболее распространенный):
Описание: Это наиболее гибкий и часто используемый способ создания двумерного массива в Unreal Engine 4. Он представляет собой массив, каждый элемент которого является другим массивом. Пример (Blueprint): Создайте переменную типа “Array”. Измените тип переменной на “Array”. Нажмите на иконку лупы справа от типа “Array” и выберите тип данных для внутреннего массива (например, Integer, Float, String, Vector). В результате тип переменной будет “Array of Array of [Тип данных]”. Пример (C++):
· // В заголовочном файле (.h)
· #include "CoreMinimal. h"
· #include "UObject/NoExportTypes. h"
· #include "MyActor. generated. h"
·
· UCLASS()
· class MYPROJECT_API AMyActor : public AActor
· {
· GENERATED_BODY()
·
· public:
· AMyActor();
·
· // Двумерный массив целых чисел
· UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "MyCategory")
· TArray > My2DArray;
·
· protected:
· virtual void BeginPlay() override;
·
· public:
· UFUNCTION(BlueprintCallable, Category = "MyCategory")
· void InitializeArray(int32 Rows, int32 Columns);
·
· UFUNCTION(BlueprintCallable, Category = "MyCategory")
· int32 GetValue(int32 Row, int32 Column);
·
· UFUNCTION(BlueprintCallable, Category = "MyCategory")
· void SetValue(int32 Row, int32 Column, int32 Value);
· };
·
· // В файле реализации (.cpp)
· #include "MyActor. h"
·
· AMyActor::AMyActor()
· {
· PrimaryActorTick. bCanEverTick = false;
· }
·
· void AMyActor::BeginPlay()
· {
· Super::BeginPlay();
· }
·
· void AMyActor::InitializeArray(int32 Rows, int32 Columns)
· {
· My2DArray. SetNum(Rows);
· for (int32 i = 0; i < Rows; ++i)
· {
· My2DArray[i].SetNum(Columns);
· }
· }
·
· int32 AMyActor::GetValue(int32 Row, int32 Column)
· {
· if (My2DArray. IsValidIndex(Row) && My2DArray[Row].IsValidIndex(Column))
· {
· return My2DArray[Row][Column];
· }
·
· // Обработка ошибок: Вернуть значение по умолчанию или вывести сообщение об ошибке.
· UE_LOG(LogTemp, Warning, TEXT("Invalid array index!"));
· return -1;
· }
·
· void AMyActor::SetValue(int32 Row, int32 Column, int32 Value)
· {
· if (My2DArray. IsValidIndex(Row) && My2DArray[Row].IsValidIndex(Column))
· {
· My2DArray[Row][Column] = Value;
· }
· else
· {
· UE_LOG(LogTemp, Warning, TEXT("Invalid array index!"));
· }
· }
Преимущества:
Гибкость: Можно изменять размер внутренних массивов динамически. Простота использования: Легко создавать, изменять и получать доступ к элементам.
Недостатки:
Может быть менее эффективным по памяти, чем статические массивы, особенно для больших массивов с фиксированным размером.
2. Одномерный массив с ручной индексацией:
Описание: Вместо создания массива массивов, вы создаете один большой массив и вычисляете индекс для доступа к элементам. Пример (Blueprint): Вам нужно будет вручную реализовать логику для вычисления индекса. Пример (C++):
· // В заголовочном файле (.h)
· UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "MyCategory")
· TArray My1DArray;
·
· UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "MyCategory")
· int32 NumRows;
·
· UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "MyCategory")
· int32 NumColumns;
·
· // В файле реализации (.cpp)
·
· void AMyActor::InitializeArray(int32 Rows, int32 Columns)
· {
· NumRows = Rows;
· NumColumns = Columns;
· My1DArray. SetNum(Rows * Columns);
· }
·
· int32 AMyActor::GetValue(int32 Row, int32 Column)
· {
· if (Row >= 0 && Row < NumRows && Column >= 0 && Column < NumColumns)
· {
· int32 Index = Row * NumColumns + Column;
· return My1DArray[Index];
· }
· UE_LOG(LogTemp, Warning, TEXT("Invalid array index!"));
· return -1;
· }
·
· void AMyActor::SetValue(int32 Row, int32 Column, int32 Value)
· {
· if (Row >= 0 && Row < NumRows && Column >= 0 && Column < NumColumns)
· {
· int32 Index = Row * NumColumns + Column;
· My1DArray[Index] = Value;
· }
· else
· {
· UE_LOG(LogTemp, Warning, TEXT("Invalid array index!"));
· }
· }
Преимущества:
Может быть более эффективным по памяти, чем массив массивов, если размер массива известен заранее.
Недостатки:
Более сложная индексация: Требуется вручную вычислять индекс. Менее гибкий: Размер массива должен быть известен заранее.
3. TStaticArray (C++ only):
Описание: TStaticArray — это статический массив фиксированного размера, определенного во время компиляции. Он может быть полезен для двумерных массивов, размер которых известен заранее. Пример (C++):
· #include "Containers/StaticArray. h"
·
· TStaticArray , 10> MyStatic2DArray; / / Массив 10×5
Преимущества:
Наиболее эффективен по памяти и производительности, поскольку размер известен во время компиляции.
Недостатки:
Размер массива должен быть известен во время компиляции. Нельзя изменять размер массива во время выполнения. Только для C++.
4. Использование структуры (struct) для представления строк:
Описание: Если у вас есть определенная структура данных, которую вы хотите представить в виде двумерного массива, вы можете создать структуру и использовать массив структур. Пример (Blueprint): Создайте структуру, содержащую данные для каждой строки массива. Затем создайте массив этой структуры. Пример (C++):
· USTRUCT(BlueprintType)
· struct FMyData
· {
· GENERATED_BODY()
·
· UPROPERTY(EditAnywhere, BlueprintReadWrite)
· int32 Value1;
·
· UPROPERTY(EditAnywhere, BlueprintReadWrite)
· FString Value2;
· };
·
· UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "MyCategory")
· TArray MyArrayOfStructs;
Как выбрать правильный подход:
Размер массива известен заранее и не меняется? Рассмотрите возможность использования TStaticArray (C++ only) или одномерного массива с ручной индексацией. Нужна гибкость и динамическое изменение размера? Используйте TArray >. Хотите представить сложные данные в виде двумерного массива? Используйте структуру и массив структур. Работаете только в Blueprint? TArray > — ваш единственный вариант.
Рекомендации:
Безопасность доступа: Всегда проверяйте границы массива перед доступом к элементам, чтобы избежать ошибок. Используйте IsValidIndex() для TArray. Производительность: Для больших массивов рассмотрите возможность использования пулов объектов для уменьшения нагрузки на сборщик мусора. Простота использования: Если вам не нужна максимальная производительность, используйте TArray >, так как он проще в использовании и более гибкий.
Независимо от выбранного вами способа, убедитесь, что вы понимаете его преимущества и недостатки, и выбирайте тот, который лучше всего подходит для ваших конкретных потребностей.