
이전에 아이템과 충돌 시 인벤토리에 넣을수 있는지를 판별한 다음, 가능하다면 사라지지도록 만들어봤다.
이번에는 아이템을 인벤토리에 넣고 인벤토리에 Icon이 나오도록 해보자
그 전에 인벤토리를 I키를 누르면 끄고 켜고 했지만, 일단 켜두고 Visible만 껐다 켰다하는 형식으로 수정하고 진행하자.
void AGridInventoryCharacter::BeginPlay()
{
Super::BeginPlay();
// PlayerController 가져오기
PC = UGameplayStatics::GetPlayerController(GetWorld(), 0);
if (PC)
{
if (InventoryWidgetClass)
{
InventoryWidget = CreateWidget(GetWorld(), InventoryWidgetClass);
InventoryWidget->SetOwningPlayer(PC);
InventoryWidget->AddToViewport();
InventoryWidget->SetVisibility(ESlateVisibility::Collapsed);
}
}
}
void AGridInventoryCharacter::ToggleInventory()
{
if (InventoryWidget->GetVisibility() == ESlateVisibility::Collapsed)
{
InventoryWidget->SetVisibility(ESlateVisibility::Visible);
PC->SetInputMode(FInputModeGameAndUI());
PC->SetShowMouseCursor(true);
}
else
{
InventoryWidget->SetVisibility(ESlateVisibility::Collapsed);
PC->SetInputMode(FInputModeGameOnly());
PC->SetShowMouseCursor(false);
}
}
ItemBase에서 Icon 변수 추가하기protected:
UPROPERTY(EditAnywhere, Category = "Item Info | Icon")
UMaterialInterface* Icon;
아이콘 리소스
https://drive.google.com/drive/folders/1-_0otpQBbicKisdJxRiyxN-iXFvCrWJo
에디터에 추가하고 머터리얼로 만들어주자
먼저 Texture 우클릭 후 - AssetAction - Edit Selection in Property Material 선택

전체 선택 후 Texture Group을 UI로 변경

베이스 머터리얼 생성 (M_IconBase)
- Texture와 회전된 Texture까지 같이 설정해주기

각 아이템마다 머터리얼 인스턴스 생성 후 액터에 넣어주기

GridInventoryCharacter에서 ItemWidgetClass와 ItemWidget변수 추가하고, ItemWidgetClass는 에디터에서 추가해주기

아이템을 추가할때 InventoryComponent에서 아이템을 추가하기 위한 bool값 변수 AddedItem을 추가하고, AddItemAt()에서 마지막에 true값을 넣기
// InventoryComponent.h
public:
bool AddedItem = false;
// InventoryComponent.cpp
void UInventoryComponent::AddItemAt(AItemBase* ItemToAdd, int32 TopLeftIndex)
{
FIntPoint dimensions = ItemToAdd->GetDimension();
FIntPoint tile = IndexToTile(TopLeftIndex); // 좌상단의 타일값
for (int32 i = tile.X; i <= tile.X + dimensions.X - 1; i++)
{
for (int32 j = tile.Y; j <= tile.Y + dimensions.Y - 1; j++)
{
Items[TileToIndex(FIntPoint(i, j))] = ItemToAdd;
}
}
AddedItem = true;
}
AddedItem이 true가 되면 InventoryGridWidget에서 아이템이미지를 추가해주는 코드를 추가하자 -> InventoryComponent::TickComponent()에서 호출void UInventoryComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (AddedItem)
{
InventoryGridWidgetReference->Refresh();
AddedItem = false;
}
}
ItemBase의 배열인 keys선언하고, InventoryComponent의 AllItems의 Key값을 keys 변수에 넣어주자GridCanvasPanel에 사이즈는 자동으로, 위치는 잡아준 위치로ItemWidget을 추가해준다.void UInventoryGridWidget::Refresh()
{
TArray<AItemBase*> keys;
InventoryComponent->GetAllItems().GetKeys(keys);
if (CharacterReference->GetItemWidgetClass())
{
CharacterReference->CreateItemWidget();
for (AItemBase* AddedItems : keys)
{
// ItemWidget의 소유플레이어를 InventoryGrid와 동일하게 셋팅
CharacterReference->GetItemWidget()->SetOwningPlayer(GetOwningPlayer());
int32 x = InventoryComponent->GetAllItems()[AddedItems].X * InventoryComponent->TileSize;
int32 y = InventoryComponent->GetAllItems()[AddedItems].Y * InventoryComponent->TileSize;
PanelSlot = GridCanvasPanel->AddChild(CharacterReference->GetItemWidget());
Cast<UCanvasPanelSlot>(PanelSlot)->SetAutoSize(true);
Cast<UCanvasPanelSlot>(PanelSlot)->SetPosition(FVector2D(x, y));
}
}
}
Refresh(CharacterReference->ItemToAdd); : ItemToAdd는 플레이어와 충돌한 액터이다. (BeginOverlap에서 설정)Icon을 ItemImage에 추가하기Dimension으로 icon의 사이즈 값을 설정하고,SizeBox와 ItemImage의 크기 설정하기void UItemWidget::NativeConstruct()
{
Super::NativeConstruct();
CharacterReference = Cast<AGridInventoryCharacter>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
if (CharacterReference)
{
Refresh(CharacterReference->ItemToAdd);
}
}
void UItemWidget::Refresh(AActor* ItemToAdd)
{
AItemBase* item = Cast<AItemBase>(ItemToAdd);
ItemImage->SetBrushFromMaterial(item->GetIcon());
// 인벤토리에 보이는 icon 사이즈 값 설정
Size = FVector2D(item->GetDimension().X * CharacterReference->GetInventoryComponent()->TileSize,
item->GetDimension().Y * CharacterReference->GetInventoryComponent()->TileSize);
// 사이즈박스 값 설정
BackgroundSizeBox->SetWidthOverride(Size.X); // 가로
BackgroundSizeBox->SetHeightOverride(Size.Y); // 세로
// 이미지 크기 설정
UCanvasPanelSlot* imageAsCanvasSlot = UWidgetLayoutLibrary::SlotAsCanvasSlot(ItemImage);
imageAsCanvasSlot->SetSize(Size);
}
