๐Ÿ“˜ TIL - ๋ชจ๋‹ฅ๋ถˆ ์ƒํ˜ธ์ž‘์šฉ ๊ด€๋ จ UI ๋””๋ฒ„๊น…, ๋ฆฌํŒฉํ† ๋ง

HappyCircleยท2026๋…„ 6์›” 2์ผ

Unreal ๊ฐœ๋ฐœ

๋ชฉ๋ก ๋ณด๊ธฐ
138/163

๐Ÿ“˜ TIL - ๋ชจ๋‹ฅ๋ถˆ ์ƒํ˜ธ์ž‘์šฉ ๊ด€๋ จ UI ๋””๋ฒ„๊น…, ๋ฆฌํŒฉํ† ๋ง

๋ฐฐ๊ฒฝ

์˜ค๋Š˜์€ ์–ด์ œ ๊ตฌํ˜„ํ•œ ๋ชจ๋‹ฅ๋ถˆ ์ œ์ž‘ยท์ €์žฅ ์‹œ์Šคํ…œ์˜ UI๊ฐ€ ์‹ค์ œ๋กœ ์˜๋„๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋ฉด์„œ ์‹œ์ž‘ํ–ˆ๋‹ค.

๊ธฐ๋Šฅ์ด "์ฝ”๋“œ์ƒ ์—ฐ๊ฒฐ"์€ ๋˜์–ด ์žˆ์ง€๋งŒ "์‹ค์ œ๋กœ ๋ˆŒ๋ฆฌ์ง€ ์•Š๋Š”" ์ƒํƒœ์˜€๋‹ค. ์ œ์ž‘ ํƒญ์—์„œ ๋ ˆ์‹œํ”ผ๋ฅผ ํด๋ฆญํ•ด๋„ ์•„๋ฌด ๋ฐ˜์‘์ด ์—†์—ˆ๊ณ , ์›”๋“œ๋งต์€ ํ•ด์ƒ๋„์— ๋”ฐ๋ผ ๋ Œ๋”๋ง ์˜์—ญ์ด ๋‹ฌ๋ž๋‹ค. ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ์›์ธ์„ ์ฐพ๋Š” ๊ฒƒ, ์Šคํƒ€์ผ์„ ํ†ต์ผํ•˜๋Š” ๊ฒƒ, ํ•˜๋“œ์ฝ”๋”ฉ์„ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด ์˜ค๋Š˜์˜ ํ๋ฆ„์ด์—ˆ๋‹ค.


1. ์ œ์ž‘ ๋ ˆ์‹œํ”ผ ์„ ํƒ UI ๋””๋ฒ„๊น…

์ œ์ž‘ ํƒญ์—์„œ ๋ ˆ์‹œํ”ผ ์—”ํŠธ๋ฆฌ๋ฅผ ํด๋ฆญํ•ด๋„ ์‹œ๊ฐ์  ๋ฐ˜์‘์ด ์—†๊ณ , ์„ ํƒ ์ƒํƒœ๋„ ๊ธฐ๋ก๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๋ฅผ ์ถ”์ ํ–ˆ๋‹ค.

์›์ธ์€ ๋‘ ๊ฐ€์ง€์˜€๋‹ค. ํ•˜๋‚˜๋Š” Arrow ์œ„์ ฏ์˜ ์œ„์น˜์˜€๋‹ค. left: -20 ์˜คํ”„์…‹์œผ๋กœ ์œ„์ ฏ ๊ฒฝ๊ณ„ ๋ฐ–์— ๋ฐฐ์น˜๋˜์–ด ์žˆ์–ด ScrollBox๊ฐ€ ํด๋ฆฌํ•‘ํ•ด๋ฒ„๋ ธ๋‹ค. ์„ ํƒ ํ‘œ์‹œ ์ž์ฒด๊ฐ€ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์œผ๋‹ˆ ๋ฐ˜์‘์ด ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์˜€๋‹ค.

๋˜ ํ•˜๋‚˜๋Š” Arrow์˜ visibility ์„ค์ •์ด์—ˆ๋‹ค. Visible๋กœ ์„ค์ •๋˜์–ด ์žˆ์–ด ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ํก์ˆ˜ํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.

Arrow ์œ„์น˜: left -20 โ†’ left 4 (๊ฒฝ๊ณ„ ์•ˆ์œผ๋กœ)
Arrow visibility: Visible โ†’ HitTestInvisible (ํด๋ฆญ ํก์ˆ˜ ์ œ๊ฑฐ)

