๐Ÿ“˜ TIL - ์ปค์„œ/๋“œ๋ž˜๊ทธ UI ์ขŒํ‘œ๊ณ„ยท์ž…๋ ฅยท๋ Œ๋”๋ง ๋””๋ฒ„๊น…

HappyCircleยท2026๋…„ 4์›” 14์ผ

Unreal ๊ฐœ๋ฐœ

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

๐Ÿ“˜ TIL - ์ปค์„œ/๋“œ๋ž˜๊ทธ UI ์ขŒํ‘œ๊ณ„ยท์ž…๋ ฅยท๋ Œ๋”๋ง ๋””๋ฒ„๊น…

๋ฌธ์ œ ์ƒํ™ฉ

์–ด์ œ๊นŒ์ง€๋Š”

UI ๊ตฌ์กฐ / ๋ฐ์ดํ„ฐ ํ๋ฆ„ / Command ์ฒ˜๋ฆฌ

๋ฅผ ์ •๋ฆฌํ•˜๋ฉด์„œ

๋™์ž‘ํ•˜๋Š” UI โ†’ ์—ฐ๊ฒฐ๋œ UI

๊นŒ์ง€ ๋งž์ถ˜ ์ƒํƒœ์˜€๋‹ค.


์˜ค๋Š˜์€ ๊ทธ ์œ„์—

์ปค์„œ UI / ๋“œ๋ž˜๊ทธ ์„ ํƒ / ์ž…๋ ฅ ์ƒํƒœ ํ‘œ์‹œ

๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด์„œ,
ํ”Œ๋ ˆ์ด์–ด ์ž…๋ ฅ์„ ์ง์ ‘ ์‹œ๊ฐ์ ์œผ๋กœ ํ”ผ๋“œ๋ฐฑํ•˜๋Š” ๋ ˆ์ด์–ด๋ฅผ ๋ถ™์ด๋Š” ์ž‘์—…์„ ์ง„ํ–‰ํ–ˆ๋‹ค.


๊ตฌํ˜„ ๋ชฉํ‘œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์•˜๋‹ค.

์ปค์„œ โ†’ ํ˜„์žฌ ์ž…๋ ฅ ์ƒํƒœ ํ‘œํ˜„
๋“œ๋ž˜๊ทธ โ†’ ์„ ํƒ ์˜์—ญ ํ‘œ์‹œ
Command โ†’ ์ž…๋ ฅ ์ƒํƒœ (Move / Attack) ์‹œ๊ฐํ™”

ํ•˜์ง€๋งŒ ๊ตฌํ˜„ ๊ณผ์ •์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.


๋ฐœ์ƒ ์ฆ์ƒ

  • ์ปค์„œ๊ฐ€ ํŠน์ • ์˜์—ญ์—์„œ ์‚ฌ๋ผ์ง
  • ์—ฃ์ง€ ์Šคํฌ๋กค ํ›„ ์ปค์„œ๊ฐ€ ๋ณต๊ท€๋˜์ง€ ์•Š์Œ
  • ์ „์ฒดํ™”๋ฉด์—์„œ ์šฐ์ธก/ํ•˜๋‹จ๋งŒ ์—ฃ์ง€ ์Šคํฌ๋กค ๋™์ž‘ ์•ˆ ํ•จ
  • ๋“œ๋ž˜๊ทธ ๋ฐ•์Šค๊ฐ€ ์ปค์„œ ์œ„์น˜์™€ ๋งž์ง€ ์•Š์Œ
  • ๋“œ๋ž˜๊ทธ UI๊ฐ€ ์ ์„ ์ฒ˜๋Ÿผ ๊นจ์ง
  • ์ปค๋งจ๋“œ ํŒจ๋„ hover ์‹œ ๊ธฐ๋ณธ ์ปค์„œ๊ฐ€ ๋‹ค์‹œ ๋‚˜ํƒ€๋‚จ

๊ณตํ†ต์ ์€

์ž…๋ ฅ์€ ์ •์ƒ์ธ๋ฐ
โ†’ ํ™”๋ฉด ํ‘œํ˜„์ด ์–ด๊ธ‹๋‚œ ์ƒํƒœ

์ฆ‰

์ž…๋ ฅ / ์ขŒํ‘œ / UI ๋ Œ๋”๋ง ๊ธฐ์ค€์ด ์„œ๋กœ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๊ณ  ์žˆ์—ˆ๋‹ค


๋ถ„์„


1. ์ขŒํ‘œ๊ณ„ ํ˜ผ์šฉ ๋ฌธ์ œ (ํ•ต์‹ฌ)

ํ˜„์žฌ ์‹œ์Šคํ…œ์—๋Š” ๋‘ ๊ฐ€์ง€ ์ขŒํ‘œ๊ฐ€ ์กด์žฌํ–ˆ๋‹ค.

