
예전부터 구현해보고 싶었던 시스템중 하나인 GridInventory시스템에 대해서 알아보자
우선 이번에 다뤄볼 부분은 인벤토리 토글 로직 구현과 시스템 설계에 필요한 기본적인 설정에 대해서 알아볼 예정이다.
먼저 기본적인 클래스를 생성해주자
| 클래스 | 역할 |
|---|---|
| InventoryComponent | 인벤토리 컴포넌트 |
| InventoryDataStructs | 필요한 구조체 모아두는 클래스 |
| InventoryWidget | 인벤토리 토글 설정 위젯 |
| InventoryGridWidget | 그리드 인벤토리의 레이아웃 위젯 |
| ItmeWidget | 인벤토리에 있는 아이템을 그려줄 위젯 |
먼저 InventoryDataSturcts()클래스에 FLines 구조체 선언
#include "InventoryDataStructs.generated.h"
USTRUCT()
struct FLines
{
GENERATED_USTRUCT_BODY()
FLines()
{
}
TArray<FVector2D> XLines;
TArray<FVector2D> YLines;
};
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "InventoryWidget.generated.h"
class UCanvasPanel;
class UBorder;
class UBackgroundBlur;
/**
*
*/
UCLASS()
class GRIDINVENTORY_API UInventoryWidget : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(VisibleAnywhere, meta = (BindWidget), Category = "UI")
UCanvasPanel* Canvas;
UPROPERTY(VisibleAnywhere, meta = (BindWidget), Category = "UI")
UBorder* BackgroundBorder;
UPROPERTY(VisibleAnywhere, meta = (BindWidget), Category = "UI")
UBackgroundBlur* Blur;
protected:
virtual void NativeConstruct() override;
};
#pragma once
// Imported
#include "Blueprint/UserWidget.h"
#include "Components/Border.h"
#include "Components/CanvasPanel.h"
#include "Components/CanvasPanelSlot.h"
#include "InventoryDataStructs.h"
// Engine
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "InventoryGridWidget.generated.h"
class UCanvasPanel;
class UBorder;
UCLASS()
class GRIDINVENTORY_API UInventoryGridWidget : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(VisibleAnywhere, meta = (BindWidget), Category = "UI")
UCanvasPanel* Canvas;
UPROPERTY(VisibleAnywhere, meta = (BindWidget), Category = "UI")
UBorder* GridBorder;
UPROPERTY(VisibleAnywhere, meta = (BindWidget), Category = "UI")
UCanvasPanel* GridCanvasPanel;
};
Canvas, Border은 GridBorder, CanvasPanel는 GridCanvasPanel로 변수명 변경GridBorder : Anchors는 가운데, Size X: 150, Size Y : 600, Alignment : (0.5, 0.5), Padding : 0, Brush Color : (0, 0, 0, 0.25)
Canvas, Border은 BackgroundBorder, Background Blur는 Blur로 변수명 변경BackgroundBorder : Anchors는 전체로, Padding은 0, Brush Color는 (0, 0, 0, 0.2)로 설정
Blur : Blur Strength는 2.0로 설정
WBP_InventoryGrid : 만들어둔 WBP_InventoryGrid를 WBP_Inventory에 가져오기
InputAction과 IMC에 설정하기

Character클래스에서 IA를 받아줄 변수와 실행함수 선언하고 연결해주기
// GridInvenctoryCharacter.h
protected:
UPROPERTY(EditAnywhere, Category = "Input")
UInputAction* InventoryAction;
protected:
void ToggleInventory();
// GridInvenctoryCharacter.h
protected:
UPROPERTY(EditAnywhere, Category = "UI")
TSubclassOf<UUserWidget> InventoryWidgetClass;
UUserWidget* InventoryWidget;
APlayerController* PC; // 변수명을 PlayerController라고 하게 되면 다른 변수와 충돌할 수 있음
protected:
virtual void BeginPlay() override;
// GridInvenctoryCharacter.cpp
void AGridInvenctoryCharacter::BeginPlay()
{
Super::BeginPlay();
// PlayerController 가져오기
PC = UGameplayStatics::GetPlayerController(GetWorld(), 0);
if (PC)
{
if (InventoryWidgetClass)
{
InventoryWidget = CreateWidget(GetWorld(), InventoryWidgetClass);
InventoryWidget->SetOwningPlayer(PC);
}
}
}
void AGridInventoryCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
// Set up action bindings
if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent))
{
/// ...
// Inventory 추가
EnhancedInputComponent->BindAction(InventoryAction, ETriggerEvent::Started, this, &AGridInventoryCharacter::ToggleInventory);
}
}
void AGridInventoryCharacter::ToggleInventory()
{
// 켜져있으면 마우스 커서 안보이게 하고, 게임모드도 게임으로 변경후 위젯 끄기
if (InventoryWidget->IsInViewport())
{
InventoryWidget->RemoveFromParent();
PC->SetShowMouseCursor(false);
PC->SetInputMode(FInputModeGameOnly());
}
// 꺼져있으면 마우스커서 보이게 하고, 게임모드는 게임과UI동시에 컨트롤할수 있게 변경 후 위젯 키기
else
{
InventoryWidget->AddToViewport();
PC->SetShowMouseCursor(true);
PC->SetInputMode(FInputModeGameAndUI());
}
}

InventoryAction과 InventoryWidgetClass를 에디터에서 연결해주기

