아이템을 픽업할 시 인벤토리에 이미지 형식으로 추가하는 작업을 해 볼 것이다.
// Inv_SlottedItem.h
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Inv_SlottedItem.generated.h"
class UInv_InventoryItem;
class UImage;
UCLASS()
class INVENTORY_API UInv_SlottedItem : public UUserWidget
{
GENERATED_BODY()
public:
bool IsStackable() const { return bIsStackable; }
void SetIsStackable(bool bStackable) { bIsStackable = bStackable; }
UImage* GetImageIcon() const { return Image_Icon; }
void SetGridIndex(int32 Index) { GridIndex = Index; }
int32 GetGridIndex() const { return GridIndex; }
void SetGridDimensions(const FIntPoint& Dimensions) { GridDimensions = Dimensions; }
FIntPoint GetGridDimensions() const { return GridDimensions; }
void SetInventoryItem(UInv_InventoryItem* Item);
UInv_InventoryItem* GetInventoryItem() const { return InventoryItem.Get(); }
void SetImageBrush(const FSlateBrush& Brush) const;
private:
UPROPERTY(meta = (BindWidget))
TObjectPtr<UImage> Image_Icon;
int32 GridIndex;
FIntPoint GridDimensions;
TWeakObjectPtr<UInv_InventoryItem> InventoryItem;
bool bIsStackable{ false };
};
// Inv_SlottedItem.cpp
#include "Widgets/Inventory/SlottedItems/Inv_SlottedItem.h"
#include "Items/Inv_InventoryItem.h"
#include "Components/Image.h"
void UInv_SlottedItem::SetInventoryItem(UInv_InventoryItem* Item)
{
InventoryItem = Item;
}
void UInv_SlottedItem::SetImageBrush(const FSlateBrush& Brush) const
{
Image_Icon->SetBrush(Brush);
}
SlottedItem을 만들어서 위와 같이 코드를 만들었다.
// Inv_InventoryGrid.h
UPROPERTY(EditAnywhere, Category = "Inventory")
TSubclassOf<UInv_SlottedItem> SlottedItemClass;
UPROPERTY()
TMap<int32, TObjectPtr<UInv_SlottedItem>> SlottedItems;
// Inv_InventoryGrid.cpp
void UInv_InventoryGrid::AddItem(UInv_InventoryItem* Item)
{
if (!MatchesCategory(Item)) return;
FInv_SlotAvailabilityResult Result = HasRoomForItem(Item);
AddItemToIndices(Result, Item);
}
void UInv_InventoryGrid::AddItemToIndices(const FInv_SlotAvailabilityResult& Result, UInv_InventoryItem* NewItem)
{
for (const auto& Availability : Result.SlotAvailabilities)
{
AddItemAtIndex(NewItem, Availability.Index, Result.bStackable, Availability.AmountToFill);
}
}
void UInv_InventoryGrid::AddItemAtIndex(UInv_InventoryItem* Item, const int32 Index, const bool bStackable, const int32 StackAmount)
{
const FInv_GridFragment* GridFragment = GetFragment<FInv_GridFragment>(Item, FragmentTags::GridFragment);
const FInv_ImageFragment* ImageFragment = GetFragment<FInv_ImageFragment>(Item, FragmentTags::IconFragment);
if (!GridFragment || !ImageFragment) return;
UInv_SlottedItem* SlottedItem = CreateSlottedItem(Item, bStackable, StackAmount, GridFragment, ImageFragment, Index);
AddSlottedItemToCanvas(Index, GridFragment, SlottedItem);
SlottedItems.Add(Index, SlottedItem);
}
UInv_SlottedItem* UInv_InventoryGrid::CreateSlottedItem(UInv_InventoryItem* Item, const bool bStackable, const int32 StackAmount, const FInv_GridFragment* GridFragment, const FInv_ImageFragment* ImageFragment, const int32 Index)
{
UInv_SlottedItem* SlottedItem = CreateWidget<UInv_SlottedItem>(GetOwningPlayer(), SlottedItemClass);
SlottedItem->SetInventoryItem(Item);
SetSlottedItemImage(SlottedItem, GridFragment, ImageFragment);
SlottedItem->SetGridIndex(Index);
return SlottedItem;
}
void UInv_InventoryGrid::AddSlottedItemToCanvas(const int32 Index, const FInv_GridFragment* GridFragment, UInv_SlottedItem* SlottedItem) const
{
CanvasPanel->AddChild(SlottedItem);
UCanvasPanelSlot* CanvasSlot = UWidgetLayoutLibrary::SlotAsCanvasSlot(SlottedItem);
CanvasSlot->SetSize(GetDrawSize(GridFragment));
const FVector2D DrawPos = UInv_WidgetUtils::GetPositionFromIndex(Index, Columns) * TileSize;
const FVector2D DrawPosWithPadding = DrawPos + FVector2D(GridFragment->GetGridPadding());
CanvasSlot->SetPosition(DrawPosWithPadding);
}
FVector2D UInv_InventoryGrid::GetDrawSize(const FInv_GridFragment* GridFragment) const
{
const float IconTileWidth = TileSize - GridFragment->GetGridPadding() * 2;
return GridFragment->GetGridSize() * IconTileWidth;
}
void UInv_InventoryGrid::SetSlottedItemImage(const UInv_SlottedItem* SlottedItem, const FInv_GridFragment* GridFragment, const FInv_ImageFragment* ImageFragment) const
{
FSlateBrush Brush;
Brush.SetResourceObject(ImageFragment->GetIcon());
Brush.DrawAs = ESlateBrushDrawType::Image;
Brush.ImageSize = GetDrawSize(GridFragment);
SlottedItem->SetImageBrush(Brush);
}
Inv_InventoryGrid.cpp에 아이템을 추가하는 함수들을 위와 같이 추가한다.
조금 복잡하긴한데 SlottedItem 이미지를 가져와서 크기를 조정하고 아이템을 만들어서 Canvas에 추가하는 함수이다.
아이템 크기를 에터디에서 설정할 수 있고 설정한대로 인벤토리에 이미지가 잘 추가되는 것을 볼 수 있다.
'언리얼 - C++ 프로젝트' 카테고리의 다른 글
| Inventory System (6) 아이템 위치 바꾸기 및 합치기 (1) | 2025.08.05 |
|---|---|
| Inventory System (5) 아이템 스택 (3) | 2025.08.03 |
| Inventory System (3) 인벤토리 그리드 및 인벤토리 컴포넌트 구성 (2) | 2025.07.30 |
| Inventory System (2) 아이템 트레이스 및 인벤토리 창 생성 (0) | 2025.07.25 |
| OpenWorldRpg (28) 활 무기 시스템 구현 3 (0) | 2025.07.01 |