[TIL] 251119

๊น€์„ธํฌยท2025๋…„ 11์›” 19์ผ

โœ๏ธToday I Learned

๐Ÿ“… 2025-11-19

  • ์œ„์ ฏ ์Šค์œ„์ฒ˜๋ฅผ ํ™œ์šฉํ•œ UI ์ƒํƒœ ๊ด€๋ฆฌ
  • Toggle ํŒจํ„ด์œผ๋กœ UI Open/Close ํ†ตํ•ฉ
  • ESC ํ‚ค ์šฐ์„ ์ˆœ์œ„ ๊ธฐ๋ฐ˜ UI ๋‹ซ๊ธฐ ๋กœ์ง
  • UInterface๋ฅผ ํ†ตํ•œ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ-C++ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ
  • ๋ฐฉ์–ด์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ์œผ๋กœ UI ์ƒํƒœ ๊ด€๋ฆฌ

์œ„์ ฏ ์Šค์œ„์ฒ˜๋ฅผ ํ™œ์šฉํ•œ UI ์ƒํƒœ ๊ด€๋ฆฌ

ํ•ต์‹ฌ ๊ฐœ๋…

Visibility๋ฅผ ์ง์ ‘ ๋ฐ”๊พธ์ง€ ๋ง๊ณ  SetActiveWidgetIndex()๋งŒ ์‚ฌ์šฉํ•ด์„œ UI ์ „ํ™˜

๊ตฌ์กฐ ์„ค๊ณ„

// WidgetSwitcher_Backpack
enum EBackpackWidgetIndex {
    Empty_Backpack = 0,
    PlayerInventory = 1
};

// WidgetSwitcher_Content  
enum EContentWidgetIndex {
    Empty_Content = 0,
    Container = 1,
    BuildingMode = 2,
    CraftingMode = 3,
    Settings = 4
};

์žฅ์ 

  • ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด์ง (Visibility ์ œ์–ด ๋ถˆํ•„์š”)
  • enum์œผ๋กœ ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ
  • ๊ฐ ์Šค์œ„์ฒ˜๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ๋™์ž‘

Toggle ํŒจํ„ด์œผ๋กœ UI Open/Close ํ†ตํ•ฉ

์‚ฌ์šฉ์ž ์ž…๋ ฅ(Eํ‚ค)ํ‚ค ํ•˜๋‚˜๋กœ UI Open/Close ํ†ตํ•ฉ ๊ด€๋ฆฌ

void ToggleContainer(AContainerActor* Container) {
    // ๊ฐ™์€ ์ƒ์ž๋ฉด ๋‹ซ๊ธฐ
    if (CurrentContainer == Container) {
        CloseCurrentContainer();
        return;
    }
    // ๋‹ค๋ฅธ ์ƒ์ž๋ฉด ๊ต์ฒด
    // ...
}

ESC ํ‚ค ์šฐ์„ ์ˆœ์œ„ ๊ธฐ๋ฐ˜ UI ๋‹ซ๊ธฐ ๋กœ์ง

์š”๊ตฌ์‚ฌํ•ญ

  • ESC๋กœ UI ๋‹จ๊ณ„์ ์œผ๋กœ ๋‹ซ๊ธฐ
  • ์•„๋ฌด๊ฒƒ๋„ ์—†์œผ๋ฉด ํ™˜๊ฒฝ์„ค์ • ์—ด๊ธฐ

๊ตฌํ˜„

void HandleEscapeKey() {
    // 1์ˆœ์œ„: ํ™˜๊ฒฝ์„ค์ • ๋‹ซ๊ธฐ
    if (bIsSettingsOpen) {
        CloseSettings();
        return;
    }
    
    // 2์ˆœ์œ„: ๊ฒŒ์ž„ UI ๋ชจ๋‘ ๋‹ซ๊ธฐ
    if (IsAnyUIOpen()) {
        CloseAllGameUI();
        return;
    }
    
    // 3์ˆœ์œ„: ํ™˜๊ฒฝ์„ค์ • ์—ด๊ธฐ
    OpenSettings();
}

UInterface๋ฅผ ํ†ตํ•œ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ-C++ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ

๋ฌธ์ œ

๋ธ”๋ฃจํ”„๋ฆฐํŠธ๋กœ ๋งŒ๋“  ์œ„์ ฏ์— C++์˜ ์ปจํ…Œ์ด๋„ˆ ์ธ๋ฒคํ† ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋–ป๊ฒŒ ์ „๋‹ฌํ• ๊นŒ?

