Merge pull request '객체 라이브러리 창 수정' (#74) from pgd/20250515 into main

Reviewed-on: http://220.90.135.190:3000/UVCXR/Studio/pulls/74
This commit was merged in pull request #74.
This commit is contained in:
2025-05-15 17:16:59 +09:00
7 changed files with 1442 additions and 41 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 271d50d4387a4824ca81fe5584a05d5f
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -34,6 +34,7 @@ RectTransform:
- {fileID: 5835114744567661830}
- {fileID: 2851634799881106517}
- {fileID: 6516329988442884210}
- {fileID: 5667924966586345141}
m_Father: {fileID: 9151118461914384115}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
@@ -364,10 +365,10 @@ RectTransform:
m_Children: []
m_Father: {fileID: 8835006081575840586}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 1}
m_AnchorMax: {x: 0.5, y: 1}
m_AnchoredPosition: {x: 0, y: -62}
m_SizeDelta: {x: 0, y: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 0, y: 0.5}
m_AnchoredPosition: {x: 45, y: -27}
m_SizeDelta: {x: 70, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &499100886614822048
CanvasRenderer:
@@ -480,7 +481,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 2
m_HorizontalFit: 0
m_VerticalFit: 2
--- !u!1 &3184001677813492081
GameObject:
@@ -699,6 +700,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
nameText: {fileID: 197987882297848403}
folderText: {fileID: 5823905245534661015}
thumbnail: {fileID: 8697110781996111556}
loadProgress: {fileID: 9157065393132299556}
expandButton: {fileID: 459961761490458298}
@@ -1031,6 +1033,157 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_ShowMaskGraphic: 1
--- !u!1 &5314708607931484652
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5667924966586345141}
- component: {fileID: 7128505562268780370}
- component: {fileID: 5823905245534661015}
- component: {fileID: 7751771326296383236}
m_Layer: 5
m_Name: TItleText
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5667924966586345141
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5314708607931484652}
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: 8835006081575840586}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 0, y: 0.5}
m_AnchoredPosition: {x: 10, y: 0}
m_SizeDelta: {x: 70, y: 0}
m_Pivot: {x: 0, y: 0.5}
--- !u!222 &7128505562268780370
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5314708607931484652}
m_CullTransparentMesh: 1
--- !u!114 &5823905245534661015
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5314708607931484652}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text:
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 4f170a218dfffe4489dc7ddd54bc15cf, type: 2}
m_sharedMaterial: {fileID: 6975767319296004534, guid: 4f170a218dfffe4489dc7ddd54bc15cf, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 15
m_fontSizeBase: 15
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 1
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_TextWrappingMode: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_ActiveFontFeatures: 6e72656b
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_EmojiFallbackSupport: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!114 &7751771326296383236
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5314708607931484652}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 2
--- !u!1 &6795736773272050223
GameObject:
m_ObjectHideFlags: 0

View File

