【UE4】DataTable — Таблица данных

В этой статье используется UE 4.26, движок поставляется с проектом ARPG и записывает DataTable в UE4, то есть использование таблицы данных, как с точки зрения кода, так и с точки зрения редактора.

1. Что такое таблица данных?

  DataTable — это таблица данных (далее — DT), которая представляет собой двумерную матрицу с M строками и N столбцами, как показано на следующем рисунке:

Вставьте сюда описание изображения

  Это таблица данных с 5 строками (Row) и тремя столбцами (Col). Программа может найти соответствующую взаимосвязь и реализовать соответствующую логику с помощью таблицы данных конфигурации планирования, что очень удобно для планирования.

2. Использование в редакторе

2.1 Создайте таблицу данных

  В редакторе щелкните правой кнопкой мыши Miscellaneous -> DataTable, чтобы создать ОУ:

Вставьте сюда описание изображения

  Вам необходимо выбрать структуру данных строки (т. е. столбца). Например, если вы выберете GameplayTagTableRow, ОУ будет создано, как показано ниже: Вновь
Вставьте сюда описание изображения
Вставьте сюда описание изображения
  созданное ОУ по умолчанию пусто. Нажмите кнопку «Добавить», чтобы создать строку по умолчанию. Если структура столбца ОУ — В коде, значение по умолчанию задается в коде; если структура столбца ОУ является ресурсом, она задается в ресурсе. В этом примере GameplayTagTableRow записан в коде, поэтому значение по умолчанию установлено в коде (значение по умолчанию не установлено, поэтому по умолчанию для тега установлено значение None, а для DevComment по умолчанию — пустое значение):

/** Simple struct for a table row in the gameplay tag table and element in the ini list */
USTRUCT()
struct FGameplayTagTableRow : public FTableRowBase
{
    
    
	GENERATED_USTRUCT_BODY()

	/** Tag specified in the table */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=GameplayTag)
	FName Tag;

	/** Developer comment clarifying the usage of a particular tag, not user facing */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=GameplayTag)
	FString DevComment;

	/** Constructors */
	FGameplayTagTableRow() {
    
    }
	FGameplayTagTableRow(FName InTag, const FString& InDevComment = TEXT("")) : Tag(InTag), DevComment(InDevComment) {
    
    }
	GAMEPLAYTAGS_API FGameplayTagTableRow(FGameplayTagTableRow const& Other);

	/** Assignment/Equality operators */
	GAMEPLAYTAGS_API FGameplayTagTableRow& operator=(FGameplayTagTableRow const& Other);
	GAMEPLAYTAGS_API bool operator==(FGameplayTagTableRow const& Other) const;
	GAMEPLAYTAGS_API bool operator!=(FGameplayTagTableRow const& Other) const;
	GAMEPLAYTAGS_API bool operator<(FGameplayTagTableRow const& Other) const;
};

  Нажмите на строку в DT, строка будет выделена, и значение этой строки можно будет изменить в редакторе строк (Уведомление: первый столбец представляет количество строк, имя столбца нельзя изменить)
Вставьте сюда описание изображения

2.2 Настройте столбцы таблицы данных

  Столбцы DT фиксируются после их создания. Вы не можете случайно добавить или удалить столбец. Если вам нужно настроить таблицу данных столбца, вы можете щелкнуть правой кнопкой мыши в Содержимом и создать «Структуру»:
Вставьте сюда описание изображения

  В Структуре вы можете добавлять переменные, регулировать положение переменных (чем выше, тем левее в DT) и Default Valuesустанавливать значение по умолчанию для каждого столбца (Уведомление: Переменные и строковые значения, оба могут быть китайскими):

Вставьте сюда описание изображения

  Затем щелкните правой кнопкой мыши, чтобы создать ОУ, используйте только что созданную структуру пользовательского столбца, нажмите «Добавить», и вы увидите значение по умолчанию:

Вставьте сюда описание изображения

3. Использование в коде

3.1 Создайте структуру столбца с помощью кода

  В коде вы можете имитировать FGameplayTagTableRow и написать его:

USTRUCT(BlueprintType)
struct FTableRowTest : public FTableRowBase
{
    
    
	GENERATED_USTRUCT_BODY()

public:

	FTableRowTest() {
    
    }

