-
[Unreal] 언리얼 ListView 간단하게 알아보기쾌락없는 책임 (공부)/Unreal 2023. 3. 23. 13:35반응형
개요
아이템을 파밍 할 때 아이템에 픽업이 뜨는가, 사용자에게 근처에 있는 아이템 목록을 알려 주는가 등 여러 가지 방법이 있습니다. 저는 프로젝트에서 '플레이어 근처에 있는 아이템들의 목록을 보여주자' 라고 결정을 했고 이에 따라 이 목록을 위한 List View 가 필요했습니다. 다만 역시 알아보면 C++로 처리한 래퍼런스를 찾기 어려워 제가 만든 걸 공유하고자 이렇게 글을 쓰게 됩니다.
- 간단 요약만 알고 싶다면 맨 아래로
C++ 코드로 보는 ListView
class UListView; UCLASS() class PROJECTFA_API UPickupItemList : public UUserWidget { GENERATED_BODY() public: UPROPERTY(meta=(BindWidget)) TObjectPtr<UListView> NearbyItemList; };
일단 ListView의 코드는 이렇게 되어 있습니다. cpp 연동도 없는, 단순히 변수를 저장하기 위한 클래스입니다.
void APlayableController::AddNearbyItem(UObject* Item) { if(NearbyItemListNotValid()) return; ProjectFAHUD->PickupItemList->NearbyItemList->AddItem(Item); } void APlayableController::DeleteNearbyItem(UObject* Item) { if(NearbyItemListNotValid()) return; ProjectFAHUD->PickupItemList->NearbyItemList->RemoveItem(Item); }
이후 저의 경우 Controller에서 NearbyItemList에 AddItem, RemoveItem 을 통해 리스트에 아이템을 추가, 제거하는 작업을 해 줍니다. 이 함수는 플레이어 근처에 아이템이 들어오거나 나가면 불리게 되는 함수입니다.
그런 다음 BP 에서 이 UI들을 만들어 줍니다.
PickupItemList 위 사진에서는 이미 List View 들의 요소들이 저장되어 있지만 요소를 만들어 줘야 합니다. 저의 경우 PickupItemListElement라고 이름 붙인 클래스를 만들었습니다.
class UImage; class UTextBlock; UCLASS() class PROJECTFA_API UPickupItemListElement : public UUserWidget, public IUserObjectListEntry { GENERATED_BODY() public: virtual void NativeOnListItemObjectSet(UObject* ListItemObject) override; public: UPROPERTY(meta=(BindWidget)) TObjectPtr<UImage> ItemImage; UPROPERTY(meta=(BindWidget)) TObjectPtr<UTextBlock> ItemName; };
여기서 중요한 점은 IUserObjectListEntry 인터페이스를 상속해야 한다는 점입니다. 이 인터페이스를 받은 클래스만이 List View에 들어갈 수 있는 것입니다.
이후 각 List View의 요소들 UI를 만들어 준 뒤
이렇게 ListView 의 ListEntries > Entry Widget Class에 이 요소 UI를 넣어줍니다.
이렇게 하면 ListView를 활용해 주변 아이템들을 보여줄 수 있습니다. 다만 디폴트 값인 Text Block으로 되어 있는 것을 볼 수 있습니다. 이때 IUserObjectListEntry를 상속받은 이유가 보이게 됩니다.
void UPickupItemListElement::NativeOnListItemObjectSet(UObject* ListItemObject) { IUserObjectListEntry::NativeOnListItemObjectSet(ListItemObject); const APickupItem* Item = Cast<APickupItem>(ListItemObject); if(Item == nullptr) return; ItemName->SetText(FText::FromString(Item->GetItemName())); }
IUserObjectListEntry에서 상속받는 NativeOnListItemObjectSet 함수를 활용하면 됩니다. 이 함수는 ListView에서 해당 요소가 Set 될때 불리게 되는 함수로 이를 통해서 저는 UObject를 캐스팅, 이후 정보를 받아와 텍스트를 세팅했습니다.
그러면 이렇게 아이템의 이름들을 볼 수 있게 됩니다!
요약
- List View에 들어가는 각 요소(칸)는 IUserObjectListEntry를 상속받은 클래스여야 한다!
- IUserObjectListEntry를 상속받은 뒤 NativeOnListItemObjectSet 함수를 재정의하면 이 요소가 Set 될 때 행동을 정의 가능하다
- List View는 TArray <TObjectPtr <UObject>> 로 이루어져 있습니다.
- 때문에 TArray를 그대로 전달할 수도 있습니다.(이때는 SetListItems 함수 활용)
- 내부적으로 TArray의 함수를 활용하므로 단순 Add, Remove를 해주면 다 처리를 해 줍니다.
- 또한 각 요소가 UObject로 전달되기에 각 요소들의 NativeOnListItemObjectSet에서는 캐스팅을 해줘야 합니다.
참고자료
UListView
A virtualized list that allows up to thousands of items to be displayed.
docs.unrealengine.com
반응형'쾌락없는 책임 (공부) > Unreal' 카테고리의 다른 글
[Unreal] NewObject로 생성한 오브젝트에서 GetWorld() 가 nullptr 이라면 (0) 2023.04.19 [Unreal] UI Click, Hover 이벤트 안불리는 문제 (0) 2023.03.27 [Unreal] Unreal StaticMeshComponent0 has to be ‘Movable’ if you’d like to move 경고 (0) 2023.03.21 [Unreal] Unreal Engine IK solver - IK는 어떤 원리로 동작할까? (1) 2023.03.20 [Unreal] Additive Animation - 애디티브 애니메이션 (1) 2023.03.13