개요
아이템의 등장 확률이나 회복물약의 수치 등을 하드코딩 하게 된다면 나중에 기획이 변경되었을 때 일일히 수정해줘야하고 변경될때마다 빌드를 해줘야한다.
따라서 실제 게임개발에서는 CSV형식으로 데이터를 따로 관리하는 경우가 많은데 언리얼에서 데이터테이블을 만드는 방법을 알아보자.
FTableRow
먼저 가지고 올 데이터의 정보들을 구조체 형식으로 만들어줘야한다.
new C++ class로 아무것도 상속하지 않도록 None을 선택하고 생성해준다.
이후 다음과 같은 정보를 가진 CSV의 행을 받아오기 위해서 구조체를 만들어준다.
여기서 수정한 부분은
- 리플렉션 시스템에 등록
- USTRUCT(BlueprintType) 으로 선언
- .generated.h include
- GENERATED_BODY()
- FTableRowBase를 상속
- 데이터 Row에 해당하는 변수 선언 후 UPROPERTY()
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "Engine/DataTable.h"
#include "CoreMinimal.h"
#include "FItemSpawnRow.generated.h"
/**
*
*/
USTRUCT(BlueprintType)
struct FItemSpawnRow : public FTableRowBase
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FName ItemName;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSubclassOf<AActor> ItemClass;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float Spawnchance;
};
데이터 테이블
CSV파일을 직접 만들어서 사용할 수도 있고 언리얼에서 직접 데이터테이블을 만들 수도 있다.
CSV 파일 임포트
첫번째 열을 행을 선택하기 위한 Key값으로 사용된다. 클래스 경로는 에디터에서 Copy Reference를 하자.
블루프린트의 경우 _C를 붙여야 BP클래스로 인식하므로 꼭 붙여주자.
파일을 저장할때 아무 위치에 저장하고 저장형식은 CSV UTF-8로 바꿔준다.
언리얼 에디터에서 Content Browser/Import to ~~ 을 선택한 다음 우리가 만든 Struct를 Row Type으로 설정하고 Apply해준다.
그러면 해당 CSV를 기준으로 데이터 테이블 에셋이 생성된다.
언리얼 에디터에서 수정
Miscellaneous> Data Table 선택
똑같이 FTableRawBase를 상속받은 클래스를 선택하면 데이터테이블이 생성된다.
Add를 통해 행들을 추가하면 끝
DataTable 활용
DataTable을 활용하기 위해서는 DataTable을 프로퍼티로 가져오고 DataTable의 Row에 접근해서 해당 데이터를 사용한다.
DataTable을 활용하여 확률에 따라 Ramdom한 Row를 가져오는 함수이다.
FItemSpawnRow* ASpawnVolume::GetRandomItem() const
{
if (!ItemDataTable) return nullptr;
//get all row
TArray<FItemSpawnRow*> AllRows;
static const FString ContextString(TEXT("ItemSpawnContext")); //DataTable에서 행을 가져올때 오류가 발생하면 오류에 추가되는 문자열
ItemDataTable->GetAllRows(ContextString, AllRows);
if (AllRows.IsEmpty()) return nullptr;
float TotalChance = 0.0f;
for (const FItemSpawnRow* Row : AllRows)
{
if (Row)
{
TotalChance += Row->Spawnchance;
}
}
const float RandValue = FMath::FRandRange(0.f, TotalChance);
float AccumulateChance = 0.f;
for (FItemSpawnRow* Row : AllRows)
{
AccumulateChance += Row->Spawnchance;
if (RandValue <= AccumulateChance)
{
return Row;
}
}
return nullptr;
}
'Unreal' 카테고리의 다른 글
[Unreal] Lyra - Anim Blueprint (1) (0) | 2025.01.26 |
---|---|
[Unreal C++] Game Flow (0) | 2025.01.23 |
[Unreal C++] Enhanced Input System (0) | 2025.01.21 |
[Unreal] State Machine (0) | 2025.01.21 |
[Unreal C++]1주차 강의 정리 (0) | 2025.01.20 |