using Cysharp.Threading.Tasks; using UVC.Locale; namespace UVC.UI.Modal { /// /// ๐Ÿ“œ ๋ชจ๋‹ฌ ์ฐฝ์— ์–ด๋–ค ๋‚ด์šฉ์„ ๋ณด์—ฌ์ค„์ง€, ์–ด๋–ป๊ฒŒ ํ–‰๋™ํ• ์ง€ ์ •ํ•˜๋Š” '๋ ˆ์‹œํ”ผ' ๋˜๋Š” '์ฃผ๋ฌธ์„œ' ๊ฐ™์€ ์นœ๊ตฌ์˜ˆ์š”. /// ์ด ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์„œ Modal.Open()์— ์ „๋‹ฌํ•˜๋ฉด, ์—ฌ๊ธฐ์— ์ ํžŒ ๋Œ€๋กœ ๋ชจ๋‹ฌ ์ฐฝ์ด ๋งŒ๋“ค์–ด์ ธ์š”. /// ์ปค์Šคํ…€ ๋ชจ๋‹ฌ ์ฐฝ์„ ๋งŒ๋“ค ๋•Œ๋Š” ModalView๋ฅผ ์ƒ์†๋ฐ›์•„์„œ Prefab์œผ๋กœ ๋งŒ๋“ค๊ณ  ModalContent ์ƒ์„ฑ์ž์— Prefab ๊ฒฝ๋กœ๋ฅผ ์ „๋‹ฌํ•ด์•ผ ํ•œ๋‹ค. /// /// /// /// // "MyAwesomeModalPrefab"์ด๋ผ๋Š” ๋””์ž์ธ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋‹ฌ์„ ์œ„ํ•œ ๋ ˆ์‹œํ”ผ๋ฅผ ๋งŒ๋“ค์–ด์š”. /// var myRecipe = new ModalContent("Prefabs/UI/MyAwesomeModalPrefab") /// { /// Title = "์ƒˆ๋กœ์šด ๋ชจํ—˜!", // ๋ชจ๋‹ฌ ์ฐฝ ์ œ๋ชฉ /// Message = "๋ชจํ—˜์„ ์‹œ์ž‘ํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‚˜์š”?", // ๋ชจ๋‹ฌ ์ฐฝ ๋ฉ”์‹œ์ง€ /// ConfirmButtonText = "๋„ค, ๊ฐ‘์‹œ๋‹ค!", // ํ™•์ธ ๋ฒ„ํŠผ ๊ธ€์ž /// ShowCancelButton = false // ์ทจ์†Œ ๋ฒ„ํŠผ์€ ์•ˆ ๋ณด์—ฌ์ค„๋ž˜์š”. /// }; /// /// // ์ด๋ ‡๊ฒŒ ๋งŒ๋“  ๋ ˆ์‹œํ”ผ(myRecipe)๋ฅผ Modal.Open()์— ์ „๋‹ฌํ•˜๋ฉด ๋ชจ๋‹ฌ์ด ๋ฟ… ๋‚˜ํƒ€๋‚˜์š”! /// // bool userChoseConfirm = await Modal.Open(myRecipe); /// /// public class ModalContent { /// /// ๐Ÿท๏ธ ๋ชจ๋‹ฌ ์ฐฝ์˜ ์ œ๋ชฉ์ด์—์š”. ์—ฌ๊ธฐ์— ๊ธ€์ž๋ฅผ ์ ์œผ๋ฉด ๋ชจ๋‹ฌ ์ฐฝ ๋งจ ์œ„์— ํฌ๊ฒŒ ๋ณด์—ฌ์š”. /// ์˜ˆ: "์•Œ๋ฆผ", "๊ฒŒ์ž„ ์ €์žฅ", "์นœ๊ตฌ ์š”์ฒญ" /// public string Title { get; set; } = ""; /// /// ๐Ÿ’ฌ ๋ชจ๋‹ฌ ์ฐฝ์— ๋ณด์—ฌ์ค„ ์ฃผ์š” ๋ฉ”์‹œ์ง€ ๋‚ด์šฉ์ด์—์š”. ์‚ฌ์šฉ์ž์—๊ฒŒ ์ „๋‹ฌํ•˜๊ณ  ์‹ถ์€ ๋ง์„ ์—ฌ๊ธฐ์— ์ ์–ด์š”. /// ์˜ˆ: "๊ฒŒ์ž„ ์„ค์ •์„ ์ €์žฅํ–ˆ์Šต๋‹ˆ๋‹ค.", "์ •๋ง๋กœ ์•„์ดํ…œ์„ ๊ตฌ๋งคํ•˜์‹œ๊ฒ ์–ด์š”?" /// public string Message { get; set; } = ""; private string _confirmButtonText = "ํ™•์ธ"; /// /// โœ… 'ํ™•์ธ' ๋ฒ„ํŠผ์— ๋ณด์—ฌ์ค„ ๊ธ€์ž์˜ˆ์š”. /// ํŠน๋ณ„ํžˆ ์ •ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ "ํ™•์ธ" (๋˜๋Š” ์„ค์ •๋œ ์–ธ์–ด์— ๋งž๊ฒŒ)์ด๋ผ๊ณ  ๋‚˜์™€์š”. /// ์ง์ ‘ "๋„ค", "์ €์žฅํ•˜๊ธฐ", "์ถœ๋ฐœ!" ์ฒ˜๋Ÿผ ์›ํ•˜๋Š” ๊ธ€์ž๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์–ด์š”. /// ๋‹ค๊ตญ์–ด ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ์–ด์š”. (์˜ˆ: "ui_button_confirm", "action_ok") /// public string ConfirmButtonText { get { // _confirmButtonText๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •๋˜์ง€ ์•Š์•˜๊ณ , LocalizationManager ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ๋ฒˆ์—ญ๋œ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ if (string.IsNullOrEmpty(_confirmButtonText) && LocalizationManager.Instance != null) { return LocalizationManager.Instance.GetString(_confirmButtonText); } // ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •๋œ ๊ฐ’์ด ์žˆ๊ฑฐ๋‚˜ LocalizationManager๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋ฉด ํ•ด๋‹น ๊ฐ’ ๋˜๋Š” ๊ธฐ๋ณธ ํ‚ค ๋ฐ˜ํ™˜ return _confirmButtonText; } set => _confirmButtonText = value; } private string _cancelButtonText = "์ทจ์†Œ"; /// /// โŒ '์ทจ์†Œ' ๋ฒ„ํŠผ์— ๋ณด์—ฌ์ค„ ๊ธ€์ž์˜ˆ์š”. /// ํŠน๋ณ„ํžˆ ์ •ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ "์ทจ์†Œ" (๋˜๋Š” ์„ค์ •๋œ ์–ธ์–ด์— ๋งž๊ฒŒ)์ด๋ผ๊ณ  ๋‚˜์™€์š”. /// ์ง์ ‘ "์•„๋‹ˆ์š”", "๋‹ซ๊ธฐ", "๋‚˜์ค‘์—" ์ฒ˜๋Ÿผ ์›ํ•˜๋Š” ๊ธ€์ž๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์–ด์š”. /// ๋‹ค๊ตญ์–ด ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ์–ด์š”. (์˜ˆ: "ui_button_cancel", "action_no") /// public string CancelButtonText { get { // _cancelButtonText๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •๋˜์ง€ ์•Š์•˜๊ณ , LocalizationManager ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ๋ฒˆ์—ญ๋œ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ if (string.IsNullOrEmpty(_cancelButtonText) && LocalizationManager.Instance != null) { return LocalizationManager.Instance.GetString(_cancelButtonText); } // ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •๋œ ๊ฐ’์ด ์žˆ๊ฑฐ๋‚˜ LocalizationManager๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋ฉด ํ•ด๋‹น ๊ฐ’ ๋˜๋Š” ๊ธฐ๋ณธ ํ‚ค ๋ฐ˜ํ™˜ return _cancelButtonText; } set => _cancelButtonText = value; } /// /// ๐Ÿ‘ 'ํ™•์ธ' ๋ฒ„ํŠผ์„ ํ™”๋ฉด์— ๋ณด์—ฌ์ค„์ง€ ๋ง์ง€ ๊ฒฐ์ •ํ•ด์š”. (๊ธฐ๋ณธ๊ฐ’: true, ๋ณด์—ฌ์คŒ) /// false๋กœ ๋ฐ”๊พธ๋ฉด 'ํ™•์ธ' ๋ฒ„ํŠผ์ด ์‚ฌ๋ผ์ ธ์š”. /// public bool ShowConfirmButton { get; set; } = true; /// /// ๐Ÿ‘Ž '์ทจ์†Œ' ๋ฒ„ํŠผ์„ ํ™”๋ฉด์— ๋ณด์—ฌ์ค„์ง€ ๋ง์ง€ ๊ฒฐ์ •ํ•ด์š”. (๊ธฐ๋ณธ๊ฐ’: true, ๋ณด์—ฌ์คŒ) /// false๋กœ ๋ฐ”๊พธ๋ฉด '์ทจ์†Œ' ๋ฒ„ํŠผ์ด ์‚ฌ๋ผ์ ธ์š”. /// public bool ShowCancelButton { get; set; } = true; /// /// ๐Ÿ‘Ž '๋‹ซ๊ธฐ' ๋ฒ„ํŠผ์„ ํ™”๋ฉด์— ๋ณด์—ฌ์ค„์ง€ ๋ง์ง€ ๊ฒฐ์ •ํ•ด์š”. (๊ธฐ๋ณธ๊ฐ’: true, ๋ณด์—ฌ์คŒ) /// false๋กœ ๋ฐ”๊พธ๋ฉด '๋‹ซ๊ธฐ' ๋ฒ„ํŠผ์ด ์‚ฌ๋ผ์ ธ์š”. /// public bool ShowCloseButton { get; set; } = true; /// /// ๐ŸŽจ ๋ชจ๋‹ฌ ์ฐฝ์˜ '๋””์ž์ธ ๋„๋ฉด' ํŒŒ์ผ์ด ์–ด๋”” ์žˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ๋Š” ๊ฒฝ๋กœ์˜ˆ์š”. /// Unity ์—๋””ํ„ฐ์—์„œ ๋งŒ๋“ค์–ด๋‘” ํ”„๋ฆฌํŒน(Prefab) ํŒŒ์ผ์˜ ๊ฒฝ๋กœ๋ฅผ ์ ์–ด์ค˜์•ผ ํ•ด์š”. /// ์˜ˆ: "Prefabs/UI/MyCustomModal" /// public string PrefabPath { get; private set; } /// /// ๐Ÿง‘โ€๐Ÿณ ModalContent ๋ ˆ์‹œํ”ผ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์ด์—์š”. (์ƒ์„ฑ์ž) /// ๋ชจ๋‹ฌ ์ฐฝ์„ ์–ด๋–ค ๋””์ž์ธ์œผ๋กœ ๋งŒ๋“ค์ง€ ์•Œ๋ ค์ค˜์•ผ ํ•ด์š”. /// /// ์‚ฌ์šฉํ•  ๋ชจ๋‹ฌ ์ฐฝ ๋””์ž์ธ(ํ”„๋ฆฌํŒน) ํŒŒ์ผ์˜ ๊ฒฝ๋กœ์˜ˆ์š”. /// /// /// // "CommonModalPrefab" ๋””์ž์ธ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ ˆ์‹œํ”ผ ๋งŒ๋“ค๊ธฐ /// var content = new ModalContent("Prefabs/UI/CommonModalPrefab"); /// content.Title = "์•ˆ๋‚ด"; /// content.Message = "์ด๊ฒƒ์€ ์ผ๋ฐ˜์ ์ธ ์•ˆ๋‚ด ๋ชจ๋‹ฌ์ž…๋‹ˆ๋‹ค."; /// /// public ModalContent(string prefabPath) { PrefabPath = prefabPath; // Title, Message ๋“ฑ ๋‹ค๋ฅธ ํ…์ŠคํŠธ ์†์„ฑ๋„ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์—ฌ๊ธฐ์„œ ๊ธฐ๋ณธ ๋‹ค๊ตญ์–ด ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ดˆ๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. // ์˜ˆ: Title = LocalizationManager.Instance.GetString("default_modal_title"); } /// /// ๐Ÿš€ ๋ชจ๋‹ฌ ์ฐฝ์ด ํ™”๋ฉด์— ๋‚˜ํƒ€๋‚˜๊ธฐ *์ง์ „*์— ์ด ๋ ˆ์‹œํ”ผ๊ฐ€ ํ•  ์ผ์„ ์ •ํ•ด์š”. (๋น„๋™๊ธฐ ์ž‘์—… ๊ฐ€๋Šฅ) /// ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ชจ๋‹ฌ์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ๋ถˆ๋Ÿฌ์˜ค๊ฑฐ๋‚˜ ํŠน๋ณ„ํ•œ ์ค€๋น„๋ฅผ ํ•  ์ˆ˜ ์žˆ์–ด์š”. /// `ModalView.OnOpen()` ๋ณด๋‹ค ๋จผ์ € ํ˜ธ์ถœ๋ผ์š”. /// /// /// ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ์†๋ฐ›์•„์„œ ํŠน๋ณ„ํ•œ ์ค€๋น„ ์ž‘์—…์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์–ด์š”: /// /// public class MySpecialModalContent : ModalContent /// { /// public MySpecialModalContent(string prefabPath) : base(prefabPath) { } /// /// public override async UniTask OnOpen() /// { /// await base.OnOpen(); // ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ OnOpen๋„ ํ˜ธ์ถœํ•ด์ฃผ๋Š” ๊ฒŒ ์ข‹์•„์š”. /// ULog.Debug("๋‚˜๋งŒ์˜ ํŠน๋ณ„ํ•œ ๋ชจ๋‹ฌ ๋‚ด์šฉ ์ค€๋น„ ์‹œ์ž‘!"); /// // ์˜ˆ: await LoadSomeDataForTheModal(); /// ULog.Debug("๋‚˜๋งŒ์˜ ํŠน๋ณ„ํ•œ ๋ชจ๋‹ฌ ๋‚ด์šฉ ์ค€๋น„ ์™„๋ฃŒ!"); /// } /// } /// /// public virtual async UniTask OnOpen() { // ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š์•„์š”. ํ•„์š”ํ•˜๋ฉด ์ƒ์†๋ฐ›์•„์„œ ๋‚ด์šฉ์„ ์ฑ„์›Œ์ฃผ์„ธ์š”! //ULog.Debug($"[ModalContent] '{Title}' OnOpen called."); await UniTask.CompletedTask; } /// /// ๐ŸŽฌ ๋ชจ๋‹ฌ ์ฐฝ์ด ํ™”๋ฉด์—์„œ ์‚ฌ๋ผ์ง€๊ธฐ *์ง์ „*์— ์ด ๋ ˆ์‹œํ”ผ๊ฐ€ ํ•  ์ผ์„ ์ •ํ•ด์š”. (๋น„๋™๊ธฐ ์ž‘์—… ๊ฐ€๋Šฅ) /// ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ชจ๋‹ฌ์—์„œ ์‚ฌ์šฉํ–ˆ๋˜ ์ž์›์„ ์ •๋ฆฌํ•˜๊ฑฐ๋‚˜ ํŠน๋ณ„ํ•œ ๋งˆ๋ฌด๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ์–ด์š”. /// `ModalView.OnClose()` ๋ณด๋‹ค ๋จผ์ € ํ˜ธ์ถœ๋ผ์š”. /// /// /// ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ์†๋ฐ›์•„์„œ ํŠน๋ณ„ํ•œ ๋งˆ๋ฌด๋ฆฌ ์ž‘์—…์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์–ด์š”: /// /// public class MySpecialModalContent : ModalContent /// { /// public MySpecialModalContent(string prefabPath) : base(prefabPath) { } /// /// // ... OnOpen ์žฌ์ •์˜ ... /// /// public override async UniTask OnClose() /// { /// ULog.Debug("๋‚˜๋งŒ์˜ ํŠน๋ณ„ํ•œ ๋ชจ๋‹ฌ ๋‚ด์šฉ ๋งˆ๋ฌด๋ฆฌ ์‹œ์ž‘!"); /// // ์˜ˆ: await ReleaseSomeDataUsedInModal(); /// ULog.Debug("๋‚˜๋งŒ์˜ ํŠน๋ณ„ํ•œ ๋ชจ๋‹ฌ ๋‚ด์šฉ ๋งˆ๋ฌด๋ฆฌ ์™„๋ฃŒ!"); /// await base.OnClose(); // ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ OnClose๋„ ํ˜ธ์ถœํ•ด์ฃผ๋Š” ๊ฒŒ ์ข‹์•„์š”. /// } /// } /// /// public virtual async UniTask OnClose() { // ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š์•„์š”. ํ•„์š”ํ•˜๋ฉด ์ƒ์†๋ฐ›์•„์„œ ๋‚ด์šฉ์„ ์ฑ„์›Œ์ฃผ์„ธ์š”! //ULog.Debug($"[ModalContent] '{Title}' OnClose called."); await UniTask.CompletedTask; } } }