저번 글에 이어서, 언리얼 엔진에서 디아블로2 아이템 생성을 구현해본다.
전체 프로젝트 코드는 여기에 있다. 자세한 구현부는 깃허브를 통해 참고하는 게 더 나을 것이다.
디아블로 2 데이터 가져오기
우선 디아블로2의 아이템 및 TreasureClass 데이터를 언리얼 엔진으로 불러와야 하는데, 데이터 파일은 여기서 찾아볼 수 있다. [ JSON파일 / txt파일 ] 본인은 txt파일을 받아서 탭 4개를 쉼표로 바꾸고 파일 확장자를 .csv로 바꿔서 사용했다.
이 데이터를 가져와서 엔진에서 사용하기 위해 만든 것들은 다음과 같다.
- FTableRowBase를 상속받은 구조체를 정의 (FD2로 시작하는 네이밍)
- 이 구조체에 .csv에서 가져오고 싶은 필드만 추가
- 구조체를 좀 더 편하게 다루기 위해서 UObject를 상속받은 나만의 UArmor, UWeapon, UMisc 클래스 추가
- UGameInstanceSubsystem를 상속받은 ULootGenerator의 생성자에서 데이터 테이블을 불러들여, TMap<FName, UArmor> 등등에 데이터들을 추가
디아블로2는 특이하게도 아이템마다 code가 정해져있어서 이를 활용해서 다른 데이터를 참조하기 때문에, code로 아이템 데이터를 바로 조회할 수 있는 TMap을 만들었다.
이제 데이터를 가져온 이후에는 이전 글에서 작성한 메커니즘대로 아이템 생성을 해주면 된다.
아이템 생성하기
총 5가지 함수를 만들었다. 위에서 말했듯이 자세한 구현부는 github를 참고.
// Location 위치에 TreasureClassName에 해당하는 전리품을 스폰한다.
SpawnLootsAt(FVector Location, TArray<FName>& TreasureClassName)
// TreasureClassName일 경우 해당 TC로 가중치 계산해서 ItemCode를 뽑는다.
// ItemCode일 경우 Location에 전리품을 스폰한다.
// Quality는 아이템 등급 계산용.
void GenerateLootAt(FName TreasureClassNameOrItemCode, FVector& Location, FQualityFactor& QualityFactor)
// 디아블로2 TC 데이터 조회하는 유틸리티 함수.
FTreasureClass* FindTreasureClassFromDataTable(FName TreasureClassName);
// 주어진 TC 데이터에 대해서 Picks 및 Prob을 랜덤으로 굴린다.
void RollTreasureClassPicks(FTreasureClass* TreasureClass, FVector& Location, FQualityFactor& QualityFactor);
// ItemCode로 게임 내에서 사용하는 아이템 인스턴스인 UItemBase를 만든다.
TObjectPtr<UItemBase> GenerateItem(FName ItemCode, FQualityFactor& QualityFactor);
모든 과정이 끝나면 UItemBase 를 생성하고, 월드에 ALootActor를 스폰하여 이를 참조시킨다.
이후 테스트를 간편하게 하기 위해서 캐릭터의 블루프린트에 다음과 같이 만들어줬다.
1번 키를 누르면 TreasureClass(weap3) 5개를 액터 로케이션에 스폰하는 테스트이다.
메쉬 제대로 된 걸 구하지 못해서 일단 인피니트 블레이드 에셋으로 떼웠다...ㅠ
5개가 생성되지 않는 것도 메쉬를 지정해주지 않아서 안보이는 것.
마무리
이렇게 해서 디아블로2 절차적 아이템 생성을 구현해보았다. 아이템의 기본적인 스탯(방어도, 무기 데미지 등등)과 아이템의 이름, 종류가 랜덤으로 정해진다.
아쉬운 것은 이 글에서는 단순히 csv를 TMap으로 조회하는 정도로 그쳤지만, 데이터를 가져와서 TreasureClass를 트리형식으로 만들어 활용했으면 어땠을까 싶다. 그래도 생성하는 것 자체는 제대로 동작하니 만족한다.
어차피 다음에 또 핵앤슬래시 관련 시스템을 만들어볼 것이기 때문에 언젠가 계속...