diff --git a/Assets/Resources/Prefabs/UI/List/ComponentList.prefab b/Assets/Resources/Prefabs/UI/List/ComponentList.prefab index fe62f0be..8962847c 100644 --- a/Assets/Resources/Prefabs/UI/List/ComponentList.prefab +++ b/Assets/Resources/Prefabs/UI/List/ComponentList.prefab @@ -696,8 +696,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} + m_AnchoredPosition: {x: -4, y: 0} + m_SizeDelta: {x: -8, y: 0} m_Pivot: {x: 0.5, y: 1} --- !u!1 &3653955404686234285 GameObject: @@ -1296,7 +1296,7 @@ RectTransform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 4780031981297733594} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 @@ -1635,7 +1635,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} - m_Color: {r: 0.14509805, g: 0.14509805, b: 0.14901961, a: 1} + m_Color: {r: 0.09411765, g: 0.09411765, b: 0.09411765, a: 1} m_RaycastTarget: 1 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 diff --git a/Assets/Resources/Prefabs/UI/List/ComponentListItem.prefab b/Assets/Resources/Prefabs/UI/List/ComponentListItem.prefab index da60e51b..4f108288 100644 --- a/Assets/Resources/Prefabs/UI/List/ComponentListItem.prefab +++ b/Assets/Resources/Prefabs/UI/List/ComponentListItem.prefab @@ -37,7 +37,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 283.21, y: -3.5} + m_AnchoredPosition: {x: 24.000008, y: -3.5} m_SizeDelta: {x: 16.79, y: 15} m_Pivot: {x: 0, y: 1} --- !u!222 &1821424897527179892 @@ -491,10 +491,10 @@ RectTransform: m_Children: [] m_Father: {fileID: 3094276047947572059} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 1} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 8.395, y: -7.5} - m_SizeDelta: {x: 6.79, y: 15} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 15} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &7899941541401797984 MonoBehaviour: @@ -915,7 +915,7 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 24, y: 0} + m_AnchoredPosition: {x: 14, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0, y: 0.5} --- !u!114 &7408577993659041275 @@ -1239,7 +1239,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!224 &3186561737559845992 RectTransform: m_ObjectHideFlags: 0 @@ -1429,6 +1429,7 @@ GameObject: m_Component: - component: {fileID: 5465326936975101749} - component: {fileID: 4840481829667430247} + - component: {fileID: 1665617654693435641} m_Layer: 5 m_Name: buttonLayout m_TagString: Untagged @@ -1452,11 +1453,11 @@ RectTransform: - {fileID: 3094276047947572059} m_Father: {fileID: 3186561737559845992} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} + m_AnchorMin: {x: 1, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: -2, y: 0} + m_SizeDelta: {x: 0, y: 22} + m_Pivot: {x: 1, y: 0.5} --- !u!114 &4840481829667430247 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1478,11 +1479,25 @@ MonoBehaviour: m_Spacing: 2 m_ChildForceExpandWidth: 0 m_ChildForceExpandHeight: 0 - m_ChildControlWidth: 0 + m_ChildControlWidth: 1 m_ChildControlHeight: 0 m_ChildScaleWidth: 0 m_ChildScaleHeight: 0 m_ReverseArrangement: 0 +--- !u!114 &1665617654693435641 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6561606999579660431} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalFit: 2 + m_VerticalFit: 0 --- !u!1 &6794951674005590907 GameObject: m_ObjectHideFlags: 0 @@ -1740,9 +1755,8 @@ MonoBehaviour: m_PersistentCalls: m_Calls: - m_Target: {fileID: 7854172782492240363} - m_TargetAssemblyTypeName: UVC.Factory.Modal.ComponentList.ComponentListItem, - Assembly-CSharp - m_MethodName: OnnSearchButtonClick + m_TargetAssemblyTypeName: UVC.UI.List.ComponentList.ComponentListItem, Assembly-CSharp + m_MethodName: OnSearchButtonClick m_Mode: 1 m_Arguments: m_ObjectArgument: {fileID: 0} @@ -1970,10 +1984,10 @@ RectTransform: m_Children: [] m_Father: {fileID: 5465326936975101749} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 1} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 270.21, y: -11} - m_SizeDelta: {x: 22, y: 22} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 22} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &4173370272032766120 CanvasRenderer: diff --git a/Assets/Scenes/SampleProject.unity b/Assets/Scenes/SampleProject.unity index 4b58c166..1751c7c4 100644 --- a/Assets/Scenes/SampleProject.unity +++ b/Assets/Scenes/SampleProject.unity @@ -3827,44 +3827,40 @@ PrefabInstance: m_Modifications: - target: {fileID: 2474022222875862313, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_AnchorMax.y - value: 1 + value: 0 objectReference: {fileID: 0} - target: {fileID: 2474022222875862313, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_AnchorMin.y - value: 1 + value: 0 objectReference: {fileID: 0} - target: {fileID: 2474022222875862313, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_AnchoredPosition.x - value: 69 + value: 0 objectReference: {fileID: 0} - target: {fileID: 2474022222875862313, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_AnchoredPosition.y - value: -11 + value: 0 objectReference: {fileID: 0} - target: {fileID: 2915193004061658818, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_AnchorMax.y - value: 1 + value: 0 objectReference: {fileID: 0} - target: {fileID: 2915193004061658818, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_AnchorMin.y - value: 1 + value: 0 objectReference: {fileID: 0} - target: {fileID: 2915193004061658818, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_AnchoredPosition.x - value: 17 + value: 0 objectReference: {fileID: 0} - target: {fileID: 2915193004061658818, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_AnchoredPosition.y - value: -11 + value: 0 objectReference: {fileID: 0} - target: {fileID: 4780031981297733594, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_Name value: ComponentList objectReference: {fileID: 0} - - target: {fileID: 4780031981297733594, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} - propertyPath: m_IsActive - value: 0 - objectReference: {fileID: 0} - target: {fileID: 6256043013987599201, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_Pivot.x value: 0 @@ -3947,27 +3943,27 @@ PrefabInstance: objectReference: {fileID: 0} - target: {fileID: 6489426726778983930, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_AnchorMax.x - value: 1 + value: 0 objectReference: {fileID: 0} - target: {fileID: 6489426726778983930, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_AnchorMax.y - value: 1 + value: 0 objectReference: {fileID: 0} - target: {fileID: 7293212476643642616, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_AnchorMax.y - value: 1 + value: 0 objectReference: {fileID: 0} - target: {fileID: 7293212476643642616, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_AnchorMin.y - value: 1 + value: 0 objectReference: {fileID: 0} - target: {fileID: 7293212476643642616, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_AnchoredPosition.x - value: 43 + value: 0 objectReference: {fileID: 0} - target: {fileID: 7293212476643642616, guid: 03f8f942677c5ce45b29b5e38c28cb18, type: 3} propertyPath: m_AnchoredPosition.y - value: -11 + value: 0 objectReference: {fileID: 0} m_RemovedComponents: [] m_RemovedGameObjects: [] diff --git a/Assets/Scripts/UVC/Factory/Camera/FactoryCameraController.cs b/Assets/Scripts/UVC/Factory/Camera/FactoryCameraController.cs index 2702817d..0261a7bc 100644 --- a/Assets/Scripts/UVC/Factory/Camera/FactoryCameraController.cs +++ b/Assets/Scripts/UVC/Factory/Camera/FactoryCameraController.cs @@ -426,7 +426,7 @@ namespace UVC.Factory /// 포커스할 대상의 Transform /// 대상과의 거리 /// 이동에 걸리는 시간(초), 기본값 1초 - public void FocusOnTarget(Vector3 equipmentPosition, float distance, float duration = 1.0f, bool keepYRotation = true) + public void FocusOnTarget(Vector3 equipmentPosition, float distance, float cameraPitch = 45, float duration = 1.0f, bool keepYRotation = true) { if (equipmentPosition == null) return; @@ -443,7 +443,7 @@ namespace UVC.Factory } // 코루틴을 사용하여 부드러운 이동 구현 - focusCoroutine = StartCoroutine(SmoothFocusOnTarget(position, distance, duration, keepYRotation)); + focusCoroutine = StartCoroutine(SmoothFocusOnTarget(position, distance, cameraPitch, duration, keepYRotation)); } /// @@ -454,7 +454,7 @@ namespace UVC.Factory /// 시각적으로 부드러운 움직임을 구현할 수 있습니다. /// 카메라를 현재 위치에서 바깥쪽으로 이동할 거리(단위)입니다. /// 카메라 전환이 발생하는 시간(초)입니다. 기본값은 1.0초입니다. - public void FocusOut(float distance, float duration = 1.0f) + public void FocusOut(float distance, float cameraPitch = 45, float duration = 1.0f) { StopFocusCoroutine(); @@ -465,13 +465,13 @@ namespace UVC.Factory // 카메라가 바라보는 방향으로 지정된 거리만큼 이동 Vector3 targetPosition = transform.position + transform.forward * distance; // 코루틴을 사용하여 부드러운 이동 구현 - focusCoroutine = StartCoroutine(SmoothFocusOnTarget(targetPosition, distance, duration)); + focusCoroutine = StartCoroutine(SmoothFocusOnTarget(targetPosition, distance, cameraPitch, duration)); } /// /// 부드럽게 타겟까지 이동하는 코루틴 /// - private IEnumerator SmoothFocusOnTarget(Vector3 targetTransform, float distance, float duration, bool keepYRotation = true) + private IEnumerator SmoothFocusOnTarget(Vector3 targetTransform, float distance, float cameraPitch, float duration, bool keepYRotation = true) { // 카메라가 바라볼 대상의 중심점 Vector3 targetPosition = targetTransform; @@ -480,21 +480,16 @@ namespace UVC.Factory Vector3 startPosition = transform.position; Quaternion startRotation = transform.rotation; - // 타겟을 보는 최종 위치와 회전 계산 - Vector3 directionToTarget = (targetPosition - startPosition).normalized; - Vector3 endPosition = targetPosition - directionToTarget * distance; - // 최종 회전값 계산 - Quaternion endRotation = Quaternion.LookRotation(targetPosition - endPosition); + // keepYRotation 플래그에 따라 Y축 회전값을 결정합니다. + float targetYaw = keepYRotation ? startRotation.eulerAngles.y : Quaternion.LookRotation(targetPosition - startPosition).eulerAngles.y; + Quaternion endRotation = Quaternion.Euler(cameraPitch, targetYaw, 0); - if (keepYRotation) - { - Vector3 euler = endRotation.eulerAngles; - euler.y = 0; // Y축 회전각을 0으로 설정 - endRotation = Quaternion.Euler(euler); - } + // 최종 위치 계산: 목표 지점에서 지정된 거리만큼, 계산된 최종 회전 방향의 반대쪽으로 이동합니다. + Vector3 endPosition = targetPosition - (endRotation * Vector3.forward) * distance; - endRotation = ValidateRotation(endRotation); // 회전값 검증 및 수정 + // 회전값 검증 및 수정 + endRotation = ValidateRotation(endRotation); // 이동 시간 계산을 위한 변수 float elapsedTime = 0f; @@ -518,14 +513,7 @@ namespace UVC.Factory // 정확한 최종 위치와 회전 설정 transform.position = endPosition; - transform.LookAt(targetPosition); - - if (keepYRotation) - { - Vector3 finalEuler = transform.eulerAngles; - finalEuler.y = 0; - transform.rotation = Quaternion.Euler(finalEuler); - } + transform.rotation = endRotation; // 회전 피봇 포인트 업데이트 rotationPivot = targetPosition; diff --git a/Assets/Scripts/UVC/UI/List/ComponentList/ComponentList.cs b/Assets/Scripts/UVC/UI/List/ComponentList/ComponentList.cs index 055761d2..6b60ca7c 100644 --- a/Assets/Scripts/UVC/UI/List/ComponentList/ComponentList.cs +++ b/Assets/Scripts/UVC/UI/List/ComponentList/ComponentList.cs @@ -339,6 +339,16 @@ namespace UVC.UI.List.ComponentList { inputField.text = string.Empty; // 입력 필드 초기화 inputField.ActivateInputField(); // 입력 필드에 다시 포커스 설정 + if (filteredData != null) + { + // 각 아이템의 Action 참조를 명시적으로 해제하여 메모리 누수 가능성을 방지합니다. + foreach (var item in filteredData) + { + item.OnCategoryExpendAction = null; + } + filteredData.Clear(); // 필터링된 데이터 리스트를 비웁니다. + filteredData = null; + } // scrollList에 설정된 필터를 제거(null)하여 모든 항목이 보이도록 합니다. scrollList.SetFilter(null); scrollList.ClearData(); // 스크롤 리스트의 내용을 비웁니다. diff --git a/Assets/Scripts/UVC/UI/List/ComponentList/ComponentListItem.cs b/Assets/Scripts/UVC/UI/List/ComponentList/ComponentListItem.cs index bcc4d5db..295933cf 100644 --- a/Assets/Scripts/UVC/UI/List/ComponentList/ComponentListItem.cs +++ b/Assets/Scripts/UVC/UI/List/ComponentList/ComponentListItem.cs @@ -236,11 +236,11 @@ namespace UVC.UI.List.ComponentList Toast.Show(LocalizationManager.Instance.GetString($"{itemData.factoryObjectInfo.Name} 객체를 찾을 수 없습니다."), 2f); return; } - // 객체가 존재하고 활성화 상태일 때만 카메라를 이동시킵니다. if (obj != null && obj.gameObject.activeSelf) { // FactoryCameraController를 사용하여 해당 객체의 위치로 카메라를 부드럽게 이동시킵니다. + FactoryObjectSelectionManager.Instance.Select(obj); FactoryCameraController.Instance.FocusOnTarget(obj.transform.position, 10f); } }