๋ฉ์ธ๋ฉ๋ด์์ ํ์์ผ๋ก ์ฃฝ์ด ์๋(SetIsEnabled(false) + TODO ์ฃผ์) "์ด์ดํ๊ธฐ"ยท"๋ถ๋ฌ์ค๊ธฐ" ๋ฒํผ์ ์ค์ ๋ก ๋์ํ๊ฒ ํ๋ค. "์ด์ดํ๊ธฐ"๋ ์ฌ๋กฏ ์ ํ ์์ด ๊ฐ์ฅ ์ต๊ทผ์ ์ ์ฅํ ์ฌ๋กฏ์ ์ฆ์ ๋ก๋ํด์ผ ํ๋ค.
์ธ์ด๋ธ ๋ฉํ์ ์ด๋ฏธ ์๋ SaveTimestamp๊ฐ "%Y-%m-%d %H:%M" ํ์์ด๋ผ, ํ์ฑ ์์ด ๋ฌธ์์ด ๋น๊ต(>)๋ง์ผ๋ก ์๊ฐ์ ์ ๋ ฌ์ด ์ฑ๋ฆฝํ๋ค(์๋ฆฟ์ ๊ณ ์ + ํฐ ๋จ์๋ถํฐ ๋์ด๋๋ ํ์์ด๋ผ ์ฌ์ ์ == ์๊ฐ์). GetMostRecentSaveSlotIndex()๋ ์กด์ฌํ๋ ์ฌ๋กฏ์ ์ํํ๋ฉฐ ์ด ๋น๊ต ํ๋๋ก ์ต์ ์ฌ๋กฏ์ ๊ณ ๋ฅธ๋ค.
// SaveTimestamp๋ "%Y-%m-%d %H:%M" ํ์์ด๋ผ ๋ฌธ์์ด ๋น๊ต๋ง์ผ๋ก ์๊ฐ์ ์ ๋ ฌ์ด ์ฑ๋ฆฝํ๋ค.
if (BestSlot == INDEX_NONE || Save->SaveTimestamp > BestTimestamp) { ... }
๋ฒํผ โ ๋ก๋๊น์ง์ ํ๋ฆ์ ์ ๊ท ๊ฒ์๊ณผ ๋์ผํ ์๋ฒ ๊ถ์ ๊ฒฝ๋ก๋ก ํต์ผํ๋ค:
ContinueButton ํด๋ฆญ โ PC->RequestContinueGame() โ Server_RequestContinueGame (RPC)
โ GameMode::HandleContinueGame (IsRequestorHost ๊ฒ์ฌ)
โ SaveSubsystem::LoadFromSlot() ์ฑ๊ณต ์ โ GameState::TransitionTo(InGame)
๋ฒํผ ํ์ฑํ ์กฐ๊ฑด๋ HasSaveGame() ๊ฒฐ๊ณผ(bSaveDataExists)๋ก ๋ฐ๊ฟ, ์ธ์ด๋ธ๊ฐ ์์ผ๋ฉด ์ด์ดํ๊ธฐ/๋ถ๋ฌ์ค๊ธฐ๊ฐ ์์ฐ์ค๋ฝ๊ฒ ๋นํ์ฑํ๋๋ค.
์ ๋ ฌ ๊ฐ๋ฅํ ๋ฌธ์์ด ํฌ๋งท์ ๊ทธ ์์ฒด๋ก ์ธ๋ฑ์ค๋ค.
FDateTime์ฌํ์ฑ์ด๋ ๋ณ๋ ํ๋ ์ถ๊ฐ ์์ด, ์ ์ฅ ํ์์ด "๊ณ ์ ์๋ฆฟ์ + ํฐ ๋จ์ ์ฐ์ "์ด๊ธฐ๋ง ํ๋ฉด ๋ฌธ์์ด ๋น๊ต๋ก ์ต์ ํ์ ์ด ๋๋๋ค โ ๋จ, ์ด ์ฑ์ง์ ํฌ๋งท์ ์์กดํ๋ฏ๋ก ํฌ๋งท์ ๋ฐ๊พธ๋ ์๊ฐ ๊ฐ์ด ๊นจ์ง๋ค๋ ๊ฑธ ์ฃผ์์ผ๋ก ๋จ๊ฒจ๋ฌ์ผ ํ๋ค.
๋ฉ๋ด ๊ธฐ๋ฅ๋ ๊ฒ์ํ๋ ์ด์ ๊ฐ์ ๊ถ์ ๊ฒฝ๋ก๋ฅผ ํ์ด๋ค. "๋ฉ๋ด ๋ฒํผ์ธ๋ฐ ๋ญ" ํ๊ณ ํด๋ผ์ด์ธํธ์์ ์ง์ ๋ก๋ํ์ง ์๊ณ Server RPC โ GameMode ํธ๋ค๋ฌ(ํธ์คํธ ๊ฒ์ฌ ํฌํจ) ๊ตฌ์กฐ๋ฅผ ์ฌ์ฌ์ฉํ๋ฉด, ์ดํ ๋ฉํฐํ๋ ์ด ํ์ฅ ์ ๋ฉ๋ด ๊ณ์ด๋ง ๋ฐ๋ก ๊ณ ์น ์ผ์ด ์๋ค.
"๋ถ๋ฌ์ค๊ธฐ" ํ๋ฉด(WBP_LoadGame + URetrieveLoadGameWidget)์ ์ฌ๋กฏ ๋ฆฌ์คํธ๋ฅผ, ๋ชจ๋ฅ๋ถ ์ ์ฅ ํญ์์ ์ด๋ฏธ ์ฐ๊ณ ์๋ WBP_SaveSlotEntry๋ฅผ ์์
์์ ์์ด ๊ทธ๋๋ก ์ฌ์ฌ์ฉํด์ ๋ง๋ ๋ค(๋์์ธ ์ผ๊ด์ฑ + ์ค๋ณต ์์ ฏ ๋ฐฉ์ง).
OwnerMenu ํ์
๊ณ ์ : WBP_SaveSlotEntry์ ํด๋ฆญ ํต์ง ๋์์ธ OwnerMenu ๋ณ์๊ฐ WBP_BonfireMenu_C ์ ์ฉ ํ์
์ผ๋ก ์ ์ธ๋ผ ์์ด, ๋ค๋ฅธ ๋ฉ๋ด๊ฐ ์์ ์ Owner๋ก ๋ฑ๋กํ ์ ์๋ค.SlotIndex ์ธ์คํด์ค ํธ์ง ๋ถ๊ฐ: ์ํธ๋ฆฌ์ ์ฌ๋กฏ ๋ฒํธ ๋ณ์๊ฐ Instance Editable์ด ์๋์ด์, ๋์์ด๋์์ 5๊ฐ๋ฅผ ๋ฐฐ์นํด๋ ๊ฐ๊ฐ์ 0~4๋ฅผ ์ง์ ํ ๋ฐฉ๋ฒ์ด ์๋ค.OwnerMenu ๊ฒฝ์ ๋ฅผ ํฌ๊ธฐํ๊ณ , ์ํธ๋ฆฌ ๋ด๋ถ์ Button์ GetWidgetFromName์ผ๋ก ์ฐพ์ C++์์ ์ง์ OnClicked/OnHovered๋ฅผ ๋ฐ์ธ๋ฉํ๋ค (HandleSlot0Clicked~HandleSlot4Clicked).WidgetTree->ConstructWidget์ผ๋ก ๋์ ์ฃผ์
ํ๋ค(์ธ๋ค์ผ์ฉ SizeBox+Image, Text_QuestName). ๋จ ์ฌ๊ธฐ์ ํจ์ ์ด ์์๋ค โ ๋ถ๋ชจ๊ฐ CanvasPanel์ธ ์๋ฆฌ(์ฐ์ธก ํ๋ฆฌ๋ทฐ์ ํ์คํธ ํ
์คํธ)๋ ๋์ ์์ฑ ์ ์ฌ๋กฏ ์ค์ ์์ด (0,0)์ ๋ถ์ด ํ๋ฉด ์ข์๋จ์ ๋ ๋ฒ๋ฆฌ๋ฏ๋ก, VerticalBox์ฒ๋ผ ์๋ ๋ฐฐ์น๋๋ ๋ถ๋ชจ ์๋์์๋ง ๋์ ์์ฑ ํด๋ฐฑ์ ๋๊ณ , CanvasPanel ์๋ฆฌ๋ WBP์ ์ค์ ๋ฐฐ์น๋ ์์ ฏ๋ง ์ฌ์ฉํ๋๋ก ๊ฐ๋๋ค.๋ถ๊ฐ๋ก, ๊ตฌํ ์ธ์ด๋ธ์ ์ธ๋ค์ผ PNG๊ฐ ์ํ 0์ผ๋ก ์ ์ฅ๋ผ ํฌ๋ช
ํ๊ฒ ๋ณด์ด๋ ๋ฌธ์ ๋ ๋์ฝ๋ฉ ์งํ ํฝ์
์ํ๋ฅผ 255๋ก ๊ฐ์ ํ๋ ๋ง์ด๊ทธ๋ ์ด์
(DecodeThumbnail)์ผ๋ก ๋ก๋ ์์ ์ ํก์ํ๊ณ , ํด๋ฆญ ์ ํ ํ์ด๋ผ์ดํธ(๊ณจ๋ ๊ธ๋ก์ฐ)๋ ๋ชจ๋ฅ๋ถ ๋ฉ๋ด์ ๋์ผ ๊ท์น์ผ๋ก ๋ง์ถฐ BonfireMenuWidget๊ณผ RetrieveLoadGameWidget ์์ชฝ์ ๊ฐ์ ์ฝ๋๋ฅผ ์ ์ฉํ๋ค.
๊ณต์ WBP ์ฌ์ฌ์ฉ์ ์ง์ง ๋น์ฉ์ "์์ ฏ์ ๊ทธ๋ฆฌ๋ ๊ฒ"์ด ์๋๋ผ "๊ทธ ์์ ฏ์ ์๋ฌต์ ๊ณ์ฝ"์ ์๋ค. OwnerMenu ํ์ , ์ธ์คํด์ค ํธ์ง ๋ถ๊ฐ ๋ณ์, ์๋ ์๋ธ์์ ฏ โ ์ ๋ค WBP๋ฅผ ๊ณ ์น๋ฉด ํ ์ค์ด์ง๋ง, ๊ทธ๋ฌ๋ฉด ์ด๋ฏธ ์ฐ๋ ํ๋ฉด(๋ชจ๋ฅ๋ถ)์ ํ๊ท ์ํ์ด ์๊ธด๋ค. ํธ์คํธ ์ชฝ C++์์ ํก์ํ๋ ๋ฐฉ์์ ์ฝ๋๊ฐ ๋์ด๋๋ ๋์ ๊ณต์ ์์ ์ ๊ธฐ์กด ์ฌ์ฉ์ฒ๋ฅผ ์์ ํ ๋ณด์กดํ๋ค.
๋์ ์์ ฏ ์ฃผ์ ์ ๋ถ๋ชจ ํจ๋ ํ์ ์ ๋จผ์ ๋ณธ๋ค. VerticalBox/HorizontalBox๋ AddChild๋ง์ผ๋ก ์์ฐ์ค๋ฝ๊ฒ ๋ฐฐ์น๋์ง๋ง CanvasPanel์ ์ฌ๋กฏ(์ต์ปค/์คํ์ )์ ์ง์ ์ค์ ํ์ง ์์ผ๋ฉด (0,0)์ ๋ฌ๋ค โ "ํด๋ฐฑ์ผ๋ก ๋์ ์์ฑ"์ด ํญ์ ์์ ํ ๊ฒ ์๋๋ผ, ๋ถ๋ชจ๊ฐ ์๋ ๋ฐฐ์นํ์ผ ๋๋ง ์์ ํ๋ค.
์ธ์ด๋ธ์ ํ์คํธ ์งํ(์๋ฃ ์คํ ๋ชฉ๋กยท์ถ์ ์คํ ยท๋ํ ๋ถ๊ธฐ ์ ํ ๊ธฐ๋ก)์ ํฌํจ์ํค๊ณ , ๋ถ๋ฌ์ค๊ธฐ ์ ๊ทธ๋๋ก ๋ณต์ํ๋ค. ์ด๋ ์ด๋ฏธ ์๋ฃํ๋ ์คํ ๋ค์ "ํ์คํธ ์๋ฃ!" ์๋ฆผ์ด ๋ก๋ ์งํ ์ฐ์๋ก ์ฌ์๋๋ฉด ์ ๋๋ค.
UQuestBranchComponent::CompleteStep์ ์ ํ ์กฐ๊ฑด ๊ฒ์ฌ์ ์๋ฆผ ๋ธ๋ก๋์บ์คํธ๊ฐ ๋ฌถ์ฌ ์๋ ๊ฒ์ํ๋ ์ด์ฉ ์ง์
์ ์ด๋ค. ์ ์ฅ๋ ์คํ
N๊ฐ๋ฅผ ์ด ๊ฒฝ๋ก๋ก ํ๋์ฉ ์ฌ์๋ฃ์ํค๋ฉด ์๋ฆผ ์๋ธ์์คํ
๊ณผ ๋ณต์ ํด๋ผ์ด์ธํธ์ OnRep_CompletedSteps๊ฐ ์ ๋ถ "๋ฐฉ๊ธ ์๋ฃ๋จ"์ผ๋ก ํ์ ํ๋ค.
๋ณต์ ์ ์ฉ API(MakeQuestSaveData/ApplyQuestSaveData)๋ฅผ ๋ถ๋ฆฌํด ์ํ๋ฅผ ํต์งธ๋ก ๋ฎ์ด์ฐ๋, ์๋ฆผ์ด ๊ธฐ์ค์ผ๋ก ์ผ๋ ๋ฒ ์ด์ค๋ผ์ธ๋ค์ ๋ณต์๋ ์ํ๋ก ์ฌ์๋ฉํ๋ค:
CompletedSteps = InCompletedSteps;
// OnRep_CompletedSteps๊ฐ ๋ณต์ ํด๋ผ์ด์ธํธ์์ ์ด ์คํ
๋ค์ "์๋ก ์๋ฃ๋จ"์ผ๋ก ์ฌ์๋ฆผํ์ง ์๋๋ก ๊ธฐ์ค์ ์ ๋ง์ถ๋ค.
LastSeenCompletedSteps = CompletedSteps;
ํธ์ถ๋ถ(SaveSubsystem)๋ ๋ณต์ ํ QuestNotificationSubsystem->ResetBaseline()์ผ๋ก ์๋ฆผ ์๋ธ์์คํ
์ ๊ธฐ์ค์ ๋ ๋ง์ถ ๋ค, UI(ํธ๋์ปค/ํ์คํธ๋ก๊ทธ)์๋ ๊ฐฑ์ ์ ํธ(Channel_Quest_StepChanged)๋ฅผ ๋ฑ ํ ๋ฒ๋ง ๋ธ๋ก๋์บ์คํธํ๋ค. "๊ฐ๋ณ ์ด๋ฒคํธ ์ฌ์"๊ณผ "์ต์ข
์ํ ํต์ง"๋ฅผ ๋ถ๋ฆฌํ ๊ฒ.
์ํ ๋ณต์์ ์ํ ์ ์ด๊ฐ ์๋๋ค. ๊ฒ์ํ๋ ์ด ์ง์ ์ (CompleteStep)์ "์ ์ด"๋ฅผ ์ ์ ๋ก ์๋ฆผยท๊ฒ์ฆ์ด ๋ฌถ์ฌ ์์ด์, ๋ก๋ ๋ณต์์ ์ฌ์ฌ์ฉํ๋ฉด ๋ถ์์ฉ(์๋ฆผ ์ฐ์)์ด ๋ฐ๋ผ์จ๋ค. ๋ณต์ ์ ์ฉ API๋ฅผ ๋ถ๋ฆฌํ๊ณ , ๊ทธ API๊ฐ ์๋ตํ ์ฑ ์(์๋ฆผ ๋ฒ ์ด์ค๋ผ์ธ, UI ๊ฐฑ์ )์ ํธ์ถ๋ถ ๊ณ์ฝ์ผ๋ก ๋ฌธ์ํํ๋ ํธ์ด ๋ช ํํ๋ค.
"์๋ฆผ ์ ํจ"๋ง์ผ๋ก๋ ๋ถ์กฑํ๊ณ , ์๋ฆผ ์์คํ ์ '๊ธฐ์ค์ '๊น์ง ์ฎ๊ฒจ์ผ ํ๋ค. ๋ณต์ ์์ ์ ์กฐ์ฉํ ๋์ด๊ฐ๋ ๋ฒ ์ด์ค๋ผ์ธ์ด ์ ์ํ๋ฉด ๋ค์ ์ ์ ์๋ฃ ๋ ๋ฐ๋ฆฐ ์ฐจ์ด๊ฐ ํ๊บผ๋ฒ์ ์๋ฆผ์ผ๋ก ํฐ์ง๋ค โ ์ํ๋ฅผ ๋ฎ์ด์ฐ๋ ์ชฝ์ด ๋น๊ต ๊ธฐ์ค(LastSeen, Baseline)๋ ํจ๊ป ๋ฎ์ด์ธ ์ฑ ์์ด ์๋ค.
์ ์ฅ ์ฌ๋กฏ ๋ฆฌ์คํธ์ ๋ถ๋ฌ์ค๊ธฐ ํ๋ฆฌ๋ทฐ์ "์ด ์ธ์ด๋ธ๊ฐ ์ด๋ ํ์คํธ๋ฅผ ์งํ ์ค์ด์๋์ง"(ํ์คํธ๋ช + ์ฒซ ๋ฏธ์๋ฃ ๋ชฉํ ๋ฌธ๊ตฌ)๋ฅผ ๋ณด์ฌ์ค๋ค.
ํ๋ ์ด์ด๊ฐ ๋ช
์์ ์ผ๋ก ์ถ์ ์ ๋ฐ๊ฟจ๋์ง๋ QuestTrackerViewModel์ ๋ก์ปฌ ์ํ๋ก๋ง ์กด์ฌํ๊ณ , ์ธ์ด๋ธ๊ฐ ์ ๊ทผํ ์ ์๋ GameState/์ปดํฌ๋ํธ์๋ ์๋ค. ๊ทธ๋ ๋ค๊ณ ์ธ์ด๋ธ๋ฅผ ์ํด HUD ์ํ๋ฅผ GameState๋ก ๋์ด์ฌ๋ฆฌ๋ ๊ฑด ๋ฐฐ๋ณด๋ค ๋ฐฐ๊ผฝ์ด ์ปค์ง๋ค.
QuestTrackerViewModel::Recompute์ ๊ธฐ๋ณธ ์ ์ ๊ท์น(DisplayOrder ์ ๋ ฌ โ ์ ๊ธ ํด์ ๋๊ณ ๋ฏธ์๋ฃ์ธ ํ์คํธ ์ค ๋ฉ์ธ ์ฐ์ , ์์ผ๋ฉด ์๋ฌด๊ฑฐ๋)์ ์ ์ฅ ์์ ์ ๊ทธ๋๋ก ๋ค์ ๋๋ ค์, ๊ฒฐ๊ณผ๋ฅผ TrackedQuestName/TrackedQuestObjective ํ์์ฉ ๋ฌธ์์ด๋ก ์ธ์ด๋ธ ๋ฉํ์ ์ ์ฅํ๋ค. UI(๋ชจ๋ฅ๋ถ ์ฌ๋กฏยท๋ถ๋ฌ์ค๊ธฐ ๋ฆฌ์คํธยทํ๋ฆฌ๋ทฐ)๋ ์ด ๋ฌธ์์ด์ ๊ทธ๋๋ก ๋ฟ๋ฆฌ๊ธฐ๋ง ํ๋ค.
์ธ์ด๋ธ ๋ฉํ์๋ "์ฌ๊ณ์ฐ ๊ฐ๋ฅํ ์ฐธ์กฐ"๋ณด๋ค "๋ฐ์ ๋ ํ์ ๋ฌธ์์ด"์ด ๋ง์ ๋๊ฐ ์๋ค. ์ฌ๋กฏ ๋ฆฌ์คํธ๋ ๋ก๋ ์ ์ ํ์๋ผ์ผ ํ๋ฏ๋ก ์ด์ฐจํผ ์ธ์ด๋ธ ํ์ผ ์์์ ์๊ธ์์กฑํด์ผ ํ๋ค โ ํ๊ทธ๋ฅผ ์ ์ฅํ๊ณ ํ์ ์์ ์ DataTable์ ๋ค์ ์กฐํํ๋ ๊ฒ๋ณด๋ค, ์ ์ฅ ์์ ์ ํ์ ๋ ๋ฌธ์์ด์ ๋ฃ๋ ์ชฝ์ด ๋ก๋ ์ UI์ ์์ ํ๋ค(ํ ์ด๋ธ์ด ๋ฐ๋์ด๋ "๊ทธ๋ ๊ทธ ์ํ"๋ฅผ ๋ณด์ฌ์ค๋ค).
์๋ณธ ์ํ์ ์ ๊ทผํ ์ ์์ผ๋ฉด "๊ฐ์ ๋ก์ง์ผ๋ก ์ฌ๊ณ์ฐ"์ด ์ฐจ์ ์ด๊ณ , ๊ทธ ์ฌ์ค์ ์ฃผ์์ผ๋ก ๋จ๊ธด๋ค. ๋ช ์์ ์ถ์ ๋ณ๊ฒฝ๊น์ง ๋ฐ์ํ์ง ๋ชปํ๋ ๊ทผ์ฌ์น๋ผ๋ ํ๊ณ๋, ์ฝ๋๋ง ๋ด์๋ ์ ๋ณด์ด๋ฏ๋ก "HUD ๋ก์ปฌ ์ํ๋ผ ์ธ์ด๋ธ์ ์์, ๊ธฐ๋ณธ๊ฐ ๊ธฐ์ค์ผ๋ก ๊ณ์ฐ"์ ์ฃผ์์ผ๋ก ๋ฐ์๋๋ค.
๋ฉ์ธ๋ฉ๋ด์์ "๋ถ๋ฌ์ค๊ธฐ"๋ "์ค์ " ํจ๋์ ์ด์๋ค ๋ซ์๋ ๋ฉ๋ด๊ฐ ๊ณ์ ์กฐ์ ๊ฐ๋ฅํด์ผ ํ๋ค.
RemoveActivePanelImmediately()๊ฐ ํจ๋์ ๋ซ์ ๋ค FInputModeGameOnly + ์ปค์ ์จ๊น์ ์ธ์
์ํ์ ๋ฌด๊ดํ๊ฒ ๊ฐ์ ํ๋ค. ์ธ๊ฒ์์์ ์ธ๋ฒคํ ๋ฆฌ๋ฅผ ๋ซ์ ๋๋ ์ฌ๋ฐ๋ฅธ ๋์์ด์ง๋ง, ๋ฉ์ธ๋ฉ๋ด(UIOnly + ์ปค์)์์ ๋ถ๋ฌ์ค๊ธฐ/์ค์ ์ ๋ซ์ผ๋ฉด ์ปค์์ UI ์
๋ ฅ์ด ์ฃฝ์ด ๋ฉ๋ด ์ ์ฒด๊ฐ ํด๋ฆญ ๋ถ๊ฐ ์ํ๊ฐ ๋๋ค โ ์ด ๊ณตํต ๊ฒฝ๋ก๋ฅผ ์ฐ๋ ํจ๋์ด ๋ฉ์ธ๋ฉ๋ด์์๋ ์ด๋ฆฌ๊ธฐ ์์ํ๋ฉด์ ์ ๋ณตํด ์๋ ์ ์ ๊ฐ ๊นจ์ง ๊ฒ.
if (SessionState == MainMenu || SessionState == Result)
{
UpdateInputMode(SessionState); // UIOnly + ์ปค์ ์ ์ง
}
else
{
SetInputMode(FInputModeGameOnly()); // ์ธ๊ฒ์๋ง ๊ธฐ์กด๋๋ก
bShowMouseCursor = false;
}
"๋ซ์ ๋ค ์ํ"๋ ์์๊ฐ ์๋๋ผ ๋ฌธ๋งฅ์ด๋ค. ํจ๋ ๋ซ๊ธฐ ๊ฐ์ ๊ณตํต ๊ฒฝ๋ก์ ํ๋์ฝ๋ฉ๋ ๋ณต์ ๊ฐ(GameOnly)์ ๊ทธ ๊ฒฝ๋ก๊ฐ ์ฒ์ ์ฐ์ด๋ ๋ฌธ๋งฅ(์ธ๊ฒ์)์ ์ ์ ์ผ ๋ฟ์ด๋ค โ ๊ฐ์ ํจ๋ ์์คํ ์ ์ ๋ฌธ๋งฅ(๋ฉ์ธ๋ฉ๋ด)์์ ์ฌ์ฌ์ฉํ๋ ์๊ฐ, ๋ณต์ ๋ก์ง์ "์๋ ์ํ๋ก"๊ฐ ์๋๋ผ "์ง๊ธ ์์ด์ผ ํ ์ํ๋ก"๋ฅผ ๋ฌผ์ด์ผ ํ๋ค. ์ธ์ ์ํ๋จธ์ ์ด ์ด๋ฏธ ์์ผ๋ ๊ทธ๊ฑธ ๋จ์ผ ์ง์ค๋ก ์ฐ๋ฉด ๋์ด์๋ค.
์ผ์์ ์ง ๋ฉ๋ด์ "์กฐ์ํค ์๋ด" ๋ฒํผ์ผ๋ก ํค๋ณด๋/๋ง์ฐ์ค ์กฐ์๋ฒ ํ๋ฉด(WBP_ControlsGuide)์ ์ด๊ณ , ESC๋ก ์์ฐ์ค๋ฝ๊ฒ ๋ซํ๊ฒ ํ๋ค.
RetrieveGamePanelWidget)๋ก, ํ์น๋จผํธ ๋ฐ์ค ํ
์ค์ฒ + ๋ง์ฐ์ค ์ข/์ค/์ฐ ์
๋ ฅ ์์ด์ฝ + ํค ํ(KeyRows) ๊ตฌ์ฑ. ํ์ ์ ์ฉ์ด๋ผ C++ ๋ฒ ์ด์ค๋ฅผ ์๋ก ๋ง๋ค ์ด์ ๊ฐ ์์๋ค.OpenControlsGuide() ํ๋ โ OpenExclusivePanel(PanelClass, EKeys::Escape)์ ๊ทธ๋๋ก ์ฌ์ฌ์ฉํ๋ค. ๋ฐฐํ ํจ๋ ๋ชจ๋ธ์ด๋ผ ์ผ์์ ์ง ํจ๋์ด ์๋์ผ๋ก ์กฐ์ํค ์๋ด๋ก "๊ต์ฒด"๋๊ณ , ESC(ToggleKey)๋ก ๋ซํ๋ค. ์คํ/๋ค๋น๊ฒ์ด์
์ฝ๋๋ฅผ ์๋ก ๋ง๋ค์ง ์์๋ค.URetrievePauseMenuWidget)๊ฐ CommandsButton์ BindWidgetOptional๋ก ์ง์ด PC->OpenControlsGuide()์ ๋ฐฐ์ ํ๋ค โ WBP๋ ์ ํด์ง ์ด๋ฆ์ ๋ฒํผ๋ง ๋ฐฐ์นํ๋ฉด ๋๊ณ ๊ทธ๋ํ ๋ฐฐ์ ์ด ํ์ ์๋ค.TSoftClassPtr + ์์ฑ์ ๊ธฐ๋ณธ ๊ฒฝ๋ก๋ก ๋๋, BP ์ค๋ฒ๋ผ์ด๋๊ฐ None์ผ๋ก ๋จ๋ ์ฌ๊ณ ์ ๋๋นํด LoadClass ํด๋ฐฑ์ ๋ฃ์๋ค(7๋ฒ ํญ๋ชฉ๊ณผ ์ธํธ)."ํ๋ฉด ํ๋ ์ถ๊ฐ"๊ฐ ์๊ตฌํ๋ ์ฝ๋๋ ํ๋ฉด ์์ ๋น๋กํ์ง ์์์ผ ํ๋ค. ๋ฐฐํ ํจ๋(OpenExclusivePanel) + ESC ToggleKey + BindWidgetOptional ๋ฒํผ ๋ฐฐ์ ์ด๋ผ๋ ๊ธฐ์กด ๊ท์ฝ์ ์น์ผ๋, ์ ํ๋ฉด์ ๋น์ฉ์ด "WBP 1๊ฐ + Open ํจ์ 1๊ฐ"๋ก ๋๋ฌ๋ค. ๋ฐ๋๋ก ๋งํ๋ฉด, ํจ๋ ์ธํ๋ผ๋ฅผ ์ฒ์ ๋ง๋ค ๋ ๊ต์ฒด/๋ซ๊ธฐ/์ ๋ ฅ ๊ท์ฝ์ ์ผ๋ฐํํด๋ ๊ฒ์ด ์ฌ๊ธฐ์ ํ์๋๋ค.
ํ์ ์ ์ฉ ์์ ฏ์ C++ ๋ฒ ์ด์ค๋ฅผ ๋ง๋ค์ง ์๋ ๊ฒ๋ ์ค๊ณ ๊ฒฐ์ ์ด๋ค. ๋ฐ์ธ๋ฉํ ์ํ๊ฐ ์๋ ์ ์ ์๋ด ํ๋ฉด์ WBP๋ง์ผ๋ก ์ถฉ๋ถํ๊ณ , C++ ํด๋์ค๋ฅผ ๋๋ฆฌ์ง ์์ผ๋ฉด ๋ฆฌ์ปดํ์ผ ์์ด ๋์์ด๋๊ฐ ๋ด์ฉ์ ๊ณ์ ๋ค๋ฌ์ ์ ์๋ค.
์๋ํฐ์์ ์ ์ด๋ฆฌ๋ ์ค์ ์ฐฝยท์ผ์์ ์ง ๋ฉ๋ดยท์กฐ์ํค ์๋ด๊ฐ Shipping ํจํค์ง์์ "๋ฒํผ์ ๋๋ฌ๋ ์กฐ์ฉํ ์๋ฌด ์ผ๋ ์ ์ผ์ด๋๋" ๋ฌธ์ ๋ฅผ ๋ง๋๋ค.
์ด UI๋ค์ ์ ๋ถ TSoftClassPtr(๋๋ ๊ฒฝ๋ก ๋ฌธ์์ด LoadClass)๋ก๋ง ์ฐธ์กฐ๋๋ค โ ํ๋ ๋ ํผ๋ฐ์ค ์ฒด์ธ์ด ์์ผ๋ ์ฟ ์ปค๊ฐ ํด๋น ํด๋์ ๋๋ฌํ์ง ๋ชปํ๊ณ , ํจํค์ง์์ LoadSynchronous()๊ฐ null์ ๋ฐํํ๋ค. ์๋ฌ ํ์
๋ ์์ด ํจ์๊ฐ ์กฐ๊ธฐ returnํ๋ฏ๋ก ์ฆ์์ด "๋ฌด๋ฐ์"๋ฟ์ด๋ผ๋ ๊ฒ ์
์ง์ด๋ค. ์ด๋ฏธ ์กฐ์ค์ ํ
์ค์ฒ, ์์ดํ
ํ๋ ํ ์คํธ์์ ๋ ๋ฒ ๊ฒช์ ๊ฒ๊ณผ ๋์ผ ํจํด์ ์ธ ๋ฒ์งธ ์ฌ๋ฐ์ด์๋ค.
; DefaultGame.ini โ ์ํํธ ์ฐธ์กฐ๋ง ์๋ UI ํด๋๋ฅผ ๋ช
์์ ์ผ๋ก ์ฟ ํน์ ํฌํจ
+DirectoriesToAlwaysCook=(Path="/Game/Retrieve/UI/Interaction")
+DirectoriesToAlwaysCook=(Path="/Game/Retrieve/UI/Settings")
+DirectoriesToAlwaysCook=(Path="/Game/Retrieve/UI/Menu")
์ฝ๋ ์ชฝ์๋ PauseMenuClass/ControlsGuideClass๊ฐ ๋น์ด ์์ผ๋ฉด(BP์ None ์ค๋ฒ๋ผ์ด๋๊ฐ ๋จ์ ๊ฒฝ์ฐ ๋ฑ) ์๋ ค์ง ๊ฒฝ๋ก๋ก LoadClass ํด๋ฐฑ์ ํ์, "ํ๋กํผํฐ ์ค์ ์ค์"์ "์ฟ ํน ๋๋ฝ"์ ๊ฐ๊ฐ ๋ค๋ฅธ ์ธต์์ ๋ฐฉ์ดํ๋ค.
TSoftClassPtr๋ก UI๋ฅผ ์ฐธ์กฐํ๋ ์๊ฐ, always-cook ๋ฑ๋ก๊น์ง๊ฐ ํ ์ธํธ๋ค. ๊ฐ์ ์์ธ์ผ๋ก ์ธ ๋ฒ์งธ ๋นํ๋ค โ ์ด์ ๊ท์นํํ๋ค: ์ํํธ ์ฐธ์กฐ/๊ฒฝ๋ก ๋ฌธ์์ด ๋ก๋๋ฅผ ์ถ๊ฐํ๋ ์ปค๋ฐ์๋ ๋ฐ๋์DirectoriesToAlwaysCookํ์ธ์ด ๋ฐ๋ผ๋ถ์ด์ผ ํ๊ณ , ์ฆ์์ ํญ์ "ํจํค์ง์์๋ง ์กฐ์ฉํ ๋ฌด๋ฐ์"์ผ๋ก ๋ํ๋๋ค๋ ๊ฑธ ๊ธฐ์ตํ ๊ฒ.
์ผ์์ ์ง ๋ฉ๋ด์ "๋ฉ์ธ ๋ฉ๋ด๋ก" ๋ฒํผ์ด ์๋ฌด ๋ฐ์์ด ์๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค. WBP ๋ฒํผ ๋ฐฐ์ ๋ฌธ์ ๋ก ๋ณด์์ง๋ง ์ค์ ์์ธ์ ์ ํ ๋ค๋ฅธ ๊ณณ์ ์์๋ค.
๋ฐฐ์ ์ ์์ฌํ๊ณ ์ถ์ ํ์ง๋ง ํ๋ฆ์ ์๋ฒฝํ๋ค: MainMenuButton ํด๋ฆญ โ HandleMainMenuClicked โ Server_RequestQuitToMenu โ GameMode::HandleQuitToMenu โ GameState::TransitionTo(MainMenu). ๋ฌธ์ ๋ ๋ง์ง๋ง ํ ์ค โ IsLegalTransition()์ด ์ ํ ํ์ดํธ๋ฆฌ์คํธ ๋ฐฉ์์ธ๋ฐ, InGame์์ ํ์ฉ๋ ๋ชฉ์ ์ง๊ฐ Result๋ฟ์ด์๋ค. "๋ฉ์ธ ๋ฉ๋ด๋ก ๋๊ฐ๊ธฐ"๋ ์ฌ๋ง ํ๋ฉด(Result โ MainMenu)๋ง ์์ ํ๊ณ ์ค๊ณ๋๊ณ , ์ผ์์ ์ง ๋ฉ๋ด๋ ๊ฒ์์ ์ค์ ๋ก ํฌ์ฆํ์ง ์์ ์ธ์
์ํ๊ฐ InGame์ธ ์ฑ๋ก ์์ฒญ๋๋ฏ๋ก ๋ก๊ทธ ํ ์ค ์์ด return false๋ก ๋ฌด์๋๋ค.
case ERetrieveSessionState::InGame:
// MainMenu ํ์ฉ: ์ผ์์ ์ง ๋ฉ๋ด์ "๋ฉ์ธ ๋ฉ๋ด๋ก"(Server_RequestQuitToMenu)๊ฐ InGame ์ํ์์ ํธ์ถ๋๋ค.
return To == ERetrieveSessionState::Result || To == ERetrieveSessionState::MainMenu;
์ ํ๋ง ํ์ฉ๋๋ฉด ๊ธฐ์กด HandleSessionStateChanged ๊ฒฝ๋ก๊ฐ ํจ๋ ์ ๋ฆฌ โ ์์ ฏ ์ค์ โ ์
๋ ฅ๋ชจ๋ โ ๋ฉ๋ด ์นด๋ฉ๋ผ๊น์ง ์์์ ์ฒ๋ฆฌํ๋ฏ๋ก ์์ ์ ์ด ํ ์ค์ด ์ ๋ถ์๋ค.
ํ์ดํธ๋ฆฌ์คํธํ ์ํ๋จธ์ ์ "๊ฑฐ๋ถ"๋ฅผ ๋ก๊ทธ๋ก ๋จ๊ฒจ์ผ ํ๋ค.
TransitionTo๊ฐ ๋ถ๋ฒ ์ ํ์ ์กฐ์ฉํfalse๋ก ์ผํค๋ ๋ฐ๋์, ์ฆ์(๋ฒํผ ๋ฌด๋ฐ์)์์ ์์ธ(์ํ๋จธ์ ๊ฑฐ๋ถ)๊น์ง ๊ฑฐ๋ฆฌ๊ฐ ๋๋ฌด ๋ฉ์๋ค โ UI ๋ฐฐ์ ๋ถํฐ RPC๊น์ง ์ ๊ตฌ๊ฐ์ ๊ฑฐ์ฌ๋ฌ ์ฌ๋ผ๊ฐ์ผ ํ๋ค. ๊ฑฐ๋ถ ์UE_LOG(Warning, "Illegal transition %s -> %s")ํ ์ค์ด ์์๋ค๋ฉด ๋ก๊ทธ ํ ๋ฒ์ ๋๋ฌ์ ๋ฌธ์ ๋ค.
์ UI ํ๋ฆ์ ์ถ๊ฐํ ๋๋ "๊ทธ ํ๋ฆ์ด ๋ฐ๋ ์ํ ์ ํ"์ด ํ์ดํธ๋ฆฌ์คํธ์ ์๋์ง ๋จผ์ ํ์ธํ๋ค. ์ผ์์ ์ง ๋ฉ๋ด๋ผ๋ ์ ์ง์ ์ ์ด ๊ธฐ์กด์ ์๋ ์ ํ(InGame โ MainMenu)์ ์๊ตฌํ๊ฒ ๋๋๋ฐ, ๋ฒํผยทRPCยทํธ๋ค๋ฌ๋ ๋ค ๋ง๋ค๋ฉด์ ์ํ๋จธ์ ๊ท์น ๊ฐฑ์ ๋ง ๋น ์ก๋ค โ ์ํ๋จธ์ ์ด ์๋ ํ๋ก์ ํธ์์ ๊ธฐ๋ฅ ์ถ๊ฐ ์ฒดํฌ๋ฆฌ์คํธ์ "์ ํ ๊ท์น ๊ฐฑ์ "์ ํฌํจํด์ผ ํ๋ค.
| ์์ | ํต์ฌ ๋ฌธ์ | ํด๊ฒฐ ์์น |
|---|---|---|
| ์ด์ดํ๊ธฐ | "๊ฐ์ฅ ์ต๊ทผ ์ฌ๋กฏ" ํ์ | ์ ๋ ฌ ๊ฐ๋ฅํ ํ์์คํฌํ ํฌ๋งท โ ๋ฌธ์์ด ๋น๊ต, ๋ก๋๋ ์๋ฒ ๊ถ์ ๊ฒฝ๋ก๋ก ํต์ผ |
| ๋ถ๋ฌ์ค๊ธฐ ํจ๋ | ๊ณต์ ์ฌ๋กฏ ์์ ฏ์ ์๋ฌต์ ๊ณ์ฝ 3๊ฐ(OwnerMenu ํ์ ยทSlotIndex ํธ์ง๋ถ๊ฐยท์๋ ์์ ฏ) | ์ ๋ถ ํธ์คํธ C++์์ ํก์(์ง์ ๋ฐ์ธ๋ฉยทChildIndexยท๋์ ์ฃผ์ ), ๊ณต์ WBP ๋ฌด์์ |
| ํ์คํธ ์ ์ฅ/๋ณต์ | ๋ก๋ ์ ์๋ฃ ์๋ฆผ ์ฐ์ ์ฌ์ | ๋ณต์ ์ ์ฉ API + ์๋ฆผ ๋ฒ ์ด์ค๋ผ์ธ ์ฌ์๋ฉ + ๊ฐฑ์ ์ ํธ 1ํ |
| ์ถ์ ํ์คํธ ํ์ | HUD ๋ก์ปฌ ์ํ๋ ์ธ์ด๋ธ์ ์์ | ์ ์ฅ ์์ ์ ๋์ผ ์ ์ ๋ก์ง์ผ๋ก ์ฌ๊ณ์ฐํด ํ์ ๋ฌธ์์ด๋ก ๋ฐ์ |
| ๋ฉ๋ด์์ ํจ๋ ๋ซ๊ธฐ | ๋ฌด์กฐ๊ฑด GameOnly ๋ณต์ โ ๋ฉ๋ด ์ปค์ ์ฌ๋ง | ๋ซ์ ๋ค ์ ๋ ฅ ๋ชจ๋๋ฅผ ์ธ์ ์ํ๋ก ๊ฒฐ์ |
| ์กฐ์ํค ์๋ด | ์ ํ๋ฉด ์ถ๊ฐ ๋น์ฉ | ๋ฐฐํ ํจ๋ ์ธํ๋ผ ์ฌ์ฌ์ฉ โ WBP 1๊ฐ + Open ํจ์ 1๊ฐ๋ก ์ข ๊ฒฐ |
| ํจํค์ง ๋ฌด๋ฐ์ | ์ํํธ ์ฐธ์กฐ๋ง ์๋ UI๊ฐ ์ฟ ํน ๋๋ฝ | always-cook ๋ฑ๋ก + LoadClass ํด๋ฐฑ ์ด์ค ๋ฐฉ์ด (๋์ผ ์์ธ 3๋ฒ์งธ ์ฌ๋ฐ โ ๊ท์นํ) |
| ๋ฉ์ธ ๋ฉ๋ด๋ก ๋ฒํผ | ์ํ๋จธ์ ์ด InGameโMainMenu๋ฅผ ์กฐ์ฉํ ๊ฑฐ๋ถ | ํ์ดํธ๋ฆฌ์คํธ ํ ์ค ์ถ๊ฐ, "๊ฑฐ๋ถ๋ ๋ก๊ทธ๋ฅผ ๋จ๊ฒจ์ผ ํ๋ค"๋ ๊ตํ |
๊ณตํต ๊ตํ: ์ค๋ ํ๋ฃจ๋ "์ด๋ฏธ ์๋ ์์คํ ์ ์ ์ง์ ์ ์ ์น์ ๋ ๊นจ์ง๋ ์ ์ ๋ค"์ ํ๋ฃจ์๋ค.
- ๊ณตํต ๊ฒฝ๋ก์ ํ๋์ฝ๋ฉ์ ์ฒซ ์ฌ์ฉ์ฒ์ ์ ์ ๋ค. ํจ๋ ๋ซ๊ธฐ์ GameOnly ๋ณต์(์ธ๊ฒ์ ์ ์ ), ์ํ๋จธ์ ์ ์ ํ ๋ชฉ๋ก(์ฌ๋ง ํ๋ฉด ์ ์ ), ์ฌ๋กฏ ์ํธ๋ฆฌ์ OwnerMenu ํ์ (๋ชจ๋ฅ๋ถ ์ ์ ) โ ์ ๋ถ ์ฒ์ ๋ง๋ค ๋ ์ณ์์ง๋ง, ๋ฉ์ธ๋ฉ๋ด/์ผ์์ ์ง๋ผ๋ ์ ๋ฌธ๋งฅ์ด ์๊ธฐ์ ์กฐ์ฉํ ๊นจ์ก๋ค. ์ฌ์ฌ์ฉ ์ ์ "์ด ๊ฐ/๊ท์น์ ๋ฌด์์ ์ ์ ๋ก ํ๋๊ฐ"๋ฅผ ๋ฌผ์ด์ผ ํ๋ค.
- ์กฐ์ฉํ ์คํจ๊ฐ ๋๋ฒ๊น ๋น์ฉ์ ๋๋ถ๋ถ์ด๋ค. ์ํ๋จธ์ ์ ๋ฌด์ธ ๊ฑฐ๋ถ, ํจํค์ง์์์ LoadSynchronous null, ๊ธธ์ด 0 ๋ชฝํ์ฃผ โ ์ค๋๋ "์๋ฌ ์์ด ์๋ฌด ์ผ๋ ์ ์ผ์ด๋๋" ์ฆ์์ด ๊ฐ์ฅ ์ค๋ ๊ฑธ๋ ธ๋ค. ๊ฑฐ๋ถ/์คํจ ์ง์ ์ ๋ก๊ทธ ํ ์ค ๋ฃ๋ ๊ฒ์ด ์ต๊ณ ์ ํฌ์๋ค.
- ์ํ๋ฅผ ๋ณต์ํ๋ ์ฝ๋์ ์ํ๋ฅผ ์ ์ด์ํค๋ ์ฝ๋๋ ๋ค๋ฅธ API์ฌ์ผ ํ๋ค. ํ์คํธ ๋ณต์์ CompleteStep์ ํ์ฐ์ง ์๊ณ ์ ์ฉ API๋ก ๋ถ๋ฆฌํ ๊ฒ์ฒ๋ผ, "์ ์ด"์ ๋ฌถ์ธ ๋ถ์ํจ๊ณผ(์๋ฆผยท๊ฒ์ฆ)๋ฅผ "๋ณต์"์ด ๋ฌผ๋ ค๋ฐ์ผ๋ฉด ์ ๋๋ค โ ๋์ ๋ณต์์ด ์๋ตํ ์ฑ ์(๋ฒ ์ด์ค๋ผ์ธ, UI ๊ฐฑ์ )์ ํธ์ถ๋ถ ๊ณ์ฝ์ผ๋ก ๋ช ์ํ๋ค.