764 lines
27 KiB
C#
764 lines
27 KiB
C#
#nullable enable
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.UIElements;
|
||
using UVC.UIToolkit;
|
||
|
||
/// <summary>
|
||
/// UTKAccordionListWindow의 기능을 테스트하기 위한 샘플 MonoBehaviour입니다.
|
||
/// 아코디언 리스트 데이터를 생성하고 다양한 이벤트 핸들러를 등록하여 동작을 확인합니다.
|
||
///
|
||
/// <para><b>테스트 기능:</b></para>
|
||
/// <list type="bullet">
|
||
/// <item>섹션 펼침/접힘</item>
|
||
/// <item>수평 레이아웃 (Head-Content-Tail)</item>
|
||
/// <item>그리드 레이아웃 (Image + Caption)</item>
|
||
/// <item>검색 필터링</item>
|
||
/// <item>드래그 앤 드롭 이벤트</item>
|
||
/// </list>
|
||
/// </summary>
|
||
public class UTKAccordionListWindowSample : MonoBehaviour
|
||
{
|
||
#region 필드 (Fields)
|
||
|
||
[SerializeField]
|
||
[Tooltip("UI를 표시할 UIDocument 컴포넌트")]
|
||
public UIDocument? uiDocument;
|
||
|
||
|
||
[SerializeField]
|
||
[Tooltip("드래그 시 고스트 이미지 표시 여부")]
|
||
private bool showDragGhost = true;
|
||
|
||
[SerializeField]
|
||
[Tooltip("시작 시 적용할 테마")]
|
||
private UTKTheme initialTheme = UTKTheme.Dark;
|
||
|
||
private UTKToggle _themeToggle;
|
||
|
||
/// <summary>UTKAccordionListWindow 인스턴스</summary>
|
||
private UTKAccordionListWindow _accordionWindow;
|
||
|
||
/// <summary>드롭 위치 (스크린 좌표)</summary>
|
||
private Vector2 _lastDropScreenPosition;
|
||
|
||
/// <summary>메인 카메라 참조</summary>
|
||
private Camera? _mainCamera;
|
||
|
||
/// <summary>드래그 중인 3D 프리뷰 오브젝트</summary>
|
||
private GameObject? _dragPreview3D;
|
||
|
||
/// <summary>드래그 중 리스트 영역 밖에 있는지 여부</summary>
|
||
private bool _isOutsideListArea;
|
||
|
||
|
||
|
||
#endregion
|
||
|
||
#region Unity 라이프사이클
|
||
|
||
private void Start()
|
||
{
|
||
// UIDocument 참조 확인
|
||
var doc = GetComponent<UIDocument>();
|
||
if (doc == null)
|
||
{
|
||
Debug.LogError("UIDocument가 할당되지 않았습니다.");
|
||
return;
|
||
}
|
||
uiDocument = doc;
|
||
|
||
var toggle = uiDocument.rootVisualElement.Q<UTKToggle>("toggle");
|
||
if (toggle == null)
|
||
{
|
||
Debug.LogError("UXML에서 UTKToggle을 찾을 수 없습니다.");
|
||
return;
|
||
}
|
||
_themeToggle = toggle;
|
||
|
||
var window = uiDocument.rootVisualElement.Q<UTKAccordionListWindow>("window");
|
||
if (window == null)
|
||
{
|
||
Debug.LogError("UXML에서 UTKAccordionListWindow를 찾을 수 없습니다.");
|
||
return;
|
||
}
|
||
_accordionWindow = window;
|
||
|
||
UTKThemeManager.Instance.RegisterRoot(uiDocument.rootVisualElement);
|
||
UTKThemeManager.Instance.SetTheme(initialTheme);
|
||
|
||
_themeToggle.OnValueChanged += (isOn) =>
|
||
{
|
||
UTKThemeManager.Instance.SetTheme(!isOn ? UTKTheme.Dark : UTKTheme.Light);
|
||
};
|
||
|
||
// UTKAccordionListWindow 인스턴스 생성 및 추가
|
||
_accordionWindow.ShowDragGhost = showDragGhost;
|
||
_accordionWindow.Title = "ACCORDION";
|
||
_accordionWindow.ShowCloseButton = true;
|
||
|
||
// 테스트 데이터 생성
|
||
CreateTestData();
|
||
|
||
// 이벤트 핸들러 등록
|
||
RegisterEventHandlers();
|
||
|
||
Debug.Log("[UTKAccordionListWindowSample] 초기화 완료");
|
||
}
|
||
|
||
private void OnDestroy()
|
||
{
|
||
// 3D 프리뷰 정리
|
||
Destroy3DPreview();
|
||
|
||
// 리소스 정리
|
||
_accordionWindow?.Dispose();
|
||
_accordionWindow = null;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 테스트 데이터 생성
|
||
|
||
/// <summary>
|
||
/// 테스트용 아코디언 데이터를 생성합니다.
|
||
/// AccordionSample과 동일한 구조로 데이터를 생성합니다.
|
||
/// </summary>
|
||
private void CreateTestData()
|
||
{
|
||
if (_accordionWindow == null) return;
|
||
|
||
var data = new UTKAccordionData();
|
||
|
||
// ========================================
|
||
// 수평 레이아웃 섹션 1: Settings
|
||
// ========================================
|
||
var settingsSection = new UTKAccordionSectionData
|
||
{
|
||
Title = "Settings",
|
||
IsExpanded = true,
|
||
LayoutType = UTKAccordionLayoutType.Horizontal,
|
||
HorizontalItems = new List<UTKAccordionHorizontalItemData>
|
||
{
|
||
new UTKAccordionHorizontalItemData
|
||
{
|
||
Head = UTKAccordionContentSpec.FromImage("Prefabs/UI/images/icon_side_tab_library_24"),
|
||
Content = UTKAccordionContentSpec.FromText("Graphics", "open_graphics"),
|
||
Tail = new List<UTKAccordionContentSpec>
|
||
{
|
||
UTKAccordionContentSpec.FromIconButton(UTKMaterialIcons.Refresh, 12, "refresh_graphics", "새로고침"),
|
||
UTKAccordionContentSpec.FromIconButton(UTKMaterialIcons.Settings, 12, "setting_graphics", "설정"),
|
||
}
|
||
},
|
||
new UTKAccordionHorizontalItemData
|
||
{
|
||
Head = UTKAccordionContentSpec.FromImage("Prefabs/UI/images/icon_side_tab_fleet_128"),
|
||
Content = UTKAccordionContentSpec.FromText("Audio", "open_audio"),
|
||
Tail = new List<UTKAccordionContentSpec>
|
||
{
|
||
UTKAccordionContentSpec.FromIconButton(UTKMaterialIcons.Refresh, 12, "refresh_audio", "새로고침"),
|
||
UTKAccordionContentSpec.FromIconButton(UTKMaterialIcons.Settings, 12, "setting_audio", "설정"),
|
||
}
|
||
},
|
||
new UTKAccordionHorizontalItemData
|
||
{
|
||
Head = UTKAccordionContentSpec.FromImage("Prefabs/UI/images/icon_side_tab_explorer_24"),
|
||
Content = UTKAccordionContentSpec.FromText("Network", "open_network"),
|
||
Tail = new List<UTKAccordionContentSpec>
|
||
{
|
||
UTKAccordionContentSpec.FromIconButton(UTKMaterialIcons.Refresh, 12, "refresh_network", "새로고침"),
|
||
}
|
||
}
|
||
}
|
||
};
|
||
data.Sections.Add(settingsSection);
|
||
|
||
// ========================================
|
||
// 수평 레이아웃 섹션 2: Components
|
||
// ========================================
|
||
var componentsSection = new UTKAccordionSectionData
|
||
{
|
||
Title = "Components",
|
||
IsExpanded = false,
|
||
LayoutType = UTKAccordionLayoutType.Horizontal,
|
||
HorizontalItems = new List<UTKAccordionHorizontalItemData>
|
||
{
|
||
new UTKAccordionHorizontalItemData
|
||
{
|
||
Content = UTKAccordionContentSpec.FromText("Transform", "open_transform"),
|
||
},
|
||
new UTKAccordionHorizontalItemData
|
||
{
|
||
Content = UTKAccordionContentSpec.FromText("Rigidbody", "open_rigidbody"),
|
||
},
|
||
new UTKAccordionHorizontalItemData
|
||
{
|
||
Content = UTKAccordionContentSpec.FromText("Collider", "open_collider"),
|
||
}
|
||
}
|
||
};
|
||
data.Sections.Add(componentsSection);
|
||
|
||
// ========================================
|
||
// 그리드 레이아웃 섹션 1: Vehicles
|
||
// ========================================
|
||
var vehiclesSection = new UTKAccordionSectionData
|
||
{
|
||
Title = "Vehicles",
|
||
IsExpanded = true,
|
||
LayoutType = UTKAccordionLayoutType.Grid,
|
||
GridItems = new List<UTKAccordionGridItemData>
|
||
{
|
||
new UTKAccordionGridItemData
|
||
{
|
||
Caption = "Forklift",
|
||
ImagePath = "Simulator/Images/lib_forklift_400x300",
|
||
PrefabPath = "Simulator/FreeForkLift/Prefabs/Forklift",
|
||
Tag = "vehicle"
|
||
},
|
||
new UTKAccordionGridItemData
|
||
{
|
||
Caption = "Truck",
|
||
ImagePath = "Simulator/Images/lib_forklift_400x300",
|
||
PrefabPath = "Simulator/FreeForkLift/Prefabs/Forklift",
|
||
Tag = "vehicle"
|
||
}
|
||
}
|
||
};
|
||
data.Sections.Add(vehiclesSection);
|
||
|
||
// ========================================
|
||
// 그리드 레이아웃 섹션 2: Objects
|
||
// ========================================
|
||
var objectsSection = new UTKAccordionSectionData
|
||
{
|
||
Title = "Objects",
|
||
IsExpanded = true,
|
||
LayoutType = UTKAccordionLayoutType.Grid,
|
||
GridItems = new List<UTKAccordionGridItemData>
|
||
{
|
||
new UTKAccordionGridItemData
|
||
{
|
||
Caption = "Pallet",
|
||
ImagePath = "Simulator/Images/lib_pallet_400x300",
|
||
PrefabPath = "Simulator/FreeForkLift/Prefabs/PalletEmpty",
|
||
Tag = "object"
|
||
},
|
||
new UTKAccordionGridItemData
|
||
{
|
||
Caption = "Pallet (Full)",
|
||
ImagePath = "Simulator/Images/lib_pallet_400x300",
|
||
PrefabPath = "Simulator/FreeForkLift/Prefabs/PalletEmpty",
|
||
Tag = "object"
|
||
},
|
||
new UTKAccordionGridItemData
|
||
{
|
||
Caption = "Box",
|
||
ImagePath = "Simulator/Images/lib_pallet_400x300",
|
||
PrefabPath = "Simulator/FreeForkLift/Prefabs/PalletEmpty",
|
||
Tag = "object"
|
||
}
|
||
}
|
||
};
|
||
data.Sections.Add(objectsSection);
|
||
|
||
// ========================================
|
||
// 그리드 레이아웃 섹션 3: Characters
|
||
// ========================================
|
||
var charactersSection = new UTKAccordionSectionData
|
||
{
|
||
Title = "Characters",
|
||
IsExpanded = true,
|
||
LayoutType = UTKAccordionLayoutType.Grid,
|
||
GridItems = new List<UTKAccordionGridItemData>
|
||
{
|
||
new UTKAccordionGridItemData
|
||
{
|
||
Caption = "Worker",
|
||
ImagePath = "Simulator/Images/lib_worker_400x300",
|
||
PrefabPath = "Simulator/CharCrafter – Free Preset Characters Pack (Vol. 1)/Prefabs/Male Young Guy",
|
||
Tag = "character"
|
||
},
|
||
new UTKAccordionGridItemData
|
||
{
|
||
Caption = "Manager",
|
||
ImagePath = "Simulator/Images/lib_worker_400x300",
|
||
PrefabPath = "Simulator/CharCrafter – Free Preset Characters Pack (Vol. 1)/Prefabs/Male Young Guy",
|
||
Tag = "character"
|
||
}
|
||
}
|
||
};
|
||
data.Sections.Add(charactersSection);
|
||
|
||
// 데이터 설정
|
||
_accordionWindow.SetData(data);
|
||
|
||
Debug.Log($"[UTKAccordionListWindowSample] 테스트 데이터 생성 완료: {data.Sections.Count}개 섹션");
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 이벤트 핸들러 등록
|
||
|
||
/// <summary>
|
||
/// UTKAccordionListWindow의 이벤트 핸들러들을 등록합니다.
|
||
/// </summary>
|
||
private void RegisterEventHandlers()
|
||
{
|
||
if (_accordionWindow == null) return;
|
||
|
||
// ========================================
|
||
// 수평 아이템 이벤트
|
||
// ========================================
|
||
|
||
// 수평 아이템 클릭 이벤트
|
||
_accordionWindow.OnHorizontalItemClick += (item, contentSpec) =>
|
||
{
|
||
var text = contentSpec?.Text ?? item.Content?.Text ?? "Unknown";
|
||
var actionId = contentSpec?.ActionId ?? "none";
|
||
Debug.Log($"[수평 아이템 클릭] {text} (ActionId: {actionId})");
|
||
|
||
// ActionId에 따라 분기 처리
|
||
HandleHorizontalItemAction(actionId);
|
||
};
|
||
|
||
// 수평 아이템 아이콘 버튼 클릭 이벤트
|
||
_accordionWindow.OnHorizontalItemIconClick += (item, iconSpec) =>
|
||
{
|
||
var actionId = iconSpec.ActionId ?? "none";
|
||
var itemText = item.Content?.Text ?? "Unknown";
|
||
Debug.Log($"[아이콘 버튼 클릭] {itemText} - {actionId}");
|
||
|
||
HandleHorizontalItemAction(actionId);
|
||
};
|
||
|
||
// ========================================
|
||
// 그리드 아이템 이벤트
|
||
// ========================================
|
||
|
||
// 그리드 아이템 클릭 이벤트
|
||
_accordionWindow.OnGridItemClick += (item) =>
|
||
{
|
||
Debug.Log($"[그리드 아이템 클릭] {item.Caption} (Tag: {item.Tag})");
|
||
};
|
||
|
||
// 드래그 시작 이벤트
|
||
_accordionWindow.OnGridItemBeginDrag += (item, position) =>
|
||
{
|
||
Debug.Log($"[드래그 시작] {item.Caption} at {position}");
|
||
};
|
||
|
||
// 드래그 중 이벤트
|
||
_accordionWindow.OnGridItemDrag += (item, position) =>
|
||
{
|
||
// 3D 프리뷰가 있으면 위치 업데이트
|
||
if (_dragPreview3D != null)
|
||
{
|
||
Update3DPreviewPosition(position);
|
||
}
|
||
};
|
||
|
||
// 드래그 종료 이벤트
|
||
_accordionWindow.OnGridItemEndDrag += (item, position) =>
|
||
{
|
||
Debug.Log($"[드래그 종료] {item.Caption} at {position}");
|
||
_lastDropScreenPosition = position;
|
||
// 드롭 이벤트에서 처리하므로 여기서는 프리뷰를 제거하지 않음
|
||
};
|
||
|
||
// 리스트 영역 이탈 이벤트 (3D 프리팹 미리보기 표시)
|
||
_accordionWindow.OnDragExitList += (item, position) =>
|
||
{
|
||
Debug.Log($"[리스트 영역 이탈] {item.Caption} - 3D 프리뷰 생성");
|
||
_isOutsideListArea = true;
|
||
Create3DPreview(item, position);
|
||
};
|
||
|
||
// 리스트 영역 진입 이벤트 (3D 프리팹 미리보기 숨김)
|
||
_accordionWindow.OnDragEnterList += (item, position) =>
|
||
{
|
||
Debug.Log($"[리스트 영역 진입] {item.Caption} - 3D 프리뷰 제거");
|
||
_isOutsideListArea = false;
|
||
Destroy3DPreview();
|
||
};
|
||
|
||
// 그리드 아이템 드롭 이벤트
|
||
_accordionWindow.OnGridItemDrop += (item) =>
|
||
{
|
||
Debug.Log($"[드롭] {item.Caption} - PrefabPath: {item.PrefabPath}, Outside: {_isOutsideListArea}");
|
||
|
||
// 리스트 영역 밖에서 드롭한 경우에만 프리팹 생성
|
||
if (!_isOutsideListArea)
|
||
{
|
||
Debug.Log("[UTKAccordionListWindowSample] 리스트 영역 내부에서 드롭 - 프리팹 생성 안함");
|
||
_isOutsideListArea = false;
|
||
return;
|
||
}
|
||
|
||
if (string.IsNullOrEmpty(item.PrefabPath))
|
||
{
|
||
Debug.LogWarning("[UTKAccordionListWindowSample] PrefabPath가 설정되지 않았습니다.");
|
||
Destroy3DPreview();
|
||
_isOutsideListArea = false;
|
||
return;
|
||
}
|
||
|
||
// 프리팹 로드
|
||
var prefab = Resources.Load<GameObject>(item.PrefabPath);
|
||
if (prefab == null)
|
||
{
|
||
Debug.LogWarning($"[UTKAccordionListWindowSample] 프리팹을 찾을 수 없습니다: {item.PrefabPath}");
|
||
Destroy3DPreview();
|
||
_isOutsideListArea = false;
|
||
return;
|
||
}
|
||
|
||
// 월드 좌표 계산
|
||
Vector3 worldPosition = ScreenToWorldPosition(_lastDropScreenPosition);
|
||
|
||
// 프리팹 인스턴스화
|
||
var instance = Instantiate(prefab, worldPosition, Quaternion.identity);
|
||
Debug.Log($"[UTKAccordionListWindowSample] 프리팹 생성됨: {instance.name} at {worldPosition}");
|
||
|
||
// 3D 프리뷰 정리 및 상태 초기화
|
||
Destroy3DPreview();
|
||
_isOutsideListArea = false;
|
||
};
|
||
|
||
// ========================================
|
||
// 섹션 이벤트
|
||
// ========================================
|
||
|
||
// 섹션 펼침/접힘 이벤트
|
||
_accordionWindow.OnSectionToggled += (section, isExpanded) =>
|
||
{
|
||
Debug.Log($"[섹션 토글] {section.Title} - {(isExpanded ? "펼침" : "접힘")}");
|
||
};
|
||
|
||
// ========================================
|
||
// 윈도우 이벤트
|
||
// ========================================
|
||
|
||
// 윈도우 닫기 이벤트
|
||
_accordionWindow.OnClosed += () =>
|
||
{
|
||
Debug.Log("[윈도우 닫힘]");
|
||
};
|
||
|
||
Debug.Log("[UTKAccordionListWindowSample] 이벤트 핸들러 등록 완료");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 수평 아이템의 ActionId에 따라 동작을 처리합니다.
|
||
/// </summary>
|
||
private void HandleHorizontalItemAction(string? actionId)
|
||
{
|
||
switch (actionId)
|
||
{
|
||
case "open_graphics":
|
||
Debug.Log(" → Graphics 설정 열기");
|
||
break;
|
||
case "refresh_graphics":
|
||
Debug.Log(" → Graphics 새로고침");
|
||
break;
|
||
case "setting_graphics":
|
||
Debug.Log(" → Graphics 상세 설정");
|
||
break;
|
||
case "open_audio":
|
||
Debug.Log(" → Audio 설정 열기");
|
||
break;
|
||
case "refresh_audio":
|
||
Debug.Log(" → Audio 새로고침");
|
||
break;
|
||
case "setting_audio":
|
||
Debug.Log(" → Audio 상세 설정");
|
||
break;
|
||
case "open_network":
|
||
Debug.Log(" → Network 설정 열기");
|
||
break;
|
||
case "refresh_network":
|
||
Debug.Log(" → Network 새로고침");
|
||
break;
|
||
case "open_transform":
|
||
Debug.Log(" → Transform 컴포넌트 열기");
|
||
break;
|
||
case "open_rigidbody":
|
||
Debug.Log(" → Rigidbody 컴포넌트 열기");
|
||
break;
|
||
case "open_collider":
|
||
Debug.Log(" → Collider 컴포넌트 열기");
|
||
break;
|
||
default:
|
||
Debug.Log($" → 알 수 없는 액션: {actionId}");
|
||
break;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 좌표 변환 (Coordinate Conversion)
|
||
|
||
/// <summary>
|
||
/// UI Toolkit 좌표를 Unity Screen 좌표로 변환합니다.
|
||
/// </summary>
|
||
private Vector2 UIToolkitToScreenPosition(Vector2 uiToolkitPosition)
|
||
{
|
||
return new Vector2(uiToolkitPosition.x, Screen.height - uiToolkitPosition.y);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 스크린 좌표를 월드 좌표로 변환합니다.
|
||
/// </summary>
|
||
private Vector3 ScreenToWorldPosition(Vector2 uiToolkitPosition)
|
||
{
|
||
_mainCamera ??= Camera.main;
|
||
if (_mainCamera == null)
|
||
{
|
||
Debug.LogWarning("[UTKAccordionListWindowSample] 메인 카메라를 찾을 수 없습니다.");
|
||
return Vector3.zero;
|
||
}
|
||
|
||
Vector2 screenPosition = UIToolkitToScreenPosition(uiToolkitPosition);
|
||
Ray ray = _mainCamera.ScreenPointToRay(screenPosition);
|
||
|
||
// 바닥면(Y=0)과의 교차점 계산
|
||
Plane groundPlane = new Plane(Vector3.up, Vector3.zero);
|
||
if (groundPlane.Raycast(ray, out float distance))
|
||
{
|
||
return ray.GetPoint(distance);
|
||
}
|
||
|
||
// 물리 레이캐스트
|
||
if (Physics.Raycast(ray, out RaycastHit hit, 100f))
|
||
{
|
||
return hit.point;
|
||
}
|
||
|
||
return ray.GetPoint(10f);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 3D 프리뷰 (3D Preview)
|
||
|
||
/// <summary>
|
||
/// 드래그 중 3D 프리뷰 오브젝트를 생성합니다.
|
||
/// </summary>
|
||
private void Create3DPreview(UTKAccordionGridItemData item, Vector2 screenPosition)
|
||
{
|
||
Destroy3DPreview();
|
||
|
||
if (string.IsNullOrEmpty(item.PrefabPath)) return;
|
||
|
||
var prefab = Resources.Load<GameObject>(item.PrefabPath);
|
||
if (prefab == null)
|
||
{
|
||
Debug.LogWarning($"[UTKAccordionListWindowSample] 프리팹을 찾을 수 없습니다: {item.PrefabPath}");
|
||
return;
|
||
}
|
||
|
||
Vector3 worldPosition = ScreenToWorldPosition(screenPosition);
|
||
_dragPreview3D = Instantiate(prefab, worldPosition, Quaternion.identity);
|
||
_dragPreview3D.name = $"DragPreview_{item.Caption}";
|
||
|
||
SetPreviewTransparency(_dragPreview3D, 0.6f);
|
||
DisableColliders(_dragPreview3D);
|
||
|
||
Debug.Log($"[UTKAccordionListWindowSample] 3D 프리뷰 생성됨: {_dragPreview3D.name} at {worldPosition}");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 3D 프리뷰 오브젝트를 제거합니다.
|
||
/// </summary>
|
||
private void Destroy3DPreview()
|
||
{
|
||
if (_dragPreview3D != null)
|
||
{
|
||
Destroy(_dragPreview3D);
|
||
_dragPreview3D = null;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 3D 프리뷰 오브젝트의 위치를 업데이트합니다.
|
||
/// </summary>
|
||
private void Update3DPreviewPosition(Vector2 screenPosition)
|
||
{
|
||
if (_dragPreview3D == null) return;
|
||
_dragPreview3D.transform.position = ScreenToWorldPosition(screenPosition);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 오브젝트의 모든 렌더러를 반투명하게 설정합니다.
|
||
/// </summary>
|
||
private void SetPreviewTransparency(GameObject obj, float alpha)
|
||
{
|
||
var renderers = obj.GetComponentsInChildren<Renderer>();
|
||
foreach (var renderer in renderers)
|
||
{
|
||
foreach (var material in renderer.materials)
|
||
{
|
||
if (material.HasProperty("_Color"))
|
||
{
|
||
var color = material.color;
|
||
color.a = alpha;
|
||
material.color = color;
|
||
|
||
material.SetFloat("_Mode", 3);
|
||
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
|
||
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
|
||
material.SetInt("_ZWrite", 0);
|
||
material.DisableKeyword("_ALPHATEST_ON");
|
||
material.EnableKeyword("_ALPHABLEND_ON");
|
||
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
||
material.renderQueue = 3000;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 오브젝트의 모든 콜라이더를 비활성화합니다.
|
||
/// </summary>
|
||
private void DisableColliders(GameObject obj)
|
||
{
|
||
var colliders = obj.GetComponentsInChildren<Collider>();
|
||
foreach (var collider in colliders)
|
||
{
|
||
collider.enabled = false;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 에디터 테스트용 메서드
|
||
|
||
/// <summary>
|
||
/// 모든 섹션을 펼칩니다.
|
||
/// </summary>
|
||
[ContextMenu("Expand All Sections")]
|
||
public void ExpandAllSections()
|
||
{
|
||
_accordionWindow?.ExpandAll();
|
||
Debug.Log("[UTKAccordionListWindowSample] 모든 섹션 펼침");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 모든 섹션을 접습니다.
|
||
/// </summary>
|
||
[ContextMenu("Collapse All Sections")]
|
||
public void CollapseAllSections()
|
||
{
|
||
_accordionWindow?.CollapseAll();
|
||
Debug.Log("[UTKAccordionListWindowSample] 모든 섹션 접힘");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 검색을 테스트합니다.
|
||
/// </summary>
|
||
[ContextMenu("Test Search (Pallet)")]
|
||
public void TestSearch()
|
||
{
|
||
_accordionWindow?.Search("Pallet");
|
||
Debug.Log("[UTKAccordionListWindowSample] 검색 테스트: 'Pallet'");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 검색을 초기화합니다.
|
||
/// </summary>
|
||
[ContextMenu("Clear Search")]
|
||
public void ClearSearchTest()
|
||
{
|
||
_accordionWindow?.ClearSearch();
|
||
Debug.Log("[UTKAccordionListWindowSample] 검색 초기화");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 모든 데이터를 제거합니다.
|
||
/// </summary>
|
||
[ContextMenu("Clear All Data")]
|
||
public void ClearAllData()
|
||
{
|
||
_accordionWindow?.Clear();
|
||
Debug.Log("[UTKAccordionListWindowSample] 모든 데이터 제거됨");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 윈도우를 다시 표시합니다.
|
||
/// </summary>
|
||
[ContextMenu("Show Window")]
|
||
public void ShowWindow()
|
||
{
|
||
_accordionWindow?.Show();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 데이터를 다시 로드합니다.
|
||
/// </summary>
|
||
[ContextMenu("Reload Data")]
|
||
public void ReloadData()
|
||
{
|
||
CreateTestData();
|
||
Debug.Log("[UTKAccordionListWindowSample] 데이터 다시 로드됨");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 새로운 통합 API(UTKAccordionItemData)를 사용하여 데이터를 생성합니다.
|
||
/// TreeView 기반 구현에 최적화된 데이터 구조입니다.
|
||
/// </summary>
|
||
[ContextMenu("Load Data (New API)")]
|
||
public void LoadDataWithNewAPI()
|
||
{
|
||
if (_accordionWindow == null) return;
|
||
|
||
var roots = new List<UTKAccordionItemData>();
|
||
|
||
// ========================================
|
||
// 섹션 1: Settings (수평 레이아웃)
|
||
// ========================================
|
||
var settingsSection = UTKAccordionItemData.CreateSection("Settings", isExpanded: true);
|
||
settingsSection
|
||
.AddHorizontalItem(
|
||
head: UTKAccordionContentSpec.FromImage("Prefabs/UI/images/icon_side_tab_library_128"),
|
||
content: UTKAccordionContentSpec.FromText("Graphics", "open_graphics"),
|
||
tail: new List<UTKAccordionContentSpec>
|
||
{
|
||
UTKAccordionContentSpec.FromIconButton(UTKMaterialIcons.Refresh, 12, "refresh_graphics", "새로고침"),
|
||
UTKAccordionContentSpec.FromIconButton(UTKMaterialIcons.Settings, 12, "setting_graphics", "설정"),
|
||
})
|
||
.AddHorizontalItem(
|
||
head: UTKAccordionContentSpec.FromImage("Prefabs/UI/images/icon_side_tab_fleet_128"),
|
||
content: UTKAccordionContentSpec.FromText("Audio", "open_audio"),
|
||
tail: new List<UTKAccordionContentSpec>
|
||
{
|
||
UTKAccordionContentSpec.FromIconButton(UTKMaterialIcons.Refresh, 12, "refresh_audio", "새로고침"),
|
||
});
|
||
roots.Add(settingsSection);
|
||
|
||
// ========================================
|
||
// 섹션 2: Vehicles (그리드 레이아웃)
|
||
// ========================================
|
||
var vehiclesSection = UTKAccordionItemData.CreateSection("Vehicles", isExpanded: true);
|
||
vehiclesSection
|
||
.AddGridItem("Forklift", "Simulator/Images/lib_forklift_400x300", "Simulator/FreeForkLift/Prefabs/Forklift", "vehicle")
|
||
.AddGridItem("Truck", "Simulator/Images/lib_forklift_400x300", "Simulator/FreeForkLift/Prefabs/Forklift", "vehicle");
|
||
roots.Add(vehiclesSection);
|
||
|
||
// ========================================
|
||
// 섹션 3: Objects (그리드 레이아웃)
|
||
// ========================================
|
||
var objectsSection = UTKAccordionItemData.CreateSection("Objects", isExpanded: true);
|
||
objectsSection
|
||
.AddGridItem("Pallet", "Simulator/Images/lib_pallet_400x300", "Simulator/FreeForkLift/Prefabs/PalletEmpty", "object")
|
||
.AddGridItem("Box", "Simulator/Images/lib_pallet_400x300", "Simulator/FreeForkLift/Prefabs/PalletEmpty", "object");
|
||
roots.Add(objectsSection);
|
||
|
||
// 새로운 통합 API로 데이터 설정
|
||
_accordionWindow.SetData(roots);
|
||
|
||
Debug.Log($"[UTKAccordionListWindowSample] 새 API로 데이터 생성 완료: {roots.Count}개 섹션");
|
||
}
|
||
|
||
#endregion
|
||
}
|