diff --git a/Assets/Scripts/SampleProject/AppMain.cs b/Assets/Scripts/SampleProject/AppMain.cs index d16b4ef4..afe716d2 100644 --- a/Assets/Scripts/SampleProject/AppMain.cs +++ b/Assets/Scripts/SampleProject/AppMain.cs @@ -1,5 +1,7 @@ +using Cysharp.Threading.Tasks; using SampleProject.Config; using System; +using System.Threading.Tasks; using UnityEngine; using UVC.Core; using UVC.Data; @@ -20,9 +22,9 @@ namespace SampleProject /// 초기 화 메서드입니다. /// Awake 메서드에서 호출되며, MonoBehaviour가 생성될 때 한 번만 실행됩니다. /// - protected override void Init() + protected override async void Init() { - SettupConfig(); + await SettupConfigAsync(); SetNetworkConfig(); if (Initialized != null) { @@ -35,7 +37,7 @@ namespace SampleProject //Tester.RunAllTests(); } - private void SettupConfig() + private async UniTask SettupConfigAsync() { if (AppConfig.LoadConfig()) { @@ -53,6 +55,10 @@ namespace SampleProject } } } + + //사용자 DataMask 설정 AppData에서 로드 + await DataMask.LoadUserMasksFromAppData(); + } private void SetNetworkConfig() @@ -82,7 +88,7 @@ namespace SampleProject agvDataMask["JOB_ID"] = ""; agvDataMask["TIMESTAMP"] = DateTime.Now; - DataMask.AddMask("AGV", agvDataMask); + DataMask.AddMask("AGV", agvDataMask, true); DataMapperValidator.Add("AGV", new DataMapperValidator( new DataMapper(agvDataMask) @@ -91,7 +97,7 @@ namespace SampleProject // 데이터 마스크(DataMask) 정의: // 수신할 데이터의 구조를 미리 정의합니다. 여기서 정의된 키(Key)들을 기준으로 데이터를 파싱합니다. var alarmDataMask = new DataMask(); - alarmDataMask.ObjectName = "Alarm"; // Alarm 객체의 이름을 설정합니다. + alarmDataMask.ObjectName = "ALARM"; // Alarm 객체의 이름을 설정합니다. alarmDataMask.ObjectIdKey = "ID"; // Alarm의 고유 식별자로 사용할 키를 설정합니다. alarmDataMask["ID"] = ""; alarmDataMask["ALARM_TYPE"] = ""; @@ -112,7 +118,7 @@ namespace SampleProject alarmDataMask["UPDATE_TIME"] = DateTime.Now; alarmDataMask["TIMESTAMP"] = DateTime.Now; - DataMask.AddMask("ALARM", alarmDataMask); + DataMask.AddMask("ALARM", alarmDataMask, true); // 데이터 유효성 검사기(DataValidator) 설정: // 수신된 데이터가 유효한지 검사하는 규칙을 추가합니다. diff --git a/Assets/Scripts/SampleProject/SceneMain.cs b/Assets/Scripts/SampleProject/SceneMain.cs index a2349bab..22f75dfe 100644 --- a/Assets/Scripts/SampleProject/SceneMain.cs +++ b/Assets/Scripts/SampleProject/SceneMain.cs @@ -1,11 +1,8 @@ using Cysharp.Threading.Tasks; using System; -using System.Threading.Tasks; using UnityEngine; using UVC.Core; using UVC.Data; -using UVC.Data.Core; -using UVC.Data.Http; using UVC.Factory; using UVC.Factory.Alarm; using UVC.Factory.Component; @@ -31,8 +28,6 @@ namespace SampleProject AppMain.Instance.Initialized += OnAppInitialized; } - - private async void OnAppInitialized() { @@ -62,7 +57,7 @@ namespace SampleProject FactoryCameraController.Instance.Enable = true; } - private async Task requestDataAsync() + private async UniTask requestDataAsync() { Debug.Log("requestDataAsync"); diff --git a/Assets/Scripts/UVC/Data/Core/DataMask.cs b/Assets/Scripts/UVC/Data/Core/DataMask.cs index b07b3597..88800f58 100644 --- a/Assets/Scripts/UVC/Data/Core/DataMask.cs +++ b/Assets/Scripts/UVC/Data/Core/DataMask.cs @@ -1,9 +1,13 @@ #nullable enable +using Cysharp.Threading.Tasks; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Text; +using UnityEngine; using UVC.Extention; namespace UVC.Data.Core @@ -17,6 +21,8 @@ namespace UVC.Data.Core /// DataMask는 주로 DataMapper 클래스와 함께 사용되어 서로 다른 JSON 형식 간의 /// 데이터 변환 및 매핑 규칙을 정의합니다. 기본 JSON 구조 외에도 추가 속성들을 /// 통해 매핑 과정에서 필요한 메타데이터를 제공합니다. + /// 또한 AppData 폴더(AppData/Company Name/Product Name)에서 JSON 파일을 로드하고 저장하는 기능을 제공하여, + /// 그 기능은 FactoryObject의 정보를 InfoWindow로 보여줄때 사용됩니다. /// /// /// 기본 사용 예시: @@ -58,6 +64,10 @@ namespace UVC.Data.Core private static Dictionary _dataMasks = new Dictionary(); public static IReadOnlyDictionary DataMasks => _dataMasks; + // 사용자 데이터 마스크를 저장하는 컬렉션입니다. + private static Dictionary _userDataMasks = new Dictionary(); + public static IReadOnlyDictionary UserDataMasks => _userDataMasks; + /// /// 컬렉션에 데이터 마스크를 추가하고 지정된 키와 연결합니다. /// @@ -65,10 +75,16 @@ namespace UVC.Data.Core /// /// 데이터 마스크에 연결할 키입니다. 이거나 비어 있을 수 없습니다. /// 추가할 입니다. 일 수 없습니다. - public static void AddMask(string key, DataMask mask) + /// 사용자 데이터 마스크도 함께 추가할지 여부를 지정합니다. 기본값은 false입니다. + public static void AddMask(string key, DataMask mask, bool withUser = false) { if (string.IsNullOrEmpty(key) || mask == null) return; _dataMasks[key] = mask; + if (withUser && !_userDataMasks.ContainsKey(key)) + { + // 사용자 데이터 마스크로 시작하는 키는 _userDataMasks에 추가 + AddUserMask(key, mask.CreateUserMask()); + } } /// @@ -76,10 +92,16 @@ namespace UVC.Data.Core /// /// 가 null이거나 비어 있으면 메서드는 아무 작업도 수행하지 않습니다. /// 제거할 데이터 마스크를 식별하는 키입니다. null이거나 비어 있으면 안 됩니다. - public static void RemoveMask(string key) + /// 사용자 데이터 마스크도 함께 제거할지 여부를 지정합니다. 기본값은 false입니다. + public static void RemoveMask(string key, bool withUser = false) { if (string.IsNullOrEmpty(key)) return; _dataMasks.Remove(key); + if(withUser) + { + // 사용자 데이터 마스크로 시작하는 키는 _userDataMasks에서 제거 + RemoveUserMask(key); + } } /// @@ -95,7 +117,127 @@ namespace UVC.Data.Core return mask; } - + /// + /// 내부 컬렉션에서 모든 데이터 마스크를 지웁니다. + /// + /// 이 메서드는 내부 데이터 마스크 컬렉션에서 모든 항목을 제거하고 + /// 빈 상태로 재설정합니다. 이전에 추가된 모든 마스크를 지워야 할 때 이 메서드를 사용하세요. + public static void ClearMask() + { + _dataMasks.Clear(); + } + + /// + /// 사용자 정의 키를 지정된 데이터 마스크에 연결합니다. + /// + /// 동일한 키를 가진 데이터 마스크가 이미 있는 경우 새 + /// 마스크로 대체됩니다. + /// 데이터 마스크의 고유 식별자입니다. 이거나 비어 있을 수 없습니다. + /// 지정된 키와 연결할 객체입니다. 일 수 없습니다. + public static void AddUserMask(string key, DataMask mask) + { + if (string.IsNullOrEmpty(key) || mask == null) return; + _userDataMasks[key] = mask; + } + + /// + /// 지정된 키와 연관된 사용자 마스크를 제거합니다. + /// + /// 가 null이거나 비어 있으면 메서드는 아무 작업도 수행하지 않습니다. + /// + /// 제거할 사용자 마스크를 식별하는 키입니다. null이거나 비어 있으면 안 됩니다. + public static void RemoveUserMask(string key) + { + if (string.IsNullOrEmpty(key)) return; + _userDataMasks.Remove(key); + } + + /// + /// 지정된 키와 연관된 를 검색합니다. + /// + /// 연관된 를 찾는 데 사용되는 키입니다. null이거나 비어 있을 수 없습니다. + /// 지정된 키와 연관된 또는 키를 찾을 수 없거나 null이거나 비어 있는 경우 을 반환합니다. + /// + public static DataMask? GetUserMask(string key) + { + if (string.IsNullOrEmpty(key)) return null; + _userDataMasks.TryGetValue(key, out var mask); + return mask; + } + + /// + /// 내부 컬렉션에서 모든 사용자 데이터 마스크를 지웁니다. + /// + /// 이 메서드는 사용자 데이터 마스크 컬렉션에서 모든 항목을 제거하고 빈 상태로 재설정합니다. + /// 일반적으로 새 마스크를 적용하기 전에 이전에 적용된 마스크를 지우는 데 사용됩니다. + /// + public static void ClearUserMask() + { + _userDataMasks.Clear(); + } + + /// + /// 애플리케이션의 영구 데이터 디렉터리(AppData/Company Name/Product Name)에서 사용자 마스크 데이터를 로드합니다. + /// + /// 이 메서드는 애플리케이션의 영구 데이터 경로에 있는 "user" 하위 디렉터리에서 JSON 파일을 검색합니다. + /// 각 JSON 파일을 읽고 그 내용을 사용하여 + /// 객체를 생성한 후 애플리케이션의 사용자 마스크 컬렉션에 추가합니다. 이 메서드는 메인 스레드를 차단하지 않도록 백그라운드 + /// 스레드에서 실행됩니다. + /// + public static async UniTask LoadUserMasksFromAppData() + { + string persistentDataPath = UnityEngine.Application.persistentDataPath; + await UniTask.RunOnThreadPool(() => + { + string folderPath = System.IO.Path.Combine(persistentDataPath, "user"); + DirectoryInfo directory = new DirectoryInfo(folderPath); + if (!directory.Exists) return; + FileInfo[] files = directory.GetFiles("*.json"); + foreach (FileInfo file in files) + { + string filePath = file.FullName; + string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath); + if (string.IsNullOrEmpty(fileName)) continue; + string jsonString = System.IO.File.ReadAllText(filePath); + AddUserMask(fileName, new DataMask(jsonString)); + } + }); + } + + /// + /// 사용자 데이터 마스크를 애플리케이션의 영구 데이터 경로(AppData/Company Name/Product Name)에 저장합니다. + /// + /// 이 메서드는 모든 사용자 데이터 마스크를 반복하며 각 마스크를 JSON 파일로 저장합니다. + /// 애플리케이션의 영구 데이터 경로에 있는 "user" 하위 디렉터리에 디렉터리가 없으면 + /// 생성됩니다. 각 파일의 이름은 해당 키와 ".json" 확장자를 사용하여 지정됩니다. 저장 과정에서 발생하는 모든 오류는 + /// Unity 콘솔에 기록됩니다. + /// + public static async UniTask SaveUserMasksToAppData() + { + string persistentDataPath = UnityEngine.Application.persistentDataPath; + await UniTask.RunOnThreadPool(() => + { + foreach (var keyValue in _userDataMasks) + { + string key = keyValue.Key; + if (string.IsNullOrEmpty(key)) continue; + if (!_userDataMasks.TryGetValue(key, out var mask)) return; + try + { + string folderPath = System.IO.Path.Combine(persistentDataPath, "user"); + if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath); + string filePath = System.IO.Path.Combine(folderPath, $"{key}.json"); + string jsonString = mask.ToJsonString(); + System.IO.File.WriteAllText(filePath, jsonString); + } + catch (Exception ex) + { + Debug.LogError($"DataMask SaveToStreamingAssets Error: {ex.Message}"); + } + } + }); + } + /// /// DataObject의 Id에 해당하는 key 문자열입니다. @@ -354,6 +496,23 @@ namespace UVC.Data.Core return mask; } + /// + /// 현재 컬렉션의 각 키가 자기 자신에게 매핑되는 새로운 인스턴스를 생성합니다. + /// + /// 이 메서드는 현재 컬렉션을 반복하고 컬렉션의 각 키가 결과 마스크의 키와 값으로 모두 사용되는 새로운 를 생성합니다. + /// + /// 각 키가 자기 자신에게 매핑되는 키-값 쌍을 포함하는 객체를 반환합니다. + public DataMask CreateUserMask() + { + DataMask userMask = new DataMask(); + foreach (var pair in this) + { + userMask[pair.Key] = pair.Key; + } + return userMask; + } + /// /// Json 문자열로 변환합니다. /// diff --git a/Assets/Scripts/UVC/Factory/Alarm/AlarmDetailView.cs b/Assets/Scripts/UVC/Factory/Alarm/AlarmDetailView.cs index 03c3fc89..4be56082 100644 --- a/Assets/Scripts/UVC/Factory/Alarm/AlarmDetailView.cs +++ b/Assets/Scripts/UVC/Factory/Alarm/AlarmDetailView.cs @@ -1,4 +1,5 @@ -using TMPro; +#nullable enable +using TMPro; using UnityEngine; using UnityEngine.UI; using UVC.Data.Core; @@ -36,12 +37,24 @@ namespace UVC.Factory.Alarm public void Show(DataObject data) { string combinedString = string.Empty; - - combinedString += $"ALARM_TYPE{data.GetString("ALARM_TYPE") ?? "null"}\n"; - combinedString += $"CODE{data.GetString("CODE") ?? "null"}\n"; - combinedString += $"MACHINENAME{data.GetString("MACHINENAME") ?? "null"}\n"; - combinedString += $"MESSAGE{data.GetString("MESSAGE") ?? "null"}\n"; - combinedString += $"TIMESTAMP{data.GetString("TIMESTAMP") ?? "null"}\n"; + + DataMask? userMask = DataMask.GetUserMask("UserALARM"); + if (userMask != null) + { + foreach (var item in userMask) + { + // DataObject에서 해당 키의 값을 가져와서 표시합니다. + combinedString += $"{item.Key}{data.GetString(item.Key) ?? "null"}\n"; + } + } + else + { + combinedString += $"ALARM_TYPE{data.GetString("ALARM_TYPE") ?? "null"}\n"; + combinedString += $"CODE{data.GetString("CODE") ?? "null"}\n"; + combinedString += $"MACHINENAME{data.GetString("MACHINENAME") ?? "null"}\n"; + combinedString += $"MESSAGE{data.GetString("MESSAGE") ?? "null"}\n"; + combinedString += $"TIMESTAMP{data.GetString("TIMESTAMP") ?? "null"}\n"; + } combinedString = combinedString.TrimEnd('\n'); // 마지막 줄바꿈 제거 detailTxt.text = combinedString; diff --git a/Assets/Scripts/UVC/Factory/Component/AGV.cs b/Assets/Scripts/UVC/Factory/Component/AGV.cs index 41285c02..4029921c 100644 --- a/Assets/Scripts/UVC/Factory/Component/AGV.cs +++ b/Assets/Scripts/UVC/Factory/Component/AGV.cs @@ -72,8 +72,8 @@ namespace UVC.Factory.Component public override void OnPointerClick(PointerEventData eventData) { - // 사용자가 AGV를 클릭했을 때 정보창에 표시될 데이터 항목과 순서를 정의합니다. - DataOrderedMask = DataMask.Get("ConfigAGV"); + // 사용자가 AGV를 클릭했을 때 정보창에 표시될 데이터 항목과 순서를 정의합니다. User+TOPIC 이름 + if(dataOrderedMask == null) dataOrderedMask = DataMask.GetUserMask("AGV"); base.OnPointerClick(eventData); } diff --git a/Assets/Scripts/UVC/Factory/Modal/Config/ConfigDataOrderModal.cs b/Assets/Scripts/UVC/Factory/Modal/Config/ConfigDataOrderModal.cs index c9b845d1..b8589afc 100644 --- a/Assets/Scripts/UVC/Factory/Modal/Config/ConfigDataOrderModal.cs +++ b/Assets/Scripts/UVC/Factory/Modal/Config/ConfigDataOrderModal.cs @@ -24,6 +24,7 @@ namespace UVC.Factory.Modal.Config var dic = DataMask.DataMasks; foreach (var item in dic) { + if(item.Key.StartsWith("User")) continue; // "User"로 시작하지 않는 키만 처리합니다. Debug.Log($"Key: {item.Key}, Value: {item.Value}"); // 1. TabConfig 설정 tabController.AddTabConfig(item.Key, item.Key, "Prefabs/UI/Tab/ConfigDataOrderTabContent", null, item.Key, true); @@ -49,7 +50,7 @@ namespace UVC.Factory.Modal.Config /// public override async UniTask OnClose(ModalContent content) { - + await DataMask.SaveUserMasksToAppData(); // 데이터 마스크를 앱 데이터에 저장합니다. await base.OnClose(content); } diff --git a/Assets/Scripts/UVC/Factory/Modal/Config/ConfigDataOrderTabContent.cs b/Assets/Scripts/UVC/Factory/Modal/Config/ConfigDataOrderTabContent.cs index 251d6750..1d9dc34f 100644 --- a/Assets/Scripts/UVC/Factory/Modal/Config/ConfigDataOrderTabContent.cs +++ b/Assets/Scripts/UVC/Factory/Modal/Config/ConfigDataOrderTabContent.cs @@ -1,8 +1,8 @@ #nullable enable using System.Collections.Generic; -using UnityEditor.Rendering.LookDev; using UnityEngine; using UVC.Data.Core; +using UVC.Extention; using UVC.UI.List.Draggable; using UVC.UI.Tab; @@ -15,7 +15,6 @@ namespace UVC.Factory.Modal.Config private DraggableList? draggableList; private string key = string.Empty; - private string configKey = string.Empty; private DataMask? totalData = null; private DataMask? viewData = null; @@ -36,18 +35,15 @@ namespace UVC.Factory.Modal.Config if (data is string key) { this.key = key; - configKey = $"Config{key}"; - DataMask? mask = DataMask.Get(key); - if (mask != null) totalData = mask; - - viewData = DataMask.Get(configKey); + totalData = DataMask.Get(key); if (totalData != null) { + viewData = DataMask.GetUserMask(key); //저장 되 있는 데이터가 없으면 전체 아이템을 체크된 상태로 추가 if (viewData == null) { - viewData = totalData.DeepClone(); - DataMask.AddMask(configKey, viewData); + viewData = totalData.CreateUserMask(); + DataMask.AddUserMask(key, viewData); } List dataList = new List(); @@ -55,7 +51,7 @@ namespace UVC.Factory.Modal.Config foreach (var item in totalData) { bool isChecked = viewData!.ContainsKey(item.Key); - dataList.Add(new ConfigDataOrderListItemData(item.Key, item.Key, isChecked)); + dataList.Add(new ConfigDataOrderListItemData(item.Key, (isChecked ? viewData[item.Key].ToString() : item.Key), isChecked)); } //드래그 가능한 리스트에 데이터 설정 draggableList?.SetData(dataList); @@ -76,9 +72,10 @@ namespace UVC.Factory.Modal.Config private void UpdateData() { - Debug.Log($"UpdateData: draggableList != null:{draggableList != null}, viewData != null:{viewData != null}, configKey:{configKey}"); - if (draggableList != null && viewData != null && configKey.Length > 0) + Debug.Log($"UpdateData: draggableList != null:{draggableList != null}, viewData != null:{viewData != null}, configKey:{key}"); + if (draggableList != null && viewData != null && key.Length > 0) { + viewData.Clear(); foreach (var item in draggableList.DataList) { if (item is ConfigDataOrderListItemData listItemData) @@ -87,14 +84,10 @@ namespace UVC.Factory.Modal.Config { viewData[listItemData.Id] = listItemData.DisplayName; } - else - { - viewData.Remove(listItemData.Id); - } } } - Debug.Log($"UpdateData: {configKey} - {viewData.ToJsonString()} items"); - DataMask.AddMask(configKey, viewData); + Debug.Log($"UpdateData: {key} - {viewData.ToJsonString()} items"); + DataMask.AddUserMask(key, viewData); } } diff --git a/Assets/Scripts/UVC/Factory/Playback/PlaybackService.cs b/Assets/Scripts/UVC/Factory/Playback/PlaybackService.cs index 0747d3e5..8210821d 100644 --- a/Assets/Scripts/UVC/Factory/Playback/PlaybackService.cs +++ b/Assets/Scripts/UVC/Factory/Playback/PlaybackService.cs @@ -194,7 +194,7 @@ namespace UVC.Factory.Playback /// await PlaybackService.Instance.StartAsync(itemData); /// /// - public async Task StartAsync(UIPlaybackListItemData data) + public async UniTask StartAsync(UIPlaybackListItemData data) { timeScale = 1.0f; //기본 시간 스케일 설정 UIPlayback.Instance.Show(); diff --git a/Assets/Scripts/UVC/UI/List/Draggable/DragBehavior.cs b/Assets/Scripts/UVC/UI/List/Draggable/DragBehavior.cs index a007285d..58d9a9b8 100644 --- a/Assets/Scripts/UVC/UI/List/Draggable/DragBehavior.cs +++ b/Assets/Scripts/UVC/UI/List/Draggable/DragBehavior.cs @@ -123,7 +123,7 @@ namespace UVC.UI.List.Draggable // 구독자들에게 드래그 종료를 알립니다 OnDragEnded?.Invoke(eventData); - Debug.Log($"[DragBehavior] 드래그 종료 - 아이템: {dragTarget.name}"); + //Debug.Log($"[DragBehavior] 드래그 종료 - 아이템: {dragTarget.name}"); } /// @@ -135,7 +135,7 @@ namespace UVC.UI.List.Draggable originalIndex = dragTarget.GetSiblingIndex(); originalPosition = dragTarget.position; - Debug.Log($"[DragBehavior] 위치 정보 업데이트 - 새 인덱스: {originalIndex}"); + //Debug.Log($"[DragBehavior] 위치 정보 업데이트 - 새 인덱스: {originalIndex}"); } /// diff --git a/Assets/Scripts/UVC/UI/List/Draggable/DraggableList.cs b/Assets/Scripts/UVC/UI/List/Draggable/DraggableList.cs index d3539e5b..9896a2b3 100644 --- a/Assets/Scripts/UVC/UI/List/Draggable/DraggableList.cs +++ b/Assets/Scripts/UVC/UI/List/Draggable/DraggableList.cs @@ -141,7 +141,7 @@ namespace UVC.UI.List.Draggable if (reorderHandler == null) { reorderHandler = content.gameObject.AddComponent(); - Debug.Log("[DraggableList] ListReorderHandler를 자동으로 추가했습니다."); + //Debug.Log("[DraggableList] ListReorderHandler를 자동으로 추가했습니다."); } // ScrollRectHandler 추가 또는 가져오기 @@ -152,7 +152,7 @@ namespace UVC.UI.List.Draggable if (scrollHandler == null) { scrollHandler = scrollRect.gameObject.AddComponent(); - Debug.Log("[DraggableList] ScrollRectHandler를 자동으로 추가했습니다."); + //Debug.Log("[DraggableList] ScrollRectHandler를 자동으로 추가했습니다."); } } @@ -249,6 +249,7 @@ namespace UVC.UI.List.Draggable var item = dataList[oldIndex]; dataList.RemoveAt(oldIndex); dataList.Insert(newIndex, item); + Debug.Log($"[DraggableList] 순서 변경: {oldIndex} -> {newIndex}"); // 이벤트 발생 OnOrderChanged?.Invoke((item as ListItemData)!, oldIndex, newIndex); @@ -259,7 +260,6 @@ namespace UVC.UI.List.Draggable // SaveOrder(); //} - Debug.Log($"[DraggableList] 순서 변경: {oldIndex} -> {newIndex}"); } } @@ -269,7 +269,7 @@ namespace UVC.UI.List.Draggable private void HandleItemClick(object data) { OnItemClicked?.Invoke((data as ListItemData)!); - Debug.Log($"[DraggableList] 아이템 클릭: {(data as ListItemData)?.DisplayName}"); + //Debug.Log($"[DraggableList] 아이템 클릭: {(data as ListItemData)?.DisplayName}"); } /// diff --git a/Assets/Scripts/UVC/UI/List/Draggable/ListItemController.cs b/Assets/Scripts/UVC/UI/List/Draggable/ListItemController.cs index eb57dd16..89698c8f 100644 --- a/Assets/Scripts/UVC/UI/List/Draggable/ListItemController.cs +++ b/Assets/Scripts/UVC/UI/List/Draggable/ListItemController.cs @@ -135,7 +135,7 @@ namespace UVC.UI.List.Draggable /// private void HandleDragEnd(PointerEventData eventData) { - Debug.Log($"[ListItemController] 드래그 종료 처리 - {gameObject.name}"); + //Debug.Log($"[ListItemController] 드래그 종료 처리 - {gameObject.name}"); // 1. 아이템을 원래 투명도로 복원합니다 if (canvasGroup != null) diff --git a/Assets/Scripts/UVC/UI/List/Draggable/ListItemView.cs b/Assets/Scripts/UVC/UI/List/Draggable/ListItemView.cs index 66ae18a2..12a25af3 100644 --- a/Assets/Scripts/UVC/UI/List/Draggable/ListItemView.cs +++ b/Assets/Scripts/UVC/UI/List/Draggable/ListItemView.cs @@ -48,7 +48,7 @@ namespace UVC.UI.List.Draggable boundData = data; UpdateUI(); - Debug.Log($"[ListItemView] 데이터 바인딩 완료 - {gameObject.name}"); + //Debug.Log($"[ListItemView] 데이터 바인딩 완료 - {gameObject.name}"); } /// diff --git a/Assets/Scripts/UVC/UI/List/Draggable/ListReorderHandler.cs b/Assets/Scripts/UVC/UI/List/Draggable/ListReorderHandler.cs index a85f183c..99fc4db0 100644 --- a/Assets/Scripts/UVC/UI/List/Draggable/ListReorderHandler.cs +++ b/Assets/Scripts/UVC/UI/List/Draggable/ListReorderHandler.cs @@ -76,7 +76,7 @@ namespace UVC.UI.List.Draggable // 마우스 위치에서 가장 가까운 인덱스를 계산합니다 int targetIndex = CalculateTargetIndex(position); - Debug.Log($"[ListReorderHandler] 드래그 위치 업데이트 - 타겟 인덱스: {targetIndex}"); + //Debug.Log($"[ListReorderHandler] 드래그 위치 업데이트 - 타겟 인덱스: {targetIndex}"); if (targetIndex >= 0) { // 현재 플레이스홀더의 인덱스와 다를 때만 이동 @@ -116,7 +116,7 @@ namespace UVC.UI.List.Draggable if (item.OriginalIndex != newIndex) { OnOrderChanged?.Invoke(item.OriginalIndex, newIndex); - Debug.Log($"[ListReorderHandler] 순서 변경됨: {item.OriginalIndex} -> {newIndex}"); + //Debug.Log($"[ListReorderHandler] 순서 변경됨: {item.OriginalIndex} -> {newIndex}"); } } else diff --git a/Assets/Scripts/UVC/UI/List/Draggable/ScrollRectHandler.cs b/Assets/Scripts/UVC/UI/List/Draggable/ScrollRectHandler.cs index 3920bde0..408aec0b 100644 --- a/Assets/Scripts/UVC/UI/List/Draggable/ScrollRectHandler.cs +++ b/Assets/Scripts/UVC/UI/List/Draggable/ScrollRectHandler.cs @@ -73,7 +73,7 @@ namespace UVC.UI.List.Draggable if (autoScrollCoroutine == null) { autoScrollCoroutine = StartCoroutine(AutoScrollRoutine()); - Debug.Log("[ScrollRectHandler] 자동 스크롤 시작"); + //Debug.Log("[ScrollRectHandler] 자동 스크롤 시작"); } } else @@ -86,7 +86,7 @@ namespace UVC.UI.List.Draggable { StopCoroutine(autoScrollCoroutine); autoScrollCoroutine = null; - Debug.Log("[ScrollRectHandler] 자동 스크롤 중지"); + //Debug.Log("[ScrollRectHandler] 자동 스크롤 중지"); } } } @@ -123,7 +123,7 @@ namespace UVC.UI.List.Draggable float normalizedDistance = (topY - mouseY) / scrollZoneHeight; scrollDelta = scrollSpeed * (1f - normalizedDistance) * Time.deltaTime; - Debug.Log($"[ScrollRectHandler] 위로 스크롤 중... 속도: {scrollDelta}"); + //Debug.Log($"[ScrollRectHandler] 위로 스크롤 중... 속도: {scrollDelta}"); } // 마우스가 아래쪽 가장자리 근처에 있으면 아래로 스크롤 else if (mouseY < bottomY + scrollZoneHeight && mouseY >= bottomY) @@ -132,7 +132,7 @@ namespace UVC.UI.List.Draggable float normalizedDistance = (mouseY - bottomY) / scrollZoneHeight; scrollDelta = -scrollSpeed * (1f - normalizedDistance) * Time.deltaTime; - Debug.Log($"[ScrollRectHandler] 아래로 스크롤 중... 속도: {scrollDelta}"); + //Debug.Log($"[ScrollRectHandler] 아래로 스크롤 중... 속도: {scrollDelta}"); } // 스크롤 적용 diff --git a/Assets/Scripts/UVC/UI/Loading/UILoading.cs b/Assets/Scripts/UVC/UI/Loading/UILoading.cs index c80adad8..3dd899e3 100644 --- a/Assets/Scripts/UVC/UI/Loading/UILoading.cs +++ b/Assets/Scripts/UVC/UI/Loading/UILoading.cs @@ -136,7 +136,6 @@ namespace UVC.UI.Loading { // 이미 애니메이션이 진행 중이고, 목표가 '나타나기(target=1)'라면 중복 실행을 방지합니다. if (animatting && target == 1) return; - target = 1; // 목표 알파 값을 1(불투명)로 설정 animatting = true; // 애니메이션 시작 상태로 변경 StopCoroutine("Animate"); // 이전에 실행 중이던 Animate 코루틴이 있다면 중지 diff --git a/Assets/Scripts/UVC/UI/Modal/ModalContent.cs b/Assets/Scripts/UVC/UI/Modal/ModalContent.cs index 7a62ff8f..395df6d0 100644 --- a/Assets/Scripts/UVC/UI/Modal/ModalContent.cs +++ b/Assets/Scripts/UVC/UI/Modal/ModalContent.cs @@ -6,6 +6,7 @@ namespace UVC.UI.Modal /// /// 📜 모달 창에 어떤 내용을 보여줄지, 어떻게 행동할지 정하는 '레시피' 또는 '주문서' 같은 친구예요. /// 이 클래스의 객체를 만들어서 Modal.Open()에 전달하면, 여기에 적힌 대로 모달 창이 만들어져요. + /// 커스텀 모달 창을 만들 때는 ModalView를 상속받아서 Prefab으로 만들고 ModalContent 생성자에 Prefab 경로를 전달해야 한다. /// /// ///