๋‘ ๋ฒˆ์งธ ๋ฌธ์ œ๋Š” SetSelectedRecipe์˜ ์ธ๋ฑ์Šค ๋น„๊ต ์˜ค๋ฅ˜์˜€๋‹ค. ScrollBox ์ž์‹ ์ˆœ๋ฒˆ(Array Index)์œผ๋กœ ๋น„๊ตํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ, ํ•„ํ„ฐ๊ฐ€ ์ ์šฉ๋œ ๊ฒฝ์šฐ DataTable ํ–‰ ๋ฒˆํ˜ธ์™€ ์ž์‹ ์ˆœ๋ฒˆ์ด ๋‹ฌ๋ผ ์—‰๋šฑํ•œ ์—”ํŠธ๋ฆฌ๊ฐ€ ์„ ํƒ๋๋‹ค. WBP_RecipeEntry์— GetRecipeIndex() ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , ๋น„๊ต ๊ธฐ์ค€์„ ์—”ํŠธ๋ฆฌ๊ฐ€ ์ง์ ‘ ๋“ค๊ณ  ์žˆ๋Š” RecipeIndex๋กœ ๊ต์ฒดํ•ด ํ•„ํ„ฐ ์—ฌ๋ถ€์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ์ •ํ™•ํžˆ ๋™์ž‘ํ•˜๋„๋ก ์ˆ˜์ •ํ–ˆ๋‹ค.

์„ ํƒํ•œ ๋ ˆ์‹œํ”ผ๊ฐ€ CurrentRecipeId์— ์ œ๋Œ€๋กœ ๊ธฐ๋ก๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๋„ ์—ฐ๊ณ„ํ•ด ์ˆ˜์ •ํ–ˆ๋‹ค. SetSelectedRecipe๊ฐ€ ์ผ์น˜ํ•˜๋Š” ์—”ํŠธ๋ฆฌ๋ฅผ ์ฐพ์œผ๋ฉด ๊ทธ ์—”ํŠธ๋ฆฌ์˜ RecipeId๋ฅผ ์ฝ์–ด BonfireMenu.CurrentRecipeId์— ์ฆ‰์‹œ ๋™๊ธฐํ™”ํ•˜๋„๋ก ํ–ˆ๋‹ค.


2. ๋ ˆ์‹œํ”ผ ์—”ํŠธ๋ฆฌ ์Šคํƒ€์ผ ๋ฆฌํŒฉํ† ๋ง

๋ ˆ์‹œํ”ผ ๋ชฉ๋ก์˜ ์™ธํ˜•์„ ์ €์žฅ ์Šฌ๋กฏ ์—”ํŠธ๋ฆฌ(WBP_SaveSlotEntry)์™€ ๋™์ผํ•˜๊ฒŒ ํ†ต์ผํ–ˆ๋‹ค.

WBP_SaveSlotEntry์˜ ๊ตฌ์กฐ๋Š” ๋ฒ„ํŠผ ์•ˆ์— FRA_Frame_1(FantasyWarrior ํ”„๋ ˆ์ž„ ์œ„์ ฏ) ๋ฐฐ๊ฒฝ๋งŒ ๋‘๊ณ , ํ…์ŠคํŠธ ์ฝ˜ํ…์ธ ๋Š” ๋ฒ„ํŠผ ๋ฐ”๊นฅ์˜ ์˜ค๋ฒ„๋ ˆ์ด๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ํŒจํ„ด์ด์—ˆ๋‹ค. ๊ธฐ์กด WBP_RecipeEntry๋Š” ํ…์ŠคํŠธ๊ฐ€ ๋ฒ„ํŠผ ๋‚ด๋ถ€์— ์žˆ์—ˆ๋‹ค.

์žฌ๊ตฌ์„ฑ ํ›„ ๋ฃจํŠธ ์œ„์ ฏ๋„ CanvasPanel์—์„œ SizeBox๋กœ ๊ต์ฒด๋๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ ์ƒˆ๋กœ์šด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค. SizeBox๋Š” ๋‚ด๋ถ€ ์ฝ˜ํ…์ธ ์˜ Desired Size๊ฐ€ ์—†์œผ๋ฉด ScrollBox์—์„œ ๋†’์ด๊ฐ€ 0์œผ๋กœ ๊ณ„์‚ฐ๋œ๋‹ค. ์ŠคํŠธ๋ ˆ์น˜ ์•ต์ปค๋กœ ์ฑ„์šด CanvasPanel ๋‚ด๋ถ€์—์„œ๋Š” ์–ด๋–ค ์ž์‹๋„ ๊ณ ์ •๋œ Desired Height๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

CanvasPanel (์ŠคํŠธ๋ ˆ์น˜ ์•ต์ปค ์ž์‹๋“ค)
โ†’ Desired Height = 0
โ†’ SizeBox๋„ 0
โ†’ ScrollBox์—์„œ ๋ชจ๋“  ์—”ํŠธ๋ฆฌ๊ฐ€ height=0์œผ๋กœ ๊ฒน์นจ
โ†’ ์ฒซ ๋ฒˆ์งธ ํ•ญ๋ชฉ๋งŒ ๋ณด์ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž„