Raw Mouse Position (Viewport ๊ธฐ์ค€)
Scaled Mouse Position (DPI ๋ณด์ •๋œ UMG ๊ธฐ์ค€)

๋ฌธ์ œ:

  • ์ปค์„œ๋Š” Scaled ์ขŒํ‘œ
  • ๋“œ๋ž˜๊ทธ๋Š” Raw ์ขŒํ‘œ
  • ์—ฃ์ง€ ์Šคํฌ๋กค๋„ ์ผ๋ถ€ ํ˜ผ์šฉ

๊ฒฐ๊ณผ:

์ปค์„œ ์œ„์น˜ โ‰  ๋“œ๋ž˜๊ทธ ์‹œ์ž‘/๋ ์œ„์น˜

โ†’ ๋“œ๋ž˜๊ทธ ๋ฐ•์Šค๊ฐ€ ์–ด๊ธ‹๋‚จ


2. ์—ฃ์ง€ ์Šคํฌ๋กค ํŒ์ • ๋ถˆ์ผ์น˜

์ „์ฒดํ™”๋ฉด์—์„œ๋งŒ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ:

MousePosition (Scaled)
vs
ViewportSize (Raw)

๋น„๊ต ๊ธฐ์ค€์ด ๋‹ฌ๋ผ์„œ

  • ์ขŒ์ธก/์ƒ๋‹จ โ†’ ์ •์ƒ
  • ์šฐ์ธก/ํ•˜๋‹จ โ†’ ์กฐ๊ฑด ๋ถˆ๋งŒ์กฑ

3. ์ปค์„œ ๋ Œ๋”๋ง ๋ฌธ์ œ

์ฆ์ƒ:

  • ์ปค์„œ๊ฐ€ ์šฐ์ธก/ํ•˜๋‹จ์—์„œ ์‚ฌ๋ผ์ง
  • ํ™”๋ฉด ๋ฐ– ๋‚˜๊ฐ”๋‹ค๊ฐ€ ๋ณต๊ท€ ์•ˆ ๋จ

์›์ธ:

์ปค์„œ ์œ„์ ฏ์ด ์ขŒ์ƒ๋‹จ ๊ธฐ์ค€์œผ๋กœ ๋ฐฐ์น˜๋จ

์ฆ‰

๋งˆ์šฐ์Šค ์œ„์น˜ = ์œ„์ ฏ์˜ ์ขŒ์ƒ๋‹จ

โ†’ ์šฐ์ธก/ํ•˜๋‹จ์—์„œ ํ™”๋ฉด ๋ฐ–์œผ๋กœ ๋ฐ€๋ฆผ


4. ์—ฃ์ง€ ์Šคํฌ๋กค ์ƒํƒœ ๋ณต๊ท€ ๋ฌธ์ œ

์—ฃ์ง€ ์ƒํƒœ ์ง„์ž… ํ›„ ๋ณต๊ท€ ์•ˆ ๋˜๋Š” ์ด์œ :

์ง„์ž… ์กฐ๊ฑด == ํ•ด์ œ ์กฐ๊ฑด

โ†’ ๊ฒฝ๊ณ„๊ฐ’ ๊ทผ์ฒ˜์—์„œ ์ƒํƒœ๊ฐ€ ๊ณ ์ฐฉ๋จ


5. ๋“œ๋ž˜๊ทธ ๋ฐ•์Šค ๋ Œ๋”๋ง ๋ฌธ์ œ

์ฒ˜์Œ ๋ฐฉ์‹:

์ด๋ฏธ์ง€ ๊ธฐ๋ฐ˜ Border (9-slice)

๋ฌธ์ œ:

  • ํ”„๋ ˆ์ž„ ํ…์Šค์ฒ˜๊ฐ€ ๋ฐ˜๋ณต๋จ
  • stretch ์‹œ ์ ์„ ์ฒ˜๋Ÿผ ๊นจ์ง

์ฆ‰
UI ํ”„๋ ˆ์ž„ ์ด๋ฏธ์ง€ โ‰  ๋“œ๋ž˜๊ทธ ๋ฐ•์Šค ์šฉ๋„


6. UMG Cursor ์ถฉ๋Œ ๋ฌธ์ œ

์ปค๋งจ๋“œ ํŒจ๋„ ์œ„์—์„œ:

  • ๊ธฐ๋ณธ ์ปค์„œ ๋‹ค์‹œ ๋‚˜ํƒ€๋‚จ

์›์ธ:

Button / Widget์ด Cursor๋ฅผ ์š”์ฒญ

โ†’ ์†Œํ”„ํŠธ์›จ์–ด ์ปค์„œ์™€ ์ถฉ๋Œ


ํ•ด๊ฒฐ