@@ -18,11 +18,16 @@ namespace XED.AssetLibraryTree
private TMP_InputField searchInput;
//private Button searchCancelButton;
private GameObject itemPrefab; // Prefab for scroll items.
private ObjectPool<AssetLibraryScrollItemUI> pool; // Pool for UI items.
private GameObject folderPrefab;
private ObjectPool<AssetLibraryScrollItemUI> itemsPool; // Pool for UI items.
private ObjectPool<AssetLibraryScrollFolderUI> foldersPool;
private List<AssetLibraryItem> data = new List<AssetLibraryItem>(); // The list of hierarchy items.
private List<AssetLibraryItem> displayData = new List<AssetLibraryItem>();
private AssetLibraryItem root;
private List<AssetLibraryScrollItemUI> activeItems = new List<AssetLibraryScrollItemUI>();
private List<AssetLibraryScrollFolderUI> activeFolders = new List<AssetLibraryScrollFolderUI>();
public List<AssetLibraryItem> selectedItems = new List<AssetLibraryItem>();
private AssetLibraryItem lastSelectedItem = null;
@@ -36,6 +41,8 @@ namespace XED.AssetLibraryTree
public bool isSiblingEditable;
int rowItemCount = 3;
private void Awake()
{
content = Find<RectTransform>("Content");
@@ -46,9 +53,10 @@ namespace XED.AssetLibraryTree
}
//searchCancelButton = UtilityFunction.FindDeepChild(transform, "Button_SearchBar").GetComponent<Button>();
itemPrefab = Resources.Load<GameObject>("Prefabs/UI/PRF_AssetLibraryItem");
folderPrefab = Resources.Load<GameObject>("Prefabs/UI/PRF_AssetLibraryFolder");
//스크롤 뷰에 사용될 오브젝트 풀을 미리 20개 생성
pool = new ObjectPool<AssetLibraryScrollItemUI>(
itemsPool = new ObjectPool<AssetLibraryScrollItemUI>(
createFunc: () => Instantiate(itemPrefab).GetComponent<AssetLibraryScrollItemUI>(),
actionOnGet: (item) => item.gameObject.SetActive(true),
actionOnRelease: (item) => item.gameObject.SetActive(false),
@@ -56,6 +64,14 @@ namespace XED.AssetLibraryTree
defaultCapacity: 20,
maxSize: 40);
foldersPool = new ObjectPool<AssetLibraryScrollFolderUI>(
createFunc: () => Instantiate(folderPrefab).GetComponent<AssetLibraryScrollFolderUI>(),
actionOnGet: (item) => item.gameObject.SetActive(true),
actionOnRelease: (item) => item.gameObject.SetActive(false),
actionOnDestroy: (item) => Destroy(item.gameObject),
defaultCapacity: 10,
maxSize: 40);
root = new AssetLibraryItem("Root", -1);
root.onParentChanged = onParentChanged;
}
@@ -172,18 +188,49 @@ namespace XED.AssetLibraryTree
int newRowIndex = Mathf.FloorToInt(scrollY / rowHeight);
if (newRowIndex < 0) newRowIndex = 0;
if (newRowIndex == currentIndex) return;
if (newRowIndex == currentIndex)
return;
currentIndex = newRowIndex;
foreach (var item in activeItems) pool.Release(item);
foreach (var item in activeItems)
itemsPool.Release(item);
foreach (var item in activeFolders)
foldersPool.Release(item);
activeItems.Clear();
activeFolders.Clear();
displayData.Clear();
int itemsPerRow = 3;
int startIndex = Mathf.Clamp(currentIndex * itemsPerRow, 0, data.Count);
int endIndex = Mathf.Clamp((currentIndex + visibleItemCount) * itemsPerRow, 0, data.Count);
foreach (var item in data)
{
if (item.type == AssetLibraryItemType.folder)
{
int offset = displayData.Count % rowItemCount;
if (offset != 0)
{
int emptyCount = rowItemCount - offset;
for (int i = 0; i < emptyCount; i++)
displayData.Add(null);
}
displayData.Add(item);
displayData.Add(null);
displayData.Add(null);
}
else
{
displayData.Add(item);
}
}
int startIndex = Mathf.Clamp(currentIndex * rowItemCount, 0, displayData.Count);
int endIndex = Mathf.Clamp((currentIndex + visibleItemCount) * rowItemCount, 0, displayData.Count);
SetScrollItemUI(startIndex, endIndex);
}
private void RebuildVisibleItems(AssetLibraryItem focusItem)
{
int itemIndex = data.FindIndex((x) => x == focusItem);
@@ -192,53 +239,97 @@ namespace XED.AssetLibraryTree
float rowHeight = itemHeight + 10f;
content.anchoredPosition = new Vector2(content.anchoredPosition.x, currentIndex * rowHeight);
foreach (var item in activeItems) pool.Release(item);
foreach (var item in activeItems)
itemsPool.Release(item);
foreach (var item in activeFolders)
foldersPool.Release(item);
activeItems.Clear();
activeFolders.Clear();
displayData.Clear();
int itemsPerRow = 3;
int startIndex = Mathf.Clamp(currentIndex * itemsPerRow, 0, data.Count);
int endIndex = Mathf.Clamp((currentIndex + visibleItemCount) * itemsPerRow, 0, data.Count);
foreach (var item in data)
{
if (item.type == AssetLibraryItemType.folder)
{
int offset = displayData.Count % rowItemCount;
if (offset != 0)
{
int emptyCount = rowItemCount - offset;
for (int i = 0; i < emptyCount; i++)
displayData.Add(null);
}
displayData.Add(item);
displayData.Add(null);
displayData.Add(null);
}
else
{
displayData.Add(item);
}
}
int startIndex = Mathf.Clamp(currentIndex * rowItemCount, 0, displayData.Count);
int endIndex = Mathf.Clamp((currentIndex + visibleItemCount) * rowItemCount, 0, displayData.Count);
SetScrollItemUI(startIndex, endIndex);
}
private void SetScrollItemUI(int startIndex, int endIndex)
{
int itemsPerRow = 3;
float spacingX = 10f;
float spacingX = 25f;
float spacingY = 10f;
RectTransform viewport = scrollRect.GetComponent<RectTransform>();
float contentWidth = viewport.sizeDelta.x;
float itemWidth = (contentWidth - spacingX * (itemsPerRow - 1)) / itemsPerRow;
float itemWidth = itemPrefab.GetComponent<RectTransform>().sizeDelta.x;
int rowCount = Mathf.CeilToInt((float)data.Count / itemsPerRow);
float totalHeight = rowCount * (itemHeight + spacingY);
int allRowItemCount = Mathf.CeilToInt(data.Count / rowItemCount);
float totalHeight = allRowItemCount * (itemHeight + spacingY);
content.sizeDelta = new Vector2(contentWidth, totalHeight);
for (int i = startIndex; i < endIndex; i++)
{
AssetLibraryItem item = data[i];
AssetLibraryScrollItemUI itemUI = GetItemUI();
itemUI.SetItemData(item);
itemUI.SetSelected(selectedItems);
itemUI.transform.SetParent(content, false);
AssetLibraryItem item = displayData[i];
int row = i / itemsPerRow;
int col = i % itemsPerRow;
if (item == null)
continue;
float x = col * (itemWidth + spacingX) - ((itemsPerRow - 1) * (itemWidth + spacingX)) / 2f;
RectTransform itemRt;
if (item.type == AssetLibraryItemType.folder)
{
AssetLibraryScrollFolderUI itemUI = foldersPool.Get();
itemUI.SetItemData(item);
itemUI.transform.SetParent(content, false);
itemRt = itemUI.GetComponent<RectTransform>();
activeFolders.Add(itemUI);
}
else
{
AssetLibraryScrollItemUI itemUI = GetItemUI();
itemUI.SetItemData(item);
itemUI.SetSelected(selectedItems);
itemUI.transform.SetParent(content, false);
itemRt = itemUI.GetComponent<RectTransform>();
activeItems.Add(itemUI);
}
int row = i / rowItemCount;
int col = i % rowItemCount;
float x = col * (itemWidth + spacingX) - ((rowItemCount - 1) * (itemWidth + spacingX)) / 2f;
float y = -row * (itemHeight + spacingY) - itemHeight / 2f;
RectTransform rt = itemUI.GetComponent<RectTransform>();
rt.sizeDelta = new Vector2(itemWidth, itemHeight);
rt.anchoredPosition = new Vector2(x, y);
activeItems.Add(itemUI);
itemRt.sizeDelta = new Vector2(itemWidth, itemHeight);
itemRt.anchoredPosition = new Vector2(x, y);
}
}
private AssetLibraryScrollItemUI GetItemUI()
{
AssetLibraryScrollItemUI itemUI = pool.Get();
AssetLibraryScrollItemUI itemUI = itemsPool.Get();
itemUI.onClickSingle.RemoveAllListeners();
itemUI.onClickSingle.AddListener(OnSelectSingle);
itemUI.onClickAddSingle.RemoveAllListeners();

View File

@@ -0,0 +1,14 @@
using TMPro;
namespace XED.AssetLibraryTree
{
public class AssetLibraryScrollFolderUI : UnityEngine.MonoBehaviour
{
public TMP_Text nameText;
public void SetItemData(AssetLibraryItem item)
{
nameText.text = item.name;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 375b7e03a026c414f9dee53d411b35bc

View File

@@ -1,15 +1,12 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using System;
using XRLib;
using XED.Manage;
using XED.Util;
using static Unity.Cinemachine.CinemachineSplineRoll;
namespace XED.AssetLibraryTree
{
@@ -57,8 +54,6 @@ namespace XED.AssetLibraryTree
thumbnail.gameObject.SetActive(item.type != AssetLibraryItemType.folder);
thumbnail.texture = data != null ? data.thumbnail : null;
//if (texture != null) thumbnail.texture = texture;
expandButton.image.sprite = currentItem.isExpanded == true ? spriteExpanded : spriteCollapsed;
float width = nameText.GetComponent<RectTransform>().sizeDelta.x + thumbnail.GetComponent<RectTransform>().sizeDelta.x;