	FTableRowTest(bool InLoop, int32 InCurrentCount, int32 InMaxNum, float InLifeTime)
		: bLoop(InLoop)
	    , CurrentCount(InCurrentCount)
		, MaxNum(InMaxNum)
		, LifeTime(InLifeTime)
	{
    
    
	}

	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "是否循环")
	bool		bLoop = false;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "当前数量")
	int64		CurrentCount = 0;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "最大数量")
	int64		MaxNum = 0;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, DisplayName = "生命周期")
	float		LifeTime = 0.f;
};

  Таким образом, вы можете создать ОУ этой структуры столбца в редакторе (а поскольку структура столбца создается кодом, к ней нельзя перейти в структуре строк. Если это ресурс, вы можете перейти непосредственно к ресурсу структуры. ):
Вставьте сюда описание изображения

3.2 Чтение/запись ОУ через код

  DT можно загрузить непосредственно через путь и имя ресурса в коде. Например, «MyTestDT» в каталоге Content/TestForDT можно загрузить следующим образом:

UDataTable* const TestTable = LoadObject<UDataTable>(nullptr, TEXT("/Game/TestForDT/MyTestDT.MyTestDT"));

  Затем вы можете void UDataTable::AddRow(FName RowName, const FTableRowBase& RowData)добавлять новые строки через . например:

TestTable->AddRow(FName("Bob"), FTableRowTest(true, 3, 8, 2.7f));

3.3 CSV, JSON

  После создания DT вы можете щелкнуть правой кнопкой мыши и экспортировать его в файл CSV или JSON:
Вставьте сюда описание изображения

  В редакторе вы можете импортировать через CSV или JSON через Reimport. Конкретный формат вы узнаете после того, как попробуете:
Вставьте сюда описание изображения

  Вы также можете создать ОУ непосредственно из CSV или JSON в коде (или проекте):

/** 
*	Create table from CSV style comma-separated string. 
*	RowStruct must be defined before calling this function. 
*	@return	Set of problems encountered while processing input
*/
ENGINE_API TArray<FString> CreateTableFromCSVString(const FString& InString);

4. Меры предосторожности

4.1 Копирование контента

  Если после выбора строки вы хотите скопировать ее содержимое, возможны две ситуации:

  1. Если это первый столбец, который является ключевым, выберите строку и F2нажмите
    Вставьте сюда описание изображения

  2. Если это другой столбец, а именно «Значение», вы можете скопировать его в редакторе строк после выбора строки.

4.2 Сортировка

  DT можно отсортировать по значению определенного столбца, но это нонсенс: независимо от того, какого он типа, TEXT преобразуется в FString и затем сравнивается.Исходный код следующий (в функции) FDataTableEditor::OnColumnSortModeChanged:

if (InSortMode == EColumnSortMode::Ascending)
{
    
    
	VisibleRows.Sort([ColumnIndex](
		const FDataTableEditorRowListViewDataPtr& first, 
		const FDataTableEditorRowListViewDataPtr& second)
	{
    
    
		// 返回值:大于 0 表示 A > B; 0 表示相等; 小于 0 表示 A < B		
		int32 Result = (first->CellData[ColumnIndex].ToString()).Compare(second->CellData[ColumnIndex].ToString());
		
		if (!Result)
		{
    
    
			return first->RowNum < second->RowNum;
		}

		return Result < 0;
	});
}

  Сравнение FString — это сортировка по словарю , поэтому 99> 963:

Вставьте сюда описание изображения

  и 2.87> 11.09:
Вставьте сюда описание изображения

  Мой собственный метод модификации — напрямую изменить движок. Если он числовой, сортируйте по числовому типу, а не по строке:

VisibleRows.Sort([ColumnIndex](
	const FDataTableEditorRowListViewDataPtr& first, 
	const FDataTableEditorRowListViewDataPtr& second)
{
    
    					
	int32 Result = (first->CellData[ColumnIndex].ToString()).Compare(second->CellData[ColumnIndex].ToString());

	FString const FirstColumnStr = first->CellData[ColumnIndex].ToString();
    FString const SecondColumnStr = second->CellData[ColumnIndex].ToString();
    bool const bNumeric = FCString::IsNumeric(*FirstColumnStr) && FCString::IsNumeric(*SecondColumnStr);
    if (bNumeric)
    {
    
    
    	double const FirstNum = FCString::Atod(*FirstColumnStr);
        double const SecondNum = FCString::Atod(*SecondColumnStr);
        Result = (FirstNum > SecondNum) ? 1 : ((FirstNum < SecondNum) ? -1 : 0);
    }
				
	if (!Result)
	{
    
    
		return first->RowNum < second->RowNum;
	}

	return Result < 0;
});

5. Справочные материалы

  1. UDataTable — документ Unrael Engine

おすすめ

転載: blog.csdn.net/Bob__yuan/article/details/117457482