1. ์ขŒํ‘œ๊ณ„ ๋ถ„๋ฆฌ

์ปค์„œ / ๋“œ๋ž˜๊ทธ โ†’ Scaled (DPI ์ขŒํ‘œ)
์—ฃ์ง€ ์Šคํฌ๋กค โ†’ Raw (Viewport ์ขŒํ‘œ)
GetMousePositionScaledByDPI() โ†’ UI์šฉ
GetMousePosition() โ†’ ์ž…๋ ฅ ํŒ์ •์šฉ

2. ์—ฃ์ง€ ์Šคํฌ๋กค ๊ธฐ์ค€ ํ†ต์ผ

MousePosition (Raw)
vs
ViewportSize (Raw)

์ขŒํ‘œ๊ณ„๋ฅผ ์™„์ „ํžˆ ๋™์ผํ•˜๊ฒŒ ๋งž์ถค


3. ์ปค์„œ ์œ„์น˜ ๋ณด์ •

Position = MousePos - (CursorSize * 0.5f)
  • Clamp ์ถ”๊ฐ€
Clamp(0 ~ ViewportSize - CursorSize)

โ†’ ํ™”๋ฉด ๋ฐ–์œผ๋กœ ๋‚˜๊ฐ€์ง€ ์•Š๊ฒŒ ์ˆ˜์ •


4. ์—ฃ์ง€ ์Šคํฌ๋กค ํžˆ์Šคํ…Œ๋ฆฌ์‹œ์Šค ์ ์šฉ

EnterMargin โ‰  ExitMargin
์ง„์ž…: 10px
๋ณต๊ท€: 20px

โ†’ ์ƒํƒœ ๊ณ ์ฐฉ ๋ฐฉ์ง€


5. ๋“œ๋ž˜๊ทธ ๋ฐ•์Šค ๋ฐฉ์‹ ๋ณ€๊ฒฝ

์ด๋ฏธ์ง€ ๊ธฐ๋ฐ˜ Border โ†’ ํ๊ธฐ

์ƒˆ ๊ตฌ์กฐ:

Canvas
 โ”œ Top Line
 โ”œ Bottom Line
 โ”œ Left Line
 โ”” Right Line
Border 4๊ฐœ๋กœ ์ง์ ‘ ๋ฐ•์Šค ๊ตฌ์„ฑ

โ†’ stretch / ๋ฐ˜๋ณต ๋ฌธ์ œ ์™„์ „ ์ œ๊ฑฐ


6. Cursor ์ถฉ๋Œ ํ•ด๊ฒฐ

SlotButton Cursor = None
  • ์žฅ์‹ ์œ„์ ฏ
Not Hit-Testable

โ†’ ๊ธฐ๋ณธ ์ปค์„œ ์žฌ๋“ฑ์žฅ ์ œ๊ฑฐ


7. ๋“œ๋ž˜๊ทธ ์ขŒํ‘œ ์ •ํ•ฉ์„ฑ ํ™•๋ณด

DragStart = Scaled
Current = Scaled

โ†’ ์ปค์„œ์™€ ๋™์ผ ๊ธฐ์ค€ ์‚ฌ์šฉ


๊ตฌ์กฐ ์ •๋ฆฌ


์ž…๋ ฅ โ†’ UI ํ๋ฆ„

Mouse Input
โ†’ PlayerController

โ†’ (Raw ์ขŒํ‘œ)
   ์—ฃ์ง€ ์Šคํฌ๋กค

โ†’ (Scaled ์ขŒํ‘œ)
   CursorOverlay
   DragOverlay

UI ๋ ˆ์ด์–ด ๋ถ„๋ฆฌ

CursorOverlay
โ†’ ํ˜„์žฌ ์ž…๋ ฅ ์ƒํƒœ ํ‘œ์‹œ

DragSelectionOverlay
โ†’ ์„ ํƒ ์˜์—ญ ํ‘œ์‹œ

CommandPanel
โ†’ ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ๋ช…๋ น

์—ญํ•  ๋ถ„๋ฆฌ

PlayerController
โ†’ ์ž…๋ ฅ ์ฒ˜๋ฆฌ / ์ขŒํ‘œ ๋ถ„๋ฆฌ

PlayerUIBridge
โ†’ UI ์ƒํƒœ ์ „๋‹ฌ

CursorOverlay
โ†’ ์ปค์„œ ํ‘œ์‹œ

DragOverlay
โ†’ ๋“œ๋ž˜๊ทธ ํ‘œ์‹œ

๋ฐœ์ƒ ์›์ธ ์ •๋ฆฌ


1. ์ขŒํ‘œ๊ณ„ ํ˜ผ์šฉ

๊ฐ€์žฅ ํฐ ์›์ธ

Raw vs Scaled ํ˜ผ์šฉ