MinDesiredHeight: 120์„ ํ™œ์„ฑํ™”ํ•ด ํ•ด๊ฒฐํ–ˆ๋‹ค. SaveSlotEntry๋„ ๋™์ผํ•œ ๊ฐ’์„ ์“ฐ๊ณ  ์žˆ์—ˆ๋‹ค.

๋˜ ํ•˜๋‚˜์˜ ๊ตํ›ˆ์ด ์žˆ์—ˆ๋‹ค. ๋นˆ CanvasPanel์€ Slate๊ฐ€ ๋‚ด๋ถ€ ํŽ˜์ธํŒ…์„ ๊ฑด๋„ˆ๋›ฐ๊ธฐ ๋•Œ๋ฌธ์— GetCachedGeometry()๊ฐ€ (0, 0)์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•ด๊ฒฐ์ฑ…์œผ๋กœ ํˆฌ๋ช…ํ•œ Image ์œ„์ ฏ์„ ์ž์‹์œผ๋กœ ์ถ”๊ฐ€ํ•ด Slate๊ฐ€ ๋ฐ˜๋“œ์‹œ ํŽ˜์ธํŒ…ํ•˜๋„๋ก ๊ฐ•์ œํ–ˆ๋‹ค.


3. ์›”๋“œ๋งต ํ•ด์ƒ๋„ ๋…๋ฆฝ ๋ Œ๋”๋ง

์›”๋“œ๋งต ํ…์Šค์ฒ˜ ๋ Œ๋”๋ง ์˜์—ญ์ด ํ•ด์ƒ๋„์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋Š” ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ–ˆ๋‹ค.

๊ทผ๋ณธ ์›์ธ์€ GetMapViewRect์˜ fallback ๊ณ„์‚ฐ์ด ์œ„์ ฏ ์ „์ฒด(AllottedGeometry) ๊ธฐ์ค€ ๊ณ ์ • ํŒจ๋”ฉ์„ ์“ฐ๊ณ  ์žˆ์—ˆ๋˜ ๊ฒƒ์ด๋‹ค. MapViewport(๋นˆ CanvasPanel)์˜ GetCachedGeometry()๊ฐ€ (0, 0)์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด fallback์ด ๋™์ž‘ํ–ˆ๊ณ , ์ „์ฒด ํ™”๋ฉด ๊ธฐ์ค€ ํŒจ๋”ฉ์€ ํ•ด์ƒ๋„๊ฐ€ ๋‹ฌ๋ผ์ง€๋ฉด ํ‹€๋ ธ๋‹ค.

์ˆ˜์ • ๋ฐฉํ–ฅ์€ ๋‘ ๋‹จ๊ณ„์˜€๋‹ค. ๋จผ์ € MapViewport ์Šฌ๋กฏ์„ ํฌ์ธํŠธ ์•ต์ปค + ํ•˜๋“œ์ฝ”๋”ฉ๋œ ํ”ฝ์…€ ํฌ๊ธฐ์—์„œ ์ŠคํŠธ๋ ˆ์น˜ ์•ต์ปค + ์˜คํ”„์…‹ ๋ฐฉ์‹์œผ๋กœ ๋ณ€๊ฒฝํ•ด ์–ด๋А ํ•ด์ƒ๋„์—์„œ๋„ ์˜ฌ๋ฐ”๋ฅธ ํฌ๊ธฐ๋ฅผ ๊ฐ–๋„๋ก ํ–ˆ๋‹ค. ๊ทธ ๋‹ค์Œ fallback์„ ์ˆ˜ํ•™ ๊ณ„์‚ฐ์œผ๋กœ ๊ต์ฒดํ–ˆ๋‹ค. Border_Window์˜ ํผ์„ผํŠธ ์•ต์ปค(0.02~0.98, 0.04~0.96)์™€ MapViewportPadding ๊ฐ’์„ ๊ณฑํ•ด ํ•ด์ƒ๋„์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ํ•ญ์ƒ ์˜ฌ๋ฐ”๋ฅธ ์˜์—ญ์„ ๊ณ„์‚ฐํ•œ๋‹ค.

์ด์ „: MapViewport ์ง€์˜ค๋ฉ”ํŠธ๋ฆฌ ์‹คํŒจ โ†’ ๊ณ ์ • ํ”ฝ์…€ fallback (ํ•ด์ƒ๋„ ์ข…์†)
์ดํ›„: MapViewport ์ง€์˜ค๋ฉ”ํŠธ๋ฆฌ ์‹คํŒจ โ†’ Border_Window ๋น„์œจ ร— MapViewportPadding (ํ•ด์ƒ๋„ ๋…๋ฆฝ)