ํ•ด๊ฒฐ: UInterface ์‚ฌ์šฉ

// C++ ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜
UINTERFACE(Blueprintable)
class UIInventoryWidget : public UInterface {
    GENERATED_BODY()
};

class IIInventoryWidget {
    GENERATED_BODY()
public:
    UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
    void SetInventoryData(UTSInventoryMasterComponent* Inventory);
};
// C++์—์„œ ํ˜ธ์ถœ
if (ContainerWidget->Implements<UIInventoryWidget>()) {
    IIInventoryWidget::Execute_SetInventoryData(
        ContainerWidget, 
        ContainerInventory
    );
}

๋ธ”๋ฃจํ”„๋ฆฐํŠธ ์—ฐ๊ฒฐ

  1. ์œ„์ ฏ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ Class Settings์—์„œ ์ธํ„ฐํŽ˜์ด์Šค ์ถ”๊ฐ€
  2. Event Graph์—์„œ SetInventoryData ์ด๋ฒคํŠธ ๊ตฌํ˜„
  3. ์ „๋‹ฌ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋กœ ์Šฌ๋กฏ UI ์ƒ์„ฑ

๋ฐฉ์–ด์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ์œผ๋กœ UI ์ƒํƒœ ๊ด€๋ฆฌ

๋ฐœ๊ฒฌํ•œ ๋ฒ„๊ทธ

// ๋ฌธ์ œ ์‹œ๋‚˜๋ฆฌ์˜ค
1. ์ƒ์ž ์—ด๋ฆผ (ํƒ€์ด๋จธ ์‹คํ–‰ ์ค‘)
2. ํ™˜๊ฒฝ์„ค์ • ๋ฒ„ํŠผ ํด๋ฆญ
3. ํ™˜๊ฒฝ์„ค์ • ๋‹ซ์Œ
4. CurrentContainer๊ฐ€ ๋‚จ์•„์žˆ๊ณ  ํƒ€์ด๋จธ๋„ ์‹คํ–‰ ์ค‘!

ํ•ด๊ฒฐ

void CloseSettings() {
    bIsSettingsOpen = false;
    
    // โœ… ํ˜น์‹œ ๋‚จ์€ ์ƒํƒœ ์ •๋ฆฌ
    CloseCurrentContainer();  // nullptr์ด๋ฉด ๋ฐ”๋กœ return
    
    UpdateInputMode();
}

void OpenSettings() {
    // โœ… ์—ด๊ธฐ ์ „์— ๊ฒŒ์ž„ UI ์ •๋ฆฌ
    if (IsAnyUIOpen()) {
        CloseAllGameUI();
    }
    // ...
}

๐Ÿ’ก ๋А๋‚€ ์  (What I Felt)

UI ์‹œ์Šคํ…œ์„ ์„ค๊ณ„ํ•˜๋ฉด์„œ "์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋–ค ์ˆœ์„œ๋กœ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ์ง€ ๋ชจ๋ฅธ๋‹ค"๋Š” ๊ฑธ ์ฒด๊ฐํ–ˆ๋‹ค. ์ฒ˜์Œ์—” ์ •์ƒ์ ์ธ ๊ฒฝ๋กœ๋งŒ ์ƒ๊ฐํ–ˆ๋Š”๋ฐ, ์ƒ์ž ์—ด๊ณ  โ†’ ์„ค์ • ์—ด๊ณ  โ†’ ์„ค์ • ๋‹ซ์œผ๋ฉด ์ƒ์ž ํƒ€์ด๋จธ๊ฐ€ ๋‚จ์•„์žˆ๋Š” ๋ฒ„๊ทธ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ๋‹ค.

๋ฐฉ์–ด์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์ค‘์š”์„ฑ์„ ๊นจ๋‹ฌ์•˜๋‹ค. ํŠนํžˆ UI์ฒ˜๋Ÿผ ์ƒํƒœ๊ฐ€ ๋ณต์žกํ•œ ์‹œ์Šคํ…œ์—์„œ๋Š” ๊ฐ ํ•จ์ˆ˜๊ฐ€ "๋“ค์–ด์˜ฌ ๋•Œ ์ƒํƒœ ํ™•์ธ, ๋‚˜๊ฐˆ ๋•Œ ์ •๋ฆฌ"๋ฅผ ์ฒ ์ €ํžˆ ํ•ด์•ผ ํ•œ๋‹ค.


0๊ฐœ์˜ ๋Œ“๊ธ€