2. UI์™€ ์ž…๋ ฅ ๊ธฐ์ค€ ๋ถˆ์ผ์น˜

์ž…๋ ฅ ํŒ์ •
โ‰ 
UI ํ‘œํ˜„

3. ์ž˜๋ชป๋œ UI ์ž์‚ฐ ์‚ฌ์šฉ

์•ก์ž ํ”„๋ ˆ์ž„ โ†’ ๋“œ๋ž˜๊ทธ ๋ฐ•์Šค

โ†’ stretch ๊ตฌ์กฐ์™€ ์ถฉ๋Œ


4. UMG ๊ธฐ๋ณธ ๋™์ž‘ ๊ฐ„๊ณผ

Widget Cursor ๊ธฐ๋ณธ๊ฐ’ ์กด์žฌ

5. ์ƒํƒœ ์ „์ด ์กฐ๊ฑด ์„ค๊ณ„ ๋ถ€์กฑ

Enter == Exit

๋ฐฐ์šด ์ 


1. ์ž…๋ ฅ ์‹œ์Šคํ…œ์€ ์ขŒํ‘œ๊ณ„๋ถ€ํ„ฐ ๋ถ„๋ฆฌํ•ด์•ผ ํ•œ๋‹ค

Raw = ์ž…๋ ฅ ํŒ์ •
Scaled = UI ํ‘œํ˜„

2. UI๋Š” โ€œ๊ทธ๋ฆฌ๋Š” ๋ฐฉ์‹โ€์ด ์ค‘์š”ํ•˜๋‹ค

์ด๋ฏธ์ง€๋กœ ํ•ด๊ฒฐ โ†’ ์‹คํŒจ
๊ตฌ์กฐ๋กœ ํ•ด๊ฒฐ โ†’ ์•ˆ์ •

3. ๋“œ๋ž˜๊ทธ ๋ฐ•์Šค๋Š” ๋‹จ์ˆœํ• ์ˆ˜๋ก ์ข‹๋‹ค

๋ณต์žกํ•œ ํ”„๋ ˆ์ž„๋ณด๋‹ค

๋ผ์ธ 4๊ฐœ ๊ตฌ์กฐ

๊ฐ€ ๊ฐ€์žฅ ์•ˆ์ •์ ์ด๋‹ค.


4. ์—ฃ์ง€ ๊ธฐ๋ฐ˜ ๋กœ์ง์€ ํžˆ์Šคํ…Œ๋ฆฌ์‹œ์Šค๊ฐ€ ํ•„์ˆ˜๋‹ค

๊ฒฝ๊ณ„ ๊ธฐ๋ฐ˜ ์‹œ์Šคํ…œ์€ ํ•ญ์ƒ

์ง„์ž… / ๋ณต๊ท€ ๋ถ„๋ฆฌ

๊ฐ€ ํ•„์š”ํ•˜๋‹ค.


5. UMG๋Š” ๊ธฐ๋ณธ ๋™์ž‘์„ ํ•ญ์ƒ ์˜์‹ฌํ•ด์•ผ ํ•œ๋‹ค

Cursor
HitTest
Visibility

์ด ์„ธ ๊ฐ€์ง€๊ฐ€ ์˜๋„์น˜ ์•Š์€ ๋™์ž‘์„ ๋งŒ๋“ ๋‹ค.


6. UI๋Š” โ€œ๋ ˆ์ด์–ดโ€๋กœ ๋‚˜๋ˆ ์•ผ ํ•œ๋‹ค

Cursor
Drag
HUD
World UI

๊ฐ๊ฐ ๋…๋ฆฝ์ ์œผ๋กœ ๊ด€๋ฆฌํ•ด์•ผ ํ•œ๋‹ค.


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

์˜ค๋Š˜ ๋ฌธ์ œ๋Š” ๋‹จ์ˆœํ•œ UI ๊ตฌํ˜„ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ
์ž…๋ ฅ ์ขŒํ‘œ๊ณ„, UI ๋ Œ๋”๋ง, UMG ๊ธฐ๋ณธ ๋™์ž‘์ด ์„œ๋กœ ๋‹ค๋ฅธ ๊ธฐ์ค€์œผ๋กœ ๋™์ž‘ํ•˜๋ฉด์„œ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ์˜€๋‹ค.
์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋ฉด์„œ โ€œ์ž…๋ ฅ์€ Raw, UI๋Š” Scaledโ€๋ผ๋Š” ๊ธฐ์ค€๊ณผ
โ€œ์ด๋ฏธ์ง€๊ฐ€ ์•„๋‹Œ ๊ตฌ์กฐ๋กœ UI๋ฅผ ๋งŒ๋“ ๋‹คโ€๋Š” ์›์น™์„ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

profile
๊ฐœ๋ฐœํ•ฉ์‹œ๋‹ค!

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