diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index b55a07ed..c4f9046b 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -6,7 +6,9 @@
"Bash(mkdir:*)",
"Bash(cat:*)",
"Bash(move:*)",
- "Bash(find:*)"
+ "Bash(find:*)",
+ "Bash(claude mcp add:*)",
+ "Bash(claude mcp list:*)"
],
"deny": [],
"ask": []
diff --git a/.mcp.json b/.mcp.json
new file mode 100644
index 00000000..4b68a134
--- /dev/null
+++ b/.mcp.json
@@ -0,0 +1,8 @@
+{
+ "mcpServers": {
+ "UnityMCP": {
+ "type": "http",
+ "url": "http://localhost:8080/mcp"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/Resources/Prefabs/UI/List/ComponentListItem.prefab b/Assets/Resources/Prefabs/UI/List/ComponentListItem.prefab
index 0af9ebaf..3123d53e 100644
--- a/Assets/Resources/Prefabs/UI/List/ComponentListItem.prefab
+++ b/Assets/Resources/Prefabs/UI/List/ComponentListItem.prefab
@@ -37,8 +37,8 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
- m_AnchoredPosition: {x: 24.000008, y: -3.5}
- m_SizeDelta: {x: 0, y: 15}
+ m_AnchoredPosition: {x: 24, y: -3.5}
+ m_SizeDelta: {x: 16.79, y: 15}
m_Pivot: {x: 0, y: 1}
--- !u!222 &1821424897527179892
CanvasRenderer:
@@ -667,10 +667,10 @@ RectTransform:
m_Children: []
m_Father: {fileID: 3094276047947572059}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
- 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_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_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &7899941541401797984
MonoBehaviour:
@@ -1418,7 +1418,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
- m_IsActive: 1
+ m_IsActive: 0
--- !u!224 &3186561737559845992
RectTransform:
m_ObjectHideFlags: 0
@@ -1635,7 +1635,7 @@ RectTransform:
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_SizeDelta: {x: 40.79, y: 22}
m_Pivot: {x: 1, y: 0.5}
--- !u!114 &4840481829667430247
MonoBehaviour:
@@ -2163,10 +2163,10 @@ RectTransform:
m_Children: []
m_Father: {fileID: 5465326936975101749}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
- 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_AnchorMin: {x: 0, y: 1}
+ m_AnchorMax: {x: 0, y: 1}
+ m_AnchoredPosition: {x: 11, y: -11}
+ m_SizeDelta: {x: 22, y: 22}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &4173370272032766120
CanvasRenderer:
diff --git a/Assets/Resources/UIToolkit/Images/icon_down_20x16.png b/Assets/Resources/UIToolkit/Images/icon_down_20x16.png
new file mode 100644
index 00000000..af3f30c4
Binary files /dev/null and b/Assets/Resources/UIToolkit/Images/icon_down_20x16.png differ
diff --git a/Assets/Resources/UIToolkit/Images/icon_search_16x17.png.meta b/Assets/Resources/UIToolkit/Images/icon_down_20x16.png.meta
similarity index 98%
rename from Assets/Resources/UIToolkit/Images/icon_search_16x17.png.meta
rename to Assets/Resources/UIToolkit/Images/icon_down_20x16.png.meta
index 80ec6f05..ac1e4f4a 100644
--- a/Assets/Resources/UIToolkit/Images/icon_search_16x17.png.meta
+++ b/Assets/Resources/UIToolkit/Images/icon_down_20x16.png.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 4737b068c8483f348aef876954e2afee
+guid: 07ba9c8b4566e80489abb0991b24b01d
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
diff --git a/Assets/Resources/UIToolkit/Images/icon_down_22.png b/Assets/Resources/UIToolkit/Images/icon_down_22.png
new file mode 100644
index 00000000..edaa47a7
Binary files /dev/null and b/Assets/Resources/UIToolkit/Images/icon_down_22.png differ
diff --git a/Assets/Resources/UIToolkit/Images/icon_down_22.png.meta b/Assets/Resources/UIToolkit/Images/icon_down_22.png.meta
new file mode 100644
index 00000000..d806a855
--- /dev/null
+++ b/Assets/Resources/UIToolkit/Images/icon_down_22.png.meta
@@ -0,0 +1,117 @@
+fileFormatVersion: 2
+guid: 68290a8f5e2d8bc46ad9e1fb9df69ac6
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 13
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ flipGreenChannel: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ vTOnly: 0
+ ignoreMipmapLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 0
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 1
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 1
+ spriteTessellationDetail: -1
+ textureType: 8
+ textureShape: 1
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 0
+ applyGammaDecoding: 0
+ swizzle: 50462976
+ cookieLightType: 0
+ platformSettings:
+ - serializedVersion: 4
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 32
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 4
+ buildTarget: Standalone
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ customData:
+ physicsShape: []
+ bones: []
+ spriteID: 5e97eb03825dee720800000000000000
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ spriteCustomMetadata:
+ entries: []
+ nameFileIdTable: {}
+ mipmapLimitGroupName:
+ pSDRemoveMatte: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Resources/UIToolkit/Images/icon_eye_22x16.png b/Assets/Resources/UIToolkit/Images/icon_eye_22x16.png
new file mode 100644
index 00000000..d0b70812
Binary files /dev/null and b/Assets/Resources/UIToolkit/Images/icon_eye_22x16.png differ
diff --git a/Assets/Resources/UIToolkit/Images/icon_eye_22x16.png.meta b/Assets/Resources/UIToolkit/Images/icon_eye_22x16.png.meta
new file mode 100644
index 00000000..2a1fe028
--- /dev/null
+++ b/Assets/Resources/UIToolkit/Images/icon_eye_22x16.png.meta
@@ -0,0 +1,143 @@
+fileFormatVersion: 2
+guid: e6a78b3026893f24abf05bfd5c515bcf
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 13
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ flipGreenChannel: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ vTOnly: 0
+ ignoreMipmapLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 0
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 1
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 1
+ spriteTessellationDetail: -1
+ textureType: 8
+ textureShape: 1
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 0
+ applyGammaDecoding: 0
+ swizzle: 50462976
+ cookieLightType: 0
+ platformSettings:
+ - serializedVersion: 4
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 32
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 4
+ buildTarget: Standalone
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 4
+ buildTarget: WebGL
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 4
+ buildTarget: WindowsStoreApps
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ customData:
+ physicsShape: []
+ bones: []
+ spriteID: 5e97eb03825dee720800000000000000
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ spriteCustomMetadata:
+ entries: []
+ nameFileIdTable: {}
+ mipmapLimitGroupName:
+ pSDRemoveMatte: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Resources/UIToolkit/Images/icon_eye_close_22x16.png b/Assets/Resources/UIToolkit/Images/icon_eye_close_22x16.png
new file mode 100644
index 00000000..b375f521
Binary files /dev/null and b/Assets/Resources/UIToolkit/Images/icon_eye_close_22x16.png differ
diff --git a/Assets/Resources/UIToolkit/Images/icon_eye_close_22x16.png.meta b/Assets/Resources/UIToolkit/Images/icon_eye_close_22x16.png.meta
new file mode 100644
index 00000000..e526d7bb
--- /dev/null
+++ b/Assets/Resources/UIToolkit/Images/icon_eye_close_22x16.png.meta
@@ -0,0 +1,143 @@
+fileFormatVersion: 2
+guid: 98d19f50484d3cf458835c97a645b838
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 13
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ flipGreenChannel: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ vTOnly: 0
+ ignoreMipmapLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 0
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 1
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 1
+ spriteTessellationDetail: -1
+ textureType: 8
+ textureShape: 1
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 0
+ applyGammaDecoding: 0
+ swizzle: 50462976
+ cookieLightType: 0
+ platformSettings:
+ - serializedVersion: 4
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 32
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 4
+ buildTarget: Standalone
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 4
+ buildTarget: WebGL
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 4
+ buildTarget: WindowsStoreApps
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ customData:
+ physicsShape: []
+ bones: []
+ spriteID: 5e97eb03825dee720800000000000000
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ spriteCustomMetadata:
+ entries: []
+ nameFileIdTable: {}
+ mipmapLimitGroupName:
+ pSDRemoveMatte: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Resources/UIToolkit/Images/icon_search_16x17.png b/Assets/Resources/UIToolkit/Images/icon_search_16x17.png
deleted file mode 100644
index 96b276f8..00000000
Binary files a/Assets/Resources/UIToolkit/Images/icon_search_16x17.png and /dev/null differ
diff --git a/Assets/Resources/UIToolkit/Images/icon_search_22x16.png b/Assets/Resources/UIToolkit/Images/icon_search_22x16.png
new file mode 100644
index 00000000..73ae4573
Binary files /dev/null and b/Assets/Resources/UIToolkit/Images/icon_search_22x16.png differ
diff --git a/Assets/Resources/UIToolkit/Images/icon_search_22x16.png.meta b/Assets/Resources/UIToolkit/Images/icon_search_22x16.png.meta
new file mode 100644
index 00000000..d383d207
--- /dev/null
+++ b/Assets/Resources/UIToolkit/Images/icon_search_22x16.png.meta
@@ -0,0 +1,143 @@
+fileFormatVersion: 2
+guid: 42ee2462b3dbdc34c8c3aab7aae8c998
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 13
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ flipGreenChannel: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ vTOnly: 0
+ ignoreMipmapLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 0
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 1
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 1
+ spriteTessellationDetail: -1
+ textureType: 8
+ textureShape: 1
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 0
+ applyGammaDecoding: 0
+ swizzle: 50462976
+ cookieLightType: 0
+ platformSettings:
+ - serializedVersion: 4
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 32
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 4
+ buildTarget: Standalone
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 4
+ buildTarget: WebGL
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 4
+ buildTarget: WindowsStoreApps
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ customData:
+ physicsShape: []
+ bones: []
+ spriteID: 5e97eb03825dee720800000000000000
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ spriteCustomMetadata:
+ entries: []
+ nameFileIdTable: {}
+ mipmapLimitGroupName:
+ pSDRemoveMatte: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Resources/UIToolkit/Images/icon_setting_22.png b/Assets/Resources/UIToolkit/Images/icon_setting_22.png
new file mode 100644
index 00000000..d6b8d627
Binary files /dev/null and b/Assets/Resources/UIToolkit/Images/icon_setting_22.png differ
diff --git a/Assets/Resources/UIToolkit/Images/icon_setting_22.png.meta b/Assets/Resources/UIToolkit/Images/icon_setting_22.png.meta
new file mode 100644
index 00000000..398d8e4a
--- /dev/null
+++ b/Assets/Resources/UIToolkit/Images/icon_setting_22.png.meta
@@ -0,0 +1,143 @@
+fileFormatVersion: 2
+guid: 44dedbf997719db41a2ef719b0b7282f
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 13
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ flipGreenChannel: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ vTOnly: 0
+ ignoreMipmapLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 0
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 1
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 1
+ spriteTessellationDetail: -1
+ textureType: 8
+ textureShape: 1
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 0
+ applyGammaDecoding: 0
+ swizzle: 50462976
+ cookieLightType: 0
+ platformSettings:
+ - serializedVersion: 4
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 32
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 4
+ buildTarget: Standalone
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 4
+ buildTarget: WebGL
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 4
+ buildTarget: WindowsStoreApps
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ customData:
+ physicsShape: []
+ bones: []
+ spriteID: 5e97eb03825dee720800000000000000
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ spriteCustomMetadata:
+ entries: []
+ nameFileIdTable: {}
+ mipmapLimitGroupName:
+ pSDRemoveMatte: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Resources/UIToolkit/List/UTKComponentList.uss b/Assets/Resources/UIToolkit/List/UTKComponentList.uss
new file mode 100644
index 00000000..e1422931
--- /dev/null
+++ b/Assets/Resources/UIToolkit/List/UTKComponentList.uss
@@ -0,0 +1,45 @@
+.tree-menu-container {
+ background-color: rgb(37, 37, 38);
+ align-self: stretch;
+ padding: 5px;
+ padding-top: 0;
+ padding-right: 0;
+ padding-bottom: 0;
+ padding-left: 0;
+ flex-grow: 1;
+}
+
+.search-field {
+ margin-bottom: 20px;
+}
+
+#unity-checkmark {
+ background-image: resource('UIToolkit/Images/icon_down_22');
+}
+
+.visibility-toggle {
+ background-color: rgba(0, 0, 0, 0);
+ border-width: 0;
+ width: 16px;
+ height: 16px;
+ margin-top: 0;
+ margin-bottom: 0;
+ padding-top: 0;
+ padding-bottom: 0;
+ margin-right: 0;
+ align-items: center;
+ justify-content: center;
+ padding-right: 0;
+ padding-left: 0;
+ margin-left: 0;
+ flex-shrink: 0;
+ background-image: resource('UIToolkit/Images/icon_eye_22x16');
+}
+
+.visibility-on {
+ background-image: resource('UIToolkit/Images/icon_eye_22x16');
+}
+
+.visibility-off {
+ background-image: resource('UIToolkit/Images/icon_eye_close_22x16');
+}
diff --git a/Assets/Resources/UIToolkit/List/UTKComponentList.uss.meta b/Assets/Resources/UIToolkit/List/UTKComponentList.uss.meta
new file mode 100644
index 00000000..b3c38bcb
--- /dev/null
+++ b/Assets/Resources/UIToolkit/List/UTKComponentList.uss.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 71cac0276293ce2479851f572ffbda27
+ScriptedImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 2
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+ script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
+ disableValidation: 0
diff --git a/Assets/Resources/UIToolkit/List/UTKComponentList.uxml b/Assets/Resources/UIToolkit/List/UTKComponentList.uxml
new file mode 100644
index 00000000..77064fcc
--- /dev/null
+++ b/Assets/Resources/UIToolkit/List/UTKComponentList.uxml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/Assets/Resources/UIToolkit/List/UTKComponentList.uxml.meta b/Assets/Resources/UIToolkit/List/UTKComponentList.uxml.meta
new file mode 100644
index 00000000..d180a86a
--- /dev/null
+++ b/Assets/Resources/UIToolkit/List/UTKComponentList.uxml.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 0a221099d1761a543bfbbb334d020885
+ScriptedImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 2
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+ script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
diff --git a/Assets/Resources/UIToolkit/List/UTKComponentListGroupItem.uxml b/Assets/Resources/UIToolkit/List/UTKComponentListGroupItem.uxml
new file mode 100644
index 00000000..56d9df77
--- /dev/null
+++ b/Assets/Resources/UIToolkit/List/UTKComponentListGroupItem.uxml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/Assets/Resources/UIToolkit/List/UTKComponentListGroupItem.uxml.meta b/Assets/Resources/UIToolkit/List/UTKComponentListGroupItem.uxml.meta
new file mode 100644
index 00000000..ace62304
--- /dev/null
+++ b/Assets/Resources/UIToolkit/List/UTKComponentListGroupItem.uxml.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 4949994f0313f02459e91ec4e4144a9d
+ScriptedImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 2
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+ script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
diff --git a/Assets/Resources/UIToolkit/List/UTKComponentListItem.uxml b/Assets/Resources/UIToolkit/List/UTKComponentListItem.uxml
new file mode 100644
index 00000000..755d3c40
--- /dev/null
+++ b/Assets/Resources/UIToolkit/List/UTKComponentListItem.uxml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/Assets/Resources/UIToolkit/List/UTKComponentListItem.uxml.meta b/Assets/Resources/UIToolkit/List/UTKComponentListItem.uxml.meta
new file mode 100644
index 00000000..7f0f8978
--- /dev/null
+++ b/Assets/Resources/UIToolkit/List/UTKComponentListItem.uxml.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: ebc2d9ee974683b4794dc4b6e4c30ac0
+ScriptedImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 2
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+ script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
diff --git a/Assets/Resources/UIToolkit/List/UTKTreeListItem.uxml b/Assets/Resources/UIToolkit/List/UTKTreeListItem.uxml
index 4c708edf..1902b140 100644
--- a/Assets/Resources/UIToolkit/List/UTKTreeListItem.uxml
+++ b/Assets/Resources/UIToolkit/List/UTKTreeListItem.uxml
@@ -2,6 +2,6 @@
-
+
diff --git a/Assets/Resources/UIToolkit/Settings/UTKDefaultStyle.uss b/Assets/Resources/UIToolkit/Settings/UTKDefaultStyle.uss
index 64ed48e4..20a6f1d4 100644
--- a/Assets/Resources/UIToolkit/Settings/UTKDefaultStyle.uss
+++ b/Assets/Resources/UIToolkit/Settings/UTKDefaultStyle.uss
@@ -27,6 +27,21 @@
/* 스크롤바 트래커(배경) 색상 변수 (코드에서 참조) */
--scroller-tracker-normal: rgba(0, 0, 0, 0);
--scroller-tracker-hover: rgba(26, 26, 26, 0);
+
+ /* 일반 항목의 기본 배경색 #252526 */
+ --collection-item: rgba(37, 37, 38, 0);
+
+ /* 마우스 오버 시 배경색 변경 */
+ --collection-item-hover: #333333;
+
+ /* 선택된 항목의 배경색 */
+ --collection-item-selected: #0E639C;
+
+ /* 선택된 항목에 마우스 오버 시 배경색*/
+ --collection-item-selected-hover: #1176b9;
+
+ /* TreeView 들여쓰기 폭 설정 */
+ --unity-item-indent-width: 0px;
}
/* ===================================
@@ -56,28 +71,83 @@ TreeView 항목 스타일
/* TreeView 펼치기/접기 화살표 토글 - 우측 여백 추가 */
.unity-tree-view__item-toggle {
- margin-right: 5px;
+ margin-right: 0px;
+}
+
+#unity-checkmark {
+ -unity-background-image-tint-color: rgb(255, 255, 255);
+}
+
+#unity-tree-view__item-toggle > VisualElement > VisualElement {
+ margin-left: 0;
+ margin-right: 0;
+ width: 22px;
+}
+
+/* ===================================
+Textfield 항목 스타일
+=================================== */
+
+.unity-base-text-field {
+ border-radius: 4px;
+ height: 24px;
+ width: auto;
+ margin-top: 0;
+ margin-right: 0;
+ margin-left: 0;
+ -unity-font-definition: resource('Fonts/Pretendard/Pretendard-Medium');
+ /* --unity-selection-color: rgba(54, 98, 160, 0.651); 선택 색상 */
+ --unity-cursor-color: rgb(255, 255, 255); /* 캐럿(커서) 색상 흰색 */
+ font-size: 13px;
+ color: rgb(204, 204, 204);
+}
+
+ .unity-base-text-field__input {
+ padding-top: 4px;
+ padding-right: 24px;
+ padding-bottom: 4px;
+ padding-left: 4px;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+ border-top-width: 0;
+ border-right-width: 0;
+ border-bottom-width: 0;
+ border-left-width: 0;
+ background-color: rgb(60, 60, 60);
+}
+
+.unity-base-text-field__input--placeholder {
+ -unity-font-style: italic;
}
/* ===================================
컬렉션 뷰 항목 스타일
- ListView, TreeView 등 컬렉션 뷰의 항목 상태별 스타일
+- Unity 기본 테마 (.unity-collection-view:focus:enabled .unity-collection-view__item--selected)를
+ 덮어쓰기 위해 동일하거나 더 높은 specificity 사용
=================================== */
-/* 기본 상태 - 투명 배경 */
+/* 일반 항목의 기본 배경색 */
.unity-collection-view__item {
- background-color: rgba(50, 50, 50, 0);
+ background-color: var(--collection-item);
}
-/* 호버 상태 - 반투명 어두운 파란색 배경 */
-.unity-collection-view__item:hover {
- background-color: rgba(0, 10, 37, 0.25);
+/* 마우스 오버 시 배경색 변경 - :hover:enabled를 더 높은 specificity로 덮어씀 */
+.unity-collection-view__item:hover:enabled {
+ background-color: var(--collection-item-hover);
}
-/* 선택 상태 - 더 진한 반투명 어두운 파란색 배경 */
-.unity-collection-view__item--selected {
- background-color: rgba(0, 10, 37, 0.5);
+/* 선택된 항목의 배경색 - Unity 기본 테마의 :focus:enabled 셀렉터를 덮어씀 */
+.unity-collection-view:focus:enabled .unity-collection-view__item--selected {
+ background-color: var(--collection-item-selected);
+}
+
+/* 선택된 항목에 마우스 오버 시 배경색 - :hover:enabled를 더 높은 specificity로 덮어씀 */
+.unity-collection-view:focus:enabled .unity-collection-view__item--selected:hover:enabled {
+ background-color: var(--collection-item-selected-hover);
}
@@ -200,3 +270,5 @@ SetupDraggerEvents() 메서드처럼 코드로 MouseEnterEvent/MouseLeaveEvent
height: 6px;
min-height: 6px;
}
+
+
diff --git a/Assets/Resources/UIToolkit/Window/UTKComponentListWindow.uss b/Assets/Resources/UIToolkit/Window/UTKComponentListWindow.uss
new file mode 100644
index 00000000..a7b7c289
--- /dev/null
+++ b/Assets/Resources/UIToolkit/Window/UTKComponentListWindow.uss
@@ -0,0 +1,59 @@
+UTKComponentListWindow {
+ height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+}
+
+UTKComponentTabListWindow {
+ height: 100%;
+ position: absolute;
+ top: 0;
+ left: 400;
+ bottom: 0;
+}
+
+.container {
+ background-color: rgb(37, 37, 38);
+ height: 100%;
+ align-self: flex-start;
+ padding: 5px;
+ padding-top: 10px;
+ padding-bottom: 25px;
+ padding-left: 20px;
+ padding-right: 20px;
+ width: 300px;
+}
+
+
+.tab-button {
+ background-color: #1E1E1E;
+ border-width: 0;
+ border-radius: 0px;
+ padding-left: 12px;
+ padding-right: 12px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ margin-right: 1px;
+ margin-left: 0;
+ margin-top: 0;
+ margin-bottom: 0;
+ color: #A0A0A0;
+ font-size: 11px;
+ -unity-font-definition: resource('Fonts/Pretendard/Pretendard-Medium');
+ flex-shrink: 0;
+}
+
+.tab-button:hover {
+ background-color: #292929;
+}
+
+.tab-button-selected {
+ background-color: #303031;
+ color: rgb(255, 255, 255);
+}
+
+.tab-button-selected:hover {
+ background-color: #3A3D41;
+}
\ No newline at end of file
diff --git a/Assets/Resources/UIToolkit/Window/UTKComponentListWindow.uss.meta b/Assets/Resources/UIToolkit/Window/UTKComponentListWindow.uss.meta
new file mode 100644
index 00000000..b712cdfd
--- /dev/null
+++ b/Assets/Resources/UIToolkit/Window/UTKComponentListWindow.uss.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3df97248d26591046ab077258a2e2e44
+ScriptedImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 2
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+ script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
+ disableValidation: 0
diff --git a/Assets/Resources/UIToolkit/Window/UTKComponentListWindow.uxml b/Assets/Resources/UIToolkit/Window/UTKComponentListWindow.uxml
new file mode 100644
index 00000000..f94b04dc
--- /dev/null
+++ b/Assets/Resources/UIToolkit/Window/UTKComponentListWindow.uxml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Assets/Resources/UIToolkit/Window/UTKComponentListWindow.uxml.meta b/Assets/Resources/UIToolkit/Window/UTKComponentListWindow.uxml.meta
new file mode 100644
index 00000000..daa66746
--- /dev/null
+++ b/Assets/Resources/UIToolkit/Window/UTKComponentListWindow.uxml.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 253ecad9e87e85f418cd7f91fd213bc0
+ScriptedImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 2
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+ script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
diff --git a/Assets/Resources/UIToolkit/Window/UTKComponentTabListWindow.uxml b/Assets/Resources/UIToolkit/Window/UTKComponentTabListWindow.uxml
new file mode 100644
index 00000000..a0b0cc85
--- /dev/null
+++ b/Assets/Resources/UIToolkit/Window/UTKComponentTabListWindow.uxml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Assets/Resources/UIToolkit/Window/UTKComponentTabListWindow.uxml.meta b/Assets/Resources/UIToolkit/Window/UTKComponentTabListWindow.uxml.meta
new file mode 100644
index 00000000..133bd3b7
--- /dev/null
+++ b/Assets/Resources/UIToolkit/Window/UTKComponentTabListWindow.uxml.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 0520c39e010a25140b8c514372d164f8
+ScriptedImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 2
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+ script: {fileID: 13804, guid: 0000000000000000e000000000000000, type: 0}
diff --git a/Assets/Resources/UIToolkit/Window/UTKTreeListWindow.uss b/Assets/Resources/UIToolkit/Window/UTKTreeListWindow.uss
index cee17482..f6632a17 100644
--- a/Assets/Resources/UIToolkit/Window/UTKTreeListWindow.uss
+++ b/Assets/Resources/UIToolkit/Window/UTKTreeListWindow.uss
@@ -20,55 +20,8 @@ UTKTreeListWindow {
.search-field {
margin-bottom: 20px;
- background-color: rgb(255, 255, 255);
- border-radius: 4px;
- height: 24px;
- width: auto;
- margin-top: 0;
- margin-right: 0;
- margin-left: 0;
-
}
-#search-field > #unity-text-input {
- padding-top: 4px;
- padding-right: 24px;
- padding-bottom: 4px;
- padding-left: 4px;
- border-top-left-radius: 0;
- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0;
- border-top-width: 0;
- border-right-width: 0;
- border-bottom-width: 0;
- border-left-width: 0;
- background-color: rgb(60, 60, 60);
- font-size: 13px;
- color: rgb(204, 204, 204);
- -unity-font-definition: resource('Fonts/Pretendard/Pretendard-Medium');
- --unity-cursor-color: rgb(255, 255, 255); /* 캐럿(커서) 색상 흰색 */
-
-}
-
-#search-field .unity-base-text-field__input--placeholder {
- -unity-font-style: italic;
-}
-
-#unity-checkmark {
- -unity-background-image-tint-color: rgb(255, 255, 255);
-}
-
-#main-tree-view {
- /* 들여쓰기 폭 설정 */
- --unity-item-indent-width: 10;
-}
-
-#unity-tree-view__item-toggle > VisualElement > VisualElement {
- margin-left: 0;
- margin-right: 0;
- width: 22px;
-}
.visibility-toggle {
background-color: rgba(0, 0, 0, 0);
@@ -86,15 +39,15 @@ UTKTreeListWindow {
padding-left: 0;
margin-left: 0;
flex-shrink: 0;
- background-image: resource('SHI/Images/icon_visibility_on_64');
+ background-image: resource('UIToolkit/Images/icon_eye_22x16');
}
.visibility-on {
- background-image: resource('SHI/Images/icon_visibility_on_64');
+ background-image: resource('UIToolkit/Images/icon_eye_22x16');
}
.visibility-off {
- background-image: resource('SHI/Images/icon_visibility_off_64');
+ background-image: resource('UIToolkit/Images/icon_eye_close_22x16');
}
diff --git a/Assets/Sample/UIToolkit/UTKComponentListWindowSample.cs b/Assets/Sample/UIToolkit/UTKComponentListWindowSample.cs
new file mode 100644
index 00000000..93f9244f
--- /dev/null
+++ b/Assets/Sample/UIToolkit/UTKComponentListWindowSample.cs
@@ -0,0 +1,225 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UIElements;
+using UVC.UIToolkit.List;
+using UVC.UIToolkit.Window;
+
+///
+/// UTKComponentListWindow와 UTKComponentTabListWindow의 기능을 테스트하기 위한 샘플 MonoBehaviour입니다.
+/// 계층적 트리 데이터를 생성하고 다양한 이벤트 핸들러를 등록하여 동작을 확인합니다.
+///
+public class UTKComponentListWindowSample : MonoBehaviour
+{
+ [SerializeField]
+ public UIDocument uiDocument;
+
+
+
+ private UTKComponentListWindow listWindow;
+ private UTKComponentTabListWindow tabListWindow;
+
+ void Start()
+ {
+ uiDocument ??= GetComponent();
+
+
+ // UTKComponentTabListWindow 사용 (탭 기능 포함)
+ tabListWindow = new UTKComponentTabListWindow();
+ tabListWindow.style.marginLeft = 500;
+ uiDocument.rootVisualElement.Add(tabListWindow);
+
+ // 테스트용 계층적 트리 데이터 생성
+ CreateTabListTestData();
+
+ // 이벤트 핸들러 등록
+ RegisterTabListEventHandlers();
+
+ // UTKComponentListWindow 사용 (기본)
+ listWindow = new UTKComponentListWindow();
+ uiDocument.rootVisualElement.Add(listWindow);
+
+ // 테스트용 계층적 트리 데이터 생성
+ CreateTestData();
+
+ // 이벤트 핸들러 등록
+ RegisterEventHandlers();
+
+ }
+
+ ///
+ /// 테스트용 계층적 트리 데이터를 생성합니다.
+ /// 10개의 루트 항목을 생성하고, 각 루트에 5개의 자식,
+ /// 각 자식에 3개의 손자, 각 손자에 2개의 증손자를 추가합니다.
+ ///
+ private void CreateTestData()
+ {
+ var data = new List();
+ for (int i = 1; i <= 5; i++)
+ {
+ string categoryName = $"Category {i}";
+ UTKComponentListItemData categoryData = new UTKComponentListItemData { name = categoryName };
+
+ for (int j = 1; j <= 20; j++)
+ {
+ var itemData = new UTKComponentListItemData
+ {
+ name = $"Item {i}-{j}",
+ option = $"Option {j}"
+ };
+ categoryData.Add(itemData);
+ }
+ data.Add(categoryData);
+ }
+ listWindow.SetData(data);
+
+ Debug.Log("[UTKComponentListWindowSample] 테스트 데이터 생성 완료: 5개 루트 항목");
+ }
+
+ ///
+ /// UTKComponentListWindow의 이벤트 핸들러들을 등록합니다.
+ /// 선택, 선택 해제, 삭제, 더블클릭, 가시성 변경 이벤트를 처리합니다.
+ ///
+ private void RegisterEventHandlers()
+ {
+ // 항목 선택 이벤트 (다중 선택 지원)
+ // 사용자가 항목을 클릭하거나 SelectItem() 호출 시 발생
+ listWindow.OnItemSelected += (List selectedItems) =>
+ {
+ foreach (var item in selectedItems)
+ {
+ Debug.Log($"[선택됨] {item.name}");
+ }
+ };
+
+ // 항목 선택 해제 이벤트 (다중 선택 지원)
+ // 사용자가 다른 항목을 선택하거나 DeselectItem() 호출 시 발생
+ listWindow.OnItemDeselected += (List deselectedItems) =>
+ {
+ foreach (var item in deselectedItems)
+ {
+ Debug.Log($"[선택 해제됨] {item.name}");
+ }
+ };
+
+ // 항목 삭제 이벤트
+ // 사용자가 Delete 또는 Backspace 키를 누를 때 발생
+ // 실제 삭제는 이 핸들러에서 DeleteItem()을 호출하여 수행
+ listWindow.OnItemDeleted += (UTKComponentListItemData deletedItem) =>
+ {
+ Debug.Log($"[삭제 요청] {deletedItem.name}");
+ // 실제로 항목을 삭제하려면 아래 주석을 해제하세요:
+ // treeListWindow.DeleteItem(deletedItem);
+ };
+
+ // 항목 더블클릭 이벤트
+ // 사용자가 항목을 더블클릭하거나 Enter 키를 누를 때 발생
+ listWindow.OnItemDoubleClicked += (UTKComponentListItemData doubleClickedItem) =>
+ {
+ Debug.Log($"[더블클릭] {doubleClickedItem.name}");
+ };
+
+ // 항목 가시성 변경 이벤트
+ // 사용자가 눈 아이콘 버튼을 클릭하여 가시성을 토글할 때 발생
+ listWindow.OnItemVisibilityChanged += (UTKComponentListItemData item, bool isVisible) =>
+ {
+ Debug.Log($"[가시성 변경] {item.name}, IsVisible: {isVisible}");
+ };
+
+ // 아이콘 클릭 이벤트
+ // 그룹 항목의 setting-btn 등 아이콘 버튼 클릭 시 발생
+ listWindow.OnItemIconClicked += (string iconName, UTKComponentListItemData item) =>
+ {
+ Debug.Log($"[아이콘 클릭] {iconName}, Item: {item.name}");
+ };
+
+ Debug.Log("[UTKComponentListWindowSample] 이벤트 핸들러 등록 완료");
+ }
+
+ ///
+ /// UTKComponentTabListWindow용 테스트 데이터를 생성합니다.
+ /// 5개의 카테고리(탭)를 생성하고, 각 카테고리에 20개의 자식 항목을 추가합니다.
+ ///
+ private void CreateTabListTestData()
+ {
+ var data = new List();
+ for (int i = 1; i <= 5; i++)
+ {
+ string categoryName = $"Category {i}";
+ UTKComponentListItemData categoryData = new UTKComponentListItemData { name = categoryName };
+
+ for (int j = 1; j <= 20; j++)
+ {
+ var itemData = new UTKComponentListItemData
+ {
+ name = $"Item {i}-{j}",
+ option = $"Option {j}"
+ };
+ categoryData.Add(itemData);
+ }
+ data.Add(categoryData);
+ }
+ tabListWindow.SetData(data);
+
+ Debug.Log("[UTKComponentListWindowSample] TabList 테스트 데이터 생성 완료: 5개 카테고리 (탭으로 표시됨)");
+ }
+
+ ///
+ /// UTKComponentTabListWindow의 이벤트 핸들러들을 등록합니다.
+ ///
+ private void RegisterTabListEventHandlers()
+ {
+ // 항목 선택 이벤트 (다중 선택 지원)
+ tabListWindow.OnItemSelected += (List selectedItems) =>
+ {
+ foreach (var item in selectedItems)
+ {
+ Debug.Log($"[TabList 선택됨] {item.name}");
+ }
+ };
+
+ // 항목 선택 해제 이벤트 (다중 선택 지원)
+ tabListWindow.OnItemDeselected += (List deselectedItems) =>
+ {
+ foreach (var item in deselectedItems)
+ {
+ Debug.Log($"[TabList 선택 해제됨] {item.name}");
+ }
+ };
+
+ // 항목 삭제 이벤트
+ tabListWindow.OnItemDeleted += (UTKComponentListItemData deletedItem) =>
+ {
+ Debug.Log($"[TabList 삭제 요청] {deletedItem.name}");
+ };
+
+ // 항목 더블클릭 이벤트
+ tabListWindow.OnItemDoubleClicked += (UTKComponentListItemData doubleClickedItem) =>
+ {
+ Debug.Log($"[TabList 더블클릭] {doubleClickedItem.name}");
+ };
+
+ // 항목 가시성 변경 이벤트
+ tabListWindow.OnItemVisibilityChanged += (UTKComponentListItemData item, bool isVisible) =>
+ {
+ Debug.Log($"[TabList 가시성 변경] {item.name}, IsVisible: {isVisible}");
+ };
+
+ // 아이콘 클릭 이벤트
+ tabListWindow.OnItemIconClicked += (string iconName, UTKComponentListItemData item) =>
+ {
+ Debug.Log($"[TabList 아이콘 클릭] {iconName}, Item: {item.name}");
+ };
+
+ Debug.Log("[UTKComponentListWindowSample] TabList 이벤트 핸들러 등록 완료");
+ }
+
+ ///
+ /// 컴포넌트가 파괴될 때 리소스를 정리합니다.
+ ///
+ private void OnDestroy()
+ {
+ // UTKComponentListWindow의 Dispose 호출로 이벤트 핸들러 정리
+ listWindow?.Dispose();
+ tabListWindow?.Dispose();
+ }
+}
diff --git a/Assets/Sample/UIToolkit/UTKComponentListWindowSample.cs.meta b/Assets/Sample/UIToolkit/UTKComponentListWindowSample.cs.meta
new file mode 100644
index 00000000..b6925f6a
--- /dev/null
+++ b/Assets/Sample/UIToolkit/UTKComponentListWindowSample.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: ed200de1f3108b441b61f25085defa29
diff --git a/Assets/Sample/UIToolkit/UTKComponentListWindowSample.unity b/Assets/Sample/UIToolkit/UTKComponentListWindowSample.unity
new file mode 100644
index 00000000..14f7556c
--- /dev/null
+++ b/Assets/Sample/UIToolkit/UTKComponentListWindowSample.unity
@@ -0,0 +1,496 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+ m_ObjectHideFlags: 0
+ serializedVersion: 2
+ m_OcclusionBakeSettings:
+ smallestOccluder: 5
+ smallestHole: 0.25
+ backfaceThreshold: 100
+ m_SceneGUID: 00000000000000000000000000000000
+ m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+ m_ObjectHideFlags: 0
+ serializedVersion: 10
+ m_Fog: 0
+ m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+ m_FogMode: 3
+ m_FogDensity: 0.01
+ m_LinearFogStart: 0
+ m_LinearFogEnd: 300
+ m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+ m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+ m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+ m_AmbientIntensity: 1
+ m_AmbientMode: 0
+ m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+ m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+ m_HaloStrength: 0.5
+ m_FlareStrength: 1
+ m_FlareFadeSpeed: 3
+ m_HaloTexture: {fileID: 0}
+ m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+ m_DefaultReflectionMode: 0
+ m_DefaultReflectionResolution: 128
+ m_ReflectionBounces: 1
+ m_ReflectionIntensity: 1
+ m_CustomReflection: {fileID: 0}
+ m_Sun: {fileID: 0}
+ m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+ m_ObjectHideFlags: 0
+ serializedVersion: 13
+ m_BakeOnSceneLoad: 0
+ m_GISettings:
+ serializedVersion: 2
+ m_BounceScale: 1
+ m_IndirectOutputScale: 1
+ m_AlbedoBoost: 1
+ m_EnvironmentLightingMode: 0
+ m_EnableBakedLightmaps: 1
+ m_EnableRealtimeLightmaps: 0
+ m_LightmapEditorSettings:
+ serializedVersion: 12
+ m_Resolution: 2
+ m_BakeResolution: 40
+ m_AtlasSize: 1024
+ m_AO: 0
+ m_AOMaxDistance: 1
+ m_CompAOExponent: 1
+ m_CompAOExponentDirect: 0
+ m_ExtractAmbientOcclusion: 0
+ m_Padding: 2
+ m_LightmapParameters: {fileID: 0}
+ m_LightmapsBakeMode: 1
+ m_TextureCompression: 1
+ m_ReflectionCompression: 2
+ m_MixedBakeMode: 2
+ m_BakeBackend: 1
+ m_PVRSampling: 1
+ m_PVRDirectSampleCount: 32
+ m_PVRSampleCount: 512
+ m_PVRBounces: 2
+ m_PVREnvironmentSampleCount: 256
+ m_PVREnvironmentReferencePointCount: 2048
+ m_PVRFilteringMode: 1
+ m_PVRDenoiserTypeDirect: 1
+ m_PVRDenoiserTypeIndirect: 1
+ m_PVRDenoiserTypeAO: 1
+ m_PVRFilterTypeDirect: 0
+ m_PVRFilterTypeIndirect: 0
+ m_PVRFilterTypeAO: 0
+ m_PVREnvironmentMIS: 1
+ m_PVRCulling: 1
+ m_PVRFilteringGaussRadiusDirect: 1
+ m_PVRFilteringGaussRadiusIndirect: 1
+ m_PVRFilteringGaussRadiusAO: 1
+ m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+ m_PVRFilteringAtrousPositionSigmaIndirect: 2
+ m_PVRFilteringAtrousPositionSigmaAO: 1
+ m_ExportTrainingData: 0
+ m_TrainingDataDestination: TrainingData
+ m_LightProbeSampleCountMultiplier: 4
+ m_LightingDataAsset: {fileID: 20201, guid: 0000000000000000f000000000000000, type: 0}
+ m_LightingSettings: {fileID: 0}
+--- !u!196 &4
+NavMeshSettings:
+ serializedVersion: 2
+ m_ObjectHideFlags: 0
+ m_BuildSettings:
+ serializedVersion: 3
+ agentTypeID: 0
+ agentRadius: 0.5
+ agentHeight: 2
+ agentSlope: 45
+ agentClimb: 0.4
+ ledgeDropHeight: 0
+ maxJumpAcrossDistance: 0
+ minRegionArea: 2
+ manualCellSize: 0
+ cellSize: 0.16666667
+ manualTileSize: 0
+ tileSize: 256
+ buildHeightMesh: 0
+ maxJobWorkers: 0
+ preserveTilesOutsideBounds: 0
+ debug:
+ m_Flags: 0
+ m_NavMeshData: {fileID: 0}
+--- !u!1 &1097328750
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1097328752}
+ - component: {fileID: 1097328754}
+ - component: {fileID: 1097328755}
+ m_Layer: 0
+ m_Name: UTKComponentListWindowSample
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &1097328752
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1097328750}
+ serializedVersion: 2
+ 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
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &1097328754
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1097328750}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0}
+ m_Name:
+ m_EditorClassIdentifier: UnityEngine.dll::UnityEngine.UIElements.UIDocument
+ m_PanelSettings: {fileID: 11400000, guid: 5ad7007b08a97b54d927c352279a18b6, type: 2}
+ m_ParentUI: {fileID: 0}
+ sourceAsset: {fileID: 9197481963319205126, guid: 9d3024917e8d4b546943ec3f7b03d9e4, type: 3}
+ m_SortingOrder: 0
+ m_Position: 0
+ m_WorldSpaceSizeMode: 1
+ m_WorldSpaceWidth: 1920
+ m_WorldSpaceHeight: 1080
+ m_PivotReferenceSize: 0
+ m_Pivot: 0
+ m_WorldSpaceCollider: {fileID: 0}
+--- !u!114 &1097328755
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1097328750}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: ed200de1f3108b441b61f25085defa29, type: 3}
+ m_Name:
+ m_EditorClassIdentifier: Assembly-CSharp::UTKComponentListWindowSample
+ uiDocument: {fileID: 1097328754}
+--- !u!1 &1331954412
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1331954415}
+ - component: {fileID: 1331954414}
+ - component: {fileID: 1331954413}
+ m_Layer: 0
+ m_Name: EventSystem
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &1331954413
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1331954412}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 01614664b831546d2ae94a42149d80ac, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_SendPointerHoverToParent: 1
+ m_MoveRepeatDelay: 0.5
+ m_MoveRepeatRate: 0.1
+ m_XRTrackingOrigin: {fileID: 0}
+ m_ActionsAsset: {fileID: -944628639613478452, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_PointAction: {fileID: -1654692200621890270, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_MoveAction: {fileID: -8784545083839296357, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_SubmitAction: {fileID: 392368643174621059, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_CancelAction: {fileID: 7727032971491509709, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_LeftClickAction: {fileID: 3001919216989983466, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_MiddleClickAction: {fileID: -2185481485913320682, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_RightClickAction: {fileID: -4090225696740746782, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_ScrollWheelAction: {fileID: 6240969308177333660, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_TrackedDevicePositionAction: {fileID: 6564999863303420839, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_TrackedDeviceOrientationAction: {fileID: 7970375526676320489, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
+ m_DeselectOnBackgroundClick: 0
+ m_PointerBehavior: 0
+ m_CursorLockBehavior: 0
+ m_ScrollDeltaPerTick: 6
+--- !u!114 &1331954414
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1331954412}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_FirstSelected: {fileID: 0}
+ m_sendNavigationEvents: 1
+ m_DragThreshold: 10
+--- !u!4 &1331954415
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1331954412}
+ serializedVersion: 2
+ 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
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1414861612
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1414861614}
+ - component: {fileID: 1414861613}
+ - component: {fileID: 1414861615}
+ m_Layer: 0
+ m_Name: Directional Light
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!108 &1414861613
+Light:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1414861612}
+ m_Enabled: 1
+ serializedVersion: 11
+ m_Type: 1
+ m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+ m_Intensity: 1
+ m_Range: 10
+ m_SpotAngle: 30
+ m_InnerSpotAngle: 21.80208
+ m_CookieSize: 10
+ m_Shadows:
+ m_Type: 2
+ m_Resolution: -1
+ m_CustomResolution: -1
+ m_Strength: 1
+ m_Bias: 0.05
+ m_NormalBias: 0.4
+ m_NearPlane: 0.2
+ m_CullingMatrixOverride:
+ e00: 1
+ e01: 0
+ e02: 0
+ e03: 0
+ e10: 0
+ e11: 1
+ e12: 0
+ e13: 0
+ e20: 0
+ e21: 0
+ e22: 1
+ e23: 0
+ e30: 0
+ e31: 0
+ e32: 0
+ e33: 1
+ m_UseCullingMatrixOverride: 0
+ m_Cookie: {fileID: 0}
+ m_DrawHalo: 0
+ m_Flare: {fileID: 0}
+ m_RenderMode: 0
+ m_CullingMask:
+ serializedVersion: 2
+ m_Bits: 4294967295
+ m_RenderingLayerMask: 1
+ m_Lightmapping: 4
+ m_LightShadowCasterMode: 0
+ m_AreaSize: {x: 1, y: 1}
+ m_BounceIntensity: 1
+ m_ColorTemperature: 6570
+ m_UseColorTemperature: 0
+ m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
+ m_UseBoundingSphereOverride: 0
+ m_UseViewFrustumForShadowCasterCull: 1
+ m_ForceVisible: 0
+ m_ShadowRadius: 0
+ m_ShadowAngle: 0
+ m_LightUnit: 1
+ m_LuxAtDistance: 1
+ m_EnableSpotReflector: 1
+--- !u!4 &1414861614
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1414861612}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
+ m_LocalPosition: {x: 0, y: 3, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
+--- !u!114 &1414861615
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1414861612}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_UsePipelineSettings: 1
+ m_AdditionalLightsShadowResolutionTier: 2
+ m_CustomShadowLayers: 0
+ m_LightCookieSize: {x: 1, y: 1}
+ m_LightCookieOffset: {x: 0, y: 0}
+ m_SoftShadowQuality: 0
+ m_RenderingLayersMask:
+ serializedVersion: 0
+ m_Bits: 1
+ m_ShadowRenderingLayersMask:
+ serializedVersion: 0
+ m_Bits: 1
+ m_Version: 4
+ m_LightLayerMask: 1
+ m_ShadowLayerMask: 1
+ m_RenderingLayers: 1
+ m_ShadowRenderingLayers: 1
+--- !u!1 &2136621999
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2136622002}
+ - component: {fileID: 2136622001}
+ - component: {fileID: 2136622000}
+ m_Layer: 0
+ m_Name: Main Camera
+ m_TagString: MainCamera
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!81 &2136622000
+AudioListener:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2136621999}
+ m_Enabled: 1
+--- !u!20 &2136622001
+Camera:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2136621999}
+ m_Enabled: 1
+ serializedVersion: 2
+ m_ClearFlags: 1
+ m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
+ m_projectionMatrixMode: 1
+ m_GateFitMode: 2
+ m_FOVAxisMode: 0
+ m_Iso: 200
+ m_ShutterSpeed: 0.005
+ m_Aperture: 16
+ m_FocusDistance: 10
+ m_FocalLength: 50
+ m_BladeCount: 5
+ m_Curvature: {x: 2, y: 11}
+ m_BarrelClipping: 0.25
+ m_Anamorphism: 0
+ m_SensorSize: {x: 36, y: 24}
+ m_LensShift: {x: 0, y: 0}
+ m_NormalizedViewPortRect:
+ serializedVersion: 2
+ x: 0
+ y: 0
+ width: 1
+ height: 1
+ near clip plane: 0.3
+ far clip plane: 1000
+ field of view: 60
+ orthographic: 0
+ orthographic size: 5
+ m_Depth: -1
+ m_CullingMask:
+ serializedVersion: 2
+ m_Bits: 4294967295
+ m_RenderingPath: -1
+ m_TargetTexture: {fileID: 0}
+ m_TargetDisplay: 0
+ m_TargetEye: 3
+ m_HDR: 1
+ m_AllowMSAA: 1
+ m_AllowDynamicResolution: 0
+ m_ForceIntoRT: 0
+ m_OcclusionCulling: 1
+ m_StereoConvergence: 10
+ m_StereoSeparation: 0.022
+--- !u!4 &2136622002
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2136621999}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 1, z: -10}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1660057539 &9223372036854775807
+SceneRoots:
+ m_ObjectHideFlags: 0
+ m_Roots:
+ - {fileID: 2136622002}
+ - {fileID: 1414861614}
+ - {fileID: 1331954415}
+ - {fileID: 1097328752}
diff --git a/Assets/Sample/UIToolkit/UTKComponentListWindowSample.unity.meta b/Assets/Sample/UIToolkit/UTKComponentListWindowSample.unity.meta
new file mode 100644
index 00000000..8b8fe248
--- /dev/null
+++ b/Assets/Sample/UIToolkit/UTKComponentListWindowSample.unity.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 65d99286ce3c5a041b57ed8209713cd5
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Sample/UIToolkit/UTKTreeListWindowSample.cs b/Assets/Sample/UIToolkit/UTKTreeListWindowSample.cs
index dd0a13f3..5cc6323a 100644
--- a/Assets/Sample/UIToolkit/UTKTreeListWindowSample.cs
+++ b/Assets/Sample/UIToolkit/UTKTreeListWindowSample.cs
@@ -45,6 +45,7 @@ public class UTKTreeListWindowSample : MonoBehaviour
///
private void CreateTestData()
{
+ List rootItems = new List();
// 10개의 루트 항목 생성
for (int i = 0; i < 10; i++)
{
@@ -74,9 +75,11 @@ public class UTKTreeListWindowSample : MonoBehaviour
}
}
- // 루트 항목을 트리에 추가
- treeListWindow.AddItem(itemData);
+ rootItems.Add(itemData);
}
+
+ // 루트 항목을 트리에 추가
+ treeListWindow.SetData(rootItems);
Debug.Log("[UTKTreeListWindowSample] 테스트 데이터 생성 완료: 10개 루트 항목");
}
diff --git a/Assets/Scripts/UVC/UIToolkit/List/UTKComponentList.cs b/Assets/Scripts/UVC/UIToolkit/List/UTKComponentList.cs
new file mode 100644
index 00000000..bfff1de6
--- /dev/null
+++ b/Assets/Scripts/UVC/UIToolkit/List/UTKComponentList.cs
@@ -0,0 +1,1481 @@
+#nullable enable
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.UIElements;
+using UVC.Locale;
+
+namespace UVC.UIToolkit.List
+{
+ ///
+ /// 계층적 트리 구조를 표시하는 커스텀 UI Toolkit 컴포넌트입니다.
+ ///
+ /// 개요:
+ ///
+ /// UTKComponentList는 Unity UI Toolkit의 TreeView를 래핑하여 검색, 가시성 토글,
+ /// 닫기 기능 등을 제공하는 재사용 가능한 컴포넌트입니다.
+ /// UXML 파일(UTKComponentList.uxml, UTKComponentListItem.uxml)과 함께 사용됩니다.
+ ///
+ ///
+ /// 주요 기능:
+ ///
+ /// - 계층적 트리 구조 표시 (펼치기/접기 지원)
+ /// - 실시간 검색 필터링
+ /// - 항목별 가시성(눈 아이콘) 토글
+ /// - 선택 이벤트 처리
+ ///
+ ///
+ /// UXML에서 사용:
+ ///
+ ///
+ ///
+ ///
+ /// 코드에서 사용:
+ ///
+ /// var list = root.Q();
+ /// list.OnSelectionChanged += (item) => Debug.Log($"선택: {item.name}");
+ /// list.OnVisibilityChanged += (item) => model.SetActive(item.id, item.IsVisible);
+ /// list.SetData(treeItems);
+ ///
+ ///
+ /// 관련 리소스:
+ ///
+ /// - Resources/UIToolkit/Window/UTKComponentList.uxml - 메인 레이아웃
+ /// - Resources/UIToolkit/List/UTKComponentListItem.uxml - 개별 항목 템플릿
+ /// - Resources/UIToolkit/List/UTKComponentListGroupItem.uxml - 그룹 항목 템플릿
+ ///
+ ///
+ /// 선택 해제 방지:
+ ///
+ /// 빈 영역 클릭 시 선택이 해제되지 않도록 하려면 EventSystem의 InputSystemUIInputModule 컴포넌트에서
+ /// Deselect On Background Click 옵션을 해제해야 합니다.
+ ///
+ ///
+ [UxmlElement]
+ public partial class UTKComponentList : VisualElement, IDisposable
+ {
+ #region IDisposable
+ private bool _disposed = false;
+ #endregion
+ #region 상수 (Constants)
+ /// 메인 UXML 파일 경로 (Resources 폴더 기준)
+ private const string UXML_PATH = "UIToolkit/List/UTKComponentList";
+
+ /// 일반 항목 UXML 파일 경로 (Resources 폴더 기준)
+ private const string ITEM_UXML_PATH = "UIToolkit/List/UTKComponentListItem";
+
+ /// 그룹 항목 UXML 파일 경로 (Resources 폴더 기준)
+ private const string GROUP_ITEM_UXML_PATH = "UIToolkit/List/UTKComponentListGroupItem";
+ #endregion
+
+ #region 캐싱된 리소스 (Cached Resources)
+ /// 일반 항목 UXML 템플릿
+ private VisualTreeAsset? _itemTemplate;
+
+ /// 그룹 항목 UXML 템플릿
+ private VisualTreeAsset? _groupItemTemplate;
+ #endregion
+
+ #region UI 컴포넌트 참조 (UI Component References)
+ /// 검색어 입력 필드
+ private TextField? _searchField;
+
+ /// Unity UI Toolkit의 TreeView 컴포넌트
+ private TreeView? _treeView;
+
+ /// 검색어 지우기 버튼
+ private Button? _clearButton;
+ #endregion
+
+ #region 내부 데이터 (Internal Data)
+
+
+ ///
+ /// 원본 루트 데이터입니다.
+ /// 검색 필터 해제 시 원래 데이터로 복원하는 데 사용됩니다.
+ ///
+ private List _originalRoots = new();
+
+ ///
+ /// TreeView에 바인딩되는 데이터 소스입니다.
+ /// TreeViewItemData는 Unity의 TreeView가 요구하는 래퍼 타입입니다.
+ ///
+ private List>? _rootData;
+
+ ///
+ /// 항목 ID 자동 생성을 위한 시드 값입니다.
+ /// SetData() 호출 시 id가 0인 항목에 순차적으로 ID를 할당합니다.
+ ///
+ private int _idSeed = 1;
+
+ ///
+ /// 이전에 선택된 항목들입니다.
+ /// 선택 해제 이벤트 발송에 사용됩니다.
+ ///
+ private List _previouslySelectedItems = new();
+
+ ///
+ /// 선택 이벤트 발송을 일시적으로 억제하는 플래그입니다.
+ /// 프로그래밍 방식으로 선택 시 이벤트를 발송하지 않으려면 true로 설정합니다.
+ ///
+ private bool _suppressSelectionEvent = false;
+
+ ///
+ /// 펼침/접힘 이벤트 처리를 일시적으로 억제하는 플래그입니다.
+ /// ExpandByData() 실행 중 이벤트로 인한 데이터 덮어쓰기를 방지합니다.
+ ///
+ private bool _suppressExpandEvent = false;
+ #endregion
+
+ #region 공개 속성 (Public Properties)
+ ///
+ /// 항목 삭제 기능 활성화 여부입니다.
+ /// true일 때만 Delete/Backspace 키로 항목 삭제 이벤트가 발생합니다.
+ /// 기본값은 false입니다.
+ ///
+ public bool EnabledDeleteItem { get; set; } = false;
+
+ ///
+ /// 현재 검색어를 가져오거나 설정합니다.
+ /// 설정 시 검색 필드의 값만 변경하고 검색은 실행하지 않습니다.
+ ///
+ public string SearchQuery
+ {
+ get => _searchField?.value ?? string.Empty;
+ set { if (_searchField != null) _searchField.value = value; }
+ }
+ #endregion
+
+ #region 외부 이벤트 (Public Events)
+
+ ///
+ /// 메인/검색 리스트에서 항목이 선택될 때 발생합니다.
+ ///
+ public Action>? OnItemSelected;
+
+ ///
+ /// 메인/검색 리스트에서 항목이 선택 해제될 때 발생합니다.
+ ///
+ public Action>? OnItemDeselected;
+ ///
+ /// 항목의 가시성(눈 아이콘)이 변경될 때 발생합니다.
+ /// 3D 모델의 GameObject 활성화/비활성화에 연동합니다.
+ ///
+ public event Action? OnItemVisibilityChanged;
+
+ ///
+ /// 메인/검색 리스트에서 항목이 삭제될 때 발생합니다 (Delete 키).
+ ///
+ public Action? OnItemDeleted;
+
+ ///
+ /// 메인/검색 리스트에서 항목이 더블클릭될 때 발생합니다.
+ ///
+ public Action? OnItemDoubleClicked;
+
+ ///
+ /// 아이콘을 클릭할 때 발생합니다.
+ ///
+ public Action? OnItemIconClicked;
+
+ #endregion
+
+ #region 생성자 (Constructor)
+ ///
+ /// UTKComponentList 컴포넌트를 초기화합니다.
+ /// UXML 템플릿을 로드하고 내부 컴포넌트를 설정합니다.
+ ///
+ public UTKComponentList()
+ {
+ // 1. 메인 UXML 로드 및 복제
+ // CloneTree(this)로 UXML 내용이 이 클래스의 자식으로 추가됨
+ var visualTree = Resources.Load(UXML_PATH);
+ if (visualTree == null)
+ {
+ Debug.LogError($"[TreeMenu] UXML not found at: {UXML_PATH}");
+ return;
+ }
+ visualTree!.CloneTree(this);
+
+ // 2. 항목 템플릿 로드
+ _itemTemplate = Resources.Load(ITEM_UXML_PATH);
+ _groupItemTemplate = Resources.Load(GROUP_ITEM_UXML_PATH);
+ if (_itemTemplate == null)
+ Debug.LogError($"[UTKComponentList] Item UXML not found at: {ITEM_UXML_PATH}");
+ if (_groupItemTemplate == null)
+ Debug.LogError($"[UTKComponentList] Group Item UXML not found at: {GROUP_ITEM_UXML_PATH}");
+
+
+ // 2. 자식 요소 참조 획득 (UXML의 name 속성으로 찾음)
+ _searchField = this.Q("search-field");
+ _treeView = this.Q("main-tree-view");
+ _clearButton = this.Q