MapWindowAnchorMin, MapWindowAnchorMax ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด WBP ๋ ˆ์ด์•„์›ƒ์ด ๋ฐ”๋€Œ๋”๋ผ๋„ ์—๋””ํ„ฐ์—์„œ ์ˆ˜์น˜๋ฅผ ์ง์ ‘ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ถ„๋ฆฌํ–ˆ๋‹ค.


4. ์ธ๋ฒคํ† ๋ฆฌ ํŒจ๋„ ๋ฆฌํŒฉํ† ๋ง

์„ธ ๊ฐ€์ง€๋ฅผ ์ •๋ฆฌํ–ˆ๋‹ค.

์žฌ๋ฃŒ ํƒญ ๋ฒ„ํŠผ(Button_TabMaterial)์„ ๋Ÿฐํƒ€์ž„์— C++๋กœ ์ƒ์„ฑํ•˜๋˜ EnsureMaterialTabButton()์„ ์ œ๊ฑฐํ•˜๊ณ , WBP ๋””์ž์ด๋„ˆ์—์„œ ์ง์ ‘ ๋ฐฐ์น˜ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ „ํ™˜ํ–ˆ๋‹ค. ๋ฌด๊ธฐยท์†Œ๋ชจํ’ˆ ํƒญ์€ WBP์—์„œ ์„ค์ •ํ•˜๋ฉด์„œ ์žฌ๋ฃŒ ํƒญ๋งŒ ์ฝ”๋“œ๋กœ ์ƒ์„ฑํ•˜๋˜ ๋ถˆ์ผ์น˜๊ฐ€ ์‚ฌ๋ผ์กŒ๋‹ค.

RefreshInventoryGridLayout()์ด Tick๋งˆ๋‹ค ๋ชจ๋“  ์ž์‹ ์œ„์ ฏ์˜ Alignment๋ฅผ ๋ฐ˜๋ณต ์„ค์ •ํ•˜๊ณ  ์žˆ์—ˆ๋‹ค. ๊ทธ๋ฆฌ๋“œ ํฌ๊ธฐ๊ฐ€ ์‹ค์ œ๋กœ ๋ฐ”๋€ ๊ฒฝ์šฐ์—๋งŒ ์‹คํ–‰ํ•˜๋„๋ก bGridAreaChanged ์กฐ๊ฑด ์•ˆ์œผ๋กœ ์ด๋™ํ–ˆ๋‹ค.

PopulateWeaponSkillIcons()์—์„œ ํ…์Šค์ฒ˜ ๋กœ๋“œ ์„ฑ๊ณต ์‹œ SetDesiredSizeOverride๋ฅผ ์ค‘๋ณต ํ˜ธ์ถœํ•˜๋˜ ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ–ˆ๋‹ค.


์˜ค๋Š˜์˜ ์ •๋ฆฌ

  • UI ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ณผ์ •์—์„œ ํ™”๋ฉด ํ‘œ์‹œ์™€ ์‹ค์ œ ๋™์ž‘์ด ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ํ™•์ธํ–ˆ๊ณ , ์ง€์˜ค๋ฉ”ํŠธ๋ฆฌ ๊ฐฑ์‹ ๊ณผ ๋ ˆ์ด์•„์›ƒ ๊ณ„์‚ฐ ํ๋ฆ„์„ ์ ๊ฒ€ํ•˜๋ฉฐ ์›์ธ์„ ์ถ”์ ํ–ˆ๋‹ค.
  • Slate์˜ Desired Size ๊ณ„์‚ฐ ๋ฐฉ์‹๊ณผ GetCachedGeometry() ๊ฐฑ์‹  ์‹œ์ ์„ ์ดํ•ดํ•˜๋ฉด์„œ UMG ๋ ˆ์ด์•„์›ƒ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ๋‹ค.
  • ์žฌ๋ฃŒ ํƒญ ๋ฒ„ํŠผ, ์ž…๋ ฅ ์ฒ˜๋ฆฌ, ๋ Œ๋”๋ง ์˜์—ญ ๊ณ„์‚ฐ์„ ์ •๋ฆฌํ•˜๋ฉฐ ์ฝ”๋“œ์™€ ์—๋””ํ„ฐ์˜ ์ฑ…์ž„์„ ๋ถ„๋ฆฌํ–ˆ๋‹ค.
  • ์ „์ฒด์ ์œผ๋กœ ๋””๋ฒ„๊น…์ด ์‰ฌ์šด ๊ตฌ์กฐ๋กœ ๋ฆฌํŒฉํ† ๋งํ•˜๋ฉด์„œ ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ํ™•์žฅ์„ฑ์„ ๊ฐœ์„ ํ–ˆ๋‹ค.
profile
๊ฐœ๋ฐœํ•ฉ์‹œ๋‹ค!

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