469 lines
23 KiB
C#
469 lines
23 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using XED.UI;
|
|
using XRLib;
|
|
using XED.Manage;
|
|
using XED.Util;
|
|
using XED.Hierarchy;
|
|
using System.Linq;
|
|
|
|
namespace XED.Asset
|
|
{
|
|
public class CustomAssetConnector : MonoBehaviour, ISingle
|
|
{
|
|
private CustomScrollRect assetScrollRect;
|
|
private PooledScrollView assetScrollView;
|
|
private PooledScrollView componentScrollView;
|
|
private GameObject renderObjectPrefab;
|
|
private float objectShowDistance = 1000.0f;
|
|
|
|
private List<ConnectedAsset> connectedAssets = new List<ConnectedAsset>();
|
|
private List<CustomAssetData> selectedAssetDatas = new List<CustomAssetData>();
|
|
private CustomAssetData selectedAssetData;
|
|
private GameObject selectedItem;
|
|
private CustomAssetRenderObject selectRenderObject;
|
|
|
|
public SaveLoadFBXData saveLoadFBXData;
|
|
public RenderObjectHandler renderObjectHandler;
|
|
public event System.Action<string, List<GameObject>> onSelectObjects;
|
|
public event System.Action onDeselectObjects;
|
|
public event System.Action onRemoveObjects;
|
|
public event System.Action onAssetDropped;
|
|
void Awake()
|
|
{
|
|
saveLoadFBXData = FindFirstObjectByType<SaveLoadFBXData>();
|
|
renderObjectHandler = FindFirstObjectByType<RenderObjectHandler>();
|
|
}
|
|
void Start()
|
|
{
|
|
assetScrollRect = FindSingle<Canvas_Windows>().panel_assetlibrary.scrollRect;
|
|
assetScrollView = FindSingle<Canvas_Windows>().panel_assetlibrary.scrollView;
|
|
componentScrollView = FindSingle<Canvas_Windows>().panel_componentlibrary.scrollView;
|
|
renderObjectPrefab = Resources.Load<GameObject>("Prefabs/PRF_RenderObject");
|
|
|
|
assetScrollRect.onDragBegin.AddListener(OnAssetSelected);
|
|
assetScrollRect.onDragAndDrop.AddListener(OnAssetDropped);
|
|
assetScrollView.onSelect.AddListener(OnSelectAssetFromHierarchy);
|
|
componentScrollView.onSelect.AddListener(OnSelectObjectFromHierarchy);
|
|
componentScrollView.onParentChanged.AddListener(OnParentChanged);
|
|
saveLoadFBXData.onLoadFbxFile.AddListener(OnLoadFbxFile);
|
|
saveLoadFBXData.onRemoveFbxFile.AddListener(OnRemoveFbxFile);
|
|
renderObjectHandler.onSelectObject.AddListener(OnSelectObjectFromObjectHandler);
|
|
renderObjectHandler.onCopyObject.AddListener(OnCopyObject);
|
|
renderObjectHandler.onRemoveObject.AddListener(OnRemoveObject);
|
|
renderObjectHandler.onOrderByHierachy.AddListener(OrderByHierarchy);
|
|
renderObjectHandler.onDeselectAll += OnDeselectAll;
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
if (selectedAssetData != null)
|
|
{
|
|
Vector3? pos = GetMousePointOnYPlane(objectShowDistance);
|
|
if (pos.HasValue)
|
|
{
|
|
selectedItem.transform.position = pos.Value;
|
|
selectedAssetData.OnTransformDataChanged();
|
|
}
|
|
}
|
|
}
|
|
void CreateConnectedAsset()
|
|
{
|
|
ConnectedAsset connectedAsset = new ConnectedAsset();
|
|
connectedAsset.assetData = selectedAssetData;
|
|
connectedAsset.hierarchyItem = componentScrollView.AddItem(selectedAssetData.assetName, selectedItem, HierarchyItemType.obj);
|
|
connectedAsset.renderObject = selectRenderObject;
|
|
connectedAsset.renderObject.onTransformChanged = connectedAsset.assetData.OnTransformDataChanged;
|
|
var command = new ActionCommand(
|
|
() =>
|
|
{
|
|
if (connectedAsset.renderObject.gameObject.activeSelf == false)
|
|
{
|
|
connectedAsset.assetData.AddTransformToRender(connectedAsset.renderObject.transform);
|
|
connectedAsset.renderObject.gameObject.SetActive(true);
|
|
componentScrollView.AddItem(connectedAsset.hierarchyItem);
|
|
}
|
|
connectedAsset.renderObject.Hide();
|
|
connectedAssets.Add(connectedAsset);
|
|
},
|
|
() =>
|
|
{
|
|
connectedAssets.Remove(connectedAsset);
|
|
connectedAsset.assetData.RemoveTransform(connectedAsset.renderObject.transform);
|
|
connectedAsset.renderObject.gameObject.SetActive(false);
|
|
componentScrollView.RemoveItem(connectedAsset.hierarchyItem);
|
|
});
|
|
CommandManager.I.ExecuteCommand(command);
|
|
}
|
|
public void OnLoadFbxFile(string objectName, string folderName, CustomAssetData assetData)
|
|
{
|
|
HierarchyItem parent = assetScrollView.FindItem(folderName, HierarchyItemType.folder);
|
|
if (parent == null)
|
|
{
|
|
parent = assetScrollView.AddItem(folderName, null, HierarchyItemType.folder);
|
|
}
|
|
HierarchyItem item = assetScrollView.AddItem(objectName, assetData.gameObject, HierarchyItemType.file, parent);
|
|
assetData.onLoadProgress.RemoveAllListeners();
|
|
assetData.onLoadProgress.AddListener((x) => item.onLoadProgress?.Invoke(x));
|
|
}
|
|
public void OnRemoveFbxFile(string objectName)
|
|
{
|
|
assetScrollView.RemoveItem(objectName, HierarchyItemType.file);
|
|
}
|
|
public void OnAssetSelected(HierarchyItem item)
|
|
{
|
|
if (item == null || item.linkedObject == null)
|
|
{
|
|
selectedAssetData = null;
|
|
return;
|
|
}
|
|
selectedAssetData = item.linkedObject.GetComponent<CustomAssetData>();
|
|
if (selectedAssetData == null || selectedAssetData.isLoadComplete == false)
|
|
{
|
|
selectedAssetData = null;
|
|
return;
|
|
}
|
|
selectedItem = Instantiate(renderObjectPrefab);
|
|
selectRenderObject = selectedItem.GetComponent<CustomAssetRenderObject>();
|
|
selectRenderObject.instantiateObject = selectedAssetData.InstantiateLoadedObject;
|
|
selectRenderObject.getBounds = selectedAssetData.GetCombinedBoundary;
|
|
selectRenderObject.CreateRenderObject();
|
|
selectRenderObject.Select();
|
|
selectedAssetData.AddTransformToRender(selectedItem.transform);
|
|
}
|
|
public void OnAssetDropped(HierarchyItem item)
|
|
{
|
|
if (selectedAssetData == null)
|
|
return;
|
|
bool isPointerOutScrollRect = !assetScrollRect.IsPointerOverScrollRect();
|
|
if (item != null && isPointerOutScrollRect)
|
|
{
|
|
CreateConnectedAsset();
|
|
}
|
|
else
|
|
{
|
|
selectedAssetData.RemoveTransform(selectedItem.transform);
|
|
Destroy(selectedItem);
|
|
}
|
|
selectRenderObject.Deselect();
|
|
selectedAssetData = null;
|
|
onAssetDropped?.Invoke();
|
|
}
|
|
public void OnSelectObjectFromHierarchy(List<HierarchyItem> selectedItems)
|
|
{
|
|
if (selectedItems.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
string name = "";
|
|
List<GameObject> selectedObjects = new List<GameObject>();
|
|
foreach (ConnectedAsset connectedAsset in connectedAssets)
|
|
{
|
|
connectedAsset.renderObject.Deselect();
|
|
}
|
|
renderObjectHandler.RemoveAllSelections();
|
|
for (int i = 0; i < selectedItems.Count; i++)
|
|
{
|
|
ConnectedAsset searchAsset = connectedAssets.Find((x) => x.hierarchyItem == selectedItems[i]);
|
|
name = i == 0 ? searchAsset.hierarchyItem.name : name.Equals(searchAsset.hierarchyItem.name) ? searchAsset.hierarchyItem.name : "-";
|
|
selectedObjects.Add(searchAsset.renderObject.gameObject);
|
|
renderObjectHandler.AddSelection(searchAsset.renderObject);
|
|
}
|
|
renderObjectHandler.ResetGizmoTargetObjects();
|
|
onSelectObjects?.Invoke(name, selectedObjects);
|
|
}
|
|
public void OnSelectAssetFromHierarchy(List<HierarchyItem> selectedItems)
|
|
{
|
|
selectedAssetDatas.Clear();
|
|
if (selectedItems.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
for (int i = 0; i < selectedItems.Count; i++)
|
|
{
|
|
HierarchyItem assetItem = selectedItems[i];
|
|
CustomAssetData assetData = null;
|
|
if (assetItem.linkedObject)
|
|
{
|
|
assetItem.linkedObject.GetComponent<CustomAssetData>();
|
|
}
|
|
if (assetData != null)
|
|
{
|
|
selectedAssetDatas.Add(assetData);
|
|
}
|
|
}
|
|
}
|
|
public void OnSelectObjectFromObjectHandler(List<CustomAssetRenderObject> objects)
|
|
{
|
|
if (objects.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
string name = "";
|
|
List<GameObject> selectedObjects = new List<GameObject>();
|
|
List<HierarchyItem> selectedItems = new List<HierarchyItem>();
|
|
for (int i = 0; i < objects.Count; i++)
|
|
{
|
|
ConnectedAsset searchAsset = connectedAssets.Find((x) => x.renderObject == objects[i]);
|
|
selectedItems.Add(searchAsset.hierarchyItem);
|
|
name = i == 0 ? searchAsset.hierarchyItem.name : name.Equals(searchAsset.hierarchyItem.name) ? searchAsset.hierarchyItem.name : "-";
|
|
selectedObjects.Add(searchAsset.renderObject.gameObject);
|
|
}
|
|
componentScrollView.OnSelect(selectedItems);
|
|
onSelectObjects?.Invoke(name, selectedObjects);
|
|
}
|
|
public void OnDragBoxSelect(Rect selectionBoxRect)
|
|
{
|
|
List<ConnectedAsset> activeAssets = connectedAssets.FindAll(x => x.renderObject != null && x.renderObject.gameObject.activeSelf);
|
|
if (activeAssets.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
string name = "";
|
|
List<HierarchyItem> selectedItems = new List<HierarchyItem>();
|
|
List<CustomAssetRenderObject> selectedRenderObjects = new List<CustomAssetRenderObject>();
|
|
renderObjectHandler.RemoveAllSelections();
|
|
for (int i = 0; i < activeAssets.Count; i++)
|
|
{
|
|
ConnectedAsset activeAsset = activeAssets[i];
|
|
if (selectionBoxRect.Contains(Camera.main.WorldToScreenPoint(activeAsset.renderObject.transform.position)))
|
|
{
|
|
name = i == 0 ? activeAsset.hierarchyItem.name : name.Equals(activeAsset.hierarchyItem.name) ? activeAsset.hierarchyItem.name : "-";
|
|
selectedItems.Add(activeAsset.hierarchyItem);
|
|
selectedRenderObjects.Add(activeAsset.renderObject);
|
|
}
|
|
}
|
|
renderObjectHandler.AddSelection(selectedRenderObjects);
|
|
componentScrollView.OnSelect(selectedItems);
|
|
onSelectObjects?.Invoke(name, selectedRenderObjects.Select(x => x.gameObject).ToList());
|
|
}
|
|
public void OnRemoveObject(List<CustomAssetRenderObject> objects)
|
|
{
|
|
if (objects.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
List<ConnectedAsset> removeList = new List<ConnectedAsset>();
|
|
List<int> siblingIndex = new List<int>();
|
|
for (int i = 0; i < objects.Count; i++)
|
|
{
|
|
ConnectedAsset searchAsset = connectedAssets.Find((x) => x.renderObject == objects[i]);
|
|
removeList.Add(searchAsset);
|
|
siblingIndex.Add(searchAsset.hierarchyItem.GetSiblingIndex());
|
|
}
|
|
var command = new ActionCommand(
|
|
() =>
|
|
{
|
|
for (int i = 0; i < removeList.Count; i++)
|
|
{
|
|
ConnectedAsset connectedAsset = removeList[i];
|
|
componentScrollView.RemoveItem(connectedAsset.hierarchyItem);
|
|
connectedAsset.assetData.RemoveTransform(connectedAsset.renderObject.transform);
|
|
connectedAsset.renderObject.gameObject.SetActive(false);
|
|
|
|
List<HierarchyItem> childItems = connectedAsset.hierarchyItem.GetAll(true);
|
|
for (int k = 0; k < childItems.Count; k++)
|
|
{
|
|
ConnectedAsset searchAsset = connectedAssets.Find((x) => x.hierarchyItem == childItems[k]);
|
|
searchAsset.assetData.RemoveTransform(searchAsset.renderObject.transform);
|
|
searchAsset.renderObject.gameObject.SetActive(false);
|
|
}
|
|
}
|
|
onRemoveObjects?.Invoke();
|
|
componentScrollView.DeselectAll();
|
|
},
|
|
() =>
|
|
{
|
|
for (int i = 0; i < removeList.Count; i++)
|
|
{
|
|
ConnectedAsset connectedAsset = removeList[i];
|
|
componentScrollView.AttachItem(connectedAsset.hierarchyItem.parent, connectedAsset.hierarchyItem, siblingIndex[i]);
|
|
connectedAsset.assetData.AddTransformToRender(connectedAsset.renderObject.transform);
|
|
connectedAsset.renderObject.gameObject.SetActive(true);
|
|
}
|
|
for (int i = 0; i < removeList.Count; i++)
|
|
{
|
|
ConnectedAsset connectedAsset = removeList[i];
|
|
List<HierarchyItem> childItems = connectedAsset.hierarchyItem.GetAll(true);
|
|
for (int k = 0; k < childItems.Count; k++)
|
|
{
|
|
ConnectedAsset searchAsset = connectedAssets.Find((x) => x.hierarchyItem == childItems[k]);
|
|
searchAsset.assetData.AddTransformToRender(searchAsset.renderObject.transform);
|
|
searchAsset.renderObject.gameObject.SetActive(true);
|
|
}
|
|
}
|
|
});
|
|
CommandManager.I.ExecuteCommand(command);
|
|
}
|
|
public void OnCopyObject(List<CustomAssetRenderObject> objects)
|
|
{
|
|
if (objects.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
List<ConnectedAsset> copySources = new List<ConnectedAsset>();
|
|
List<ConnectedAsset> copyList = new List<ConnectedAsset>();
|
|
for (int i = 0; i < objects.Count; i++)
|
|
{
|
|
ConnectedAsset searchAsset = connectedAssets.Find((x) => x.renderObject == objects[i]);
|
|
copySources.Add(searchAsset);
|
|
ConnectedAsset copyAsset = new ConnectedAsset();
|
|
copyList.Add(copyAsset);
|
|
connectedAssets.Add(copyAsset);
|
|
}
|
|
var command = new ActionCommand(
|
|
() =>
|
|
{
|
|
for (int i = 0; i < copyList.Count; i++)
|
|
{
|
|
ConnectedAsset copySource = copySources[i];
|
|
ConnectedAsset copyAsset = copyList[i];
|
|
if (copyAsset.hierarchyItem == null)
|
|
{
|
|
GameObject copyObject = Instantiate(renderObjectPrefab);
|
|
copyAsset.assetData = copySource.assetData;
|
|
copyAsset.hierarchyItem = copySource.hierarchyItem.Copy();
|
|
copyAsset.renderObject = copyObject.GetComponent<CustomAssetRenderObject>();
|
|
copyAsset.renderObject.getBounds = copySource.assetData.GetCombinedBoundary;
|
|
copyAsset.renderObject.onTransformChanged = copySource.assetData.OnTransformDataChanged;
|
|
copyAsset.renderObject.instantiateObject = copySource.assetData.InstantiateLoadedObject;
|
|
copyAsset.renderObject.CreateRenderObject();
|
|
copyAsset.renderObject.transform.position = copySource.renderObject.transform.position;
|
|
copyAsset.renderObject.transform.rotation = copySource.renderObject.transform.rotation;
|
|
copyAsset.renderObject.transform.localScale = copySource.renderObject.transform.localScale;
|
|
|
|
List<Transform> lastParent = new List<Transform>();
|
|
for (int j = 0; j < copyAsset.hierarchyItem.layerNum + 1; j++)
|
|
{
|
|
lastParent.Add(copyAsset.renderObject.transform);
|
|
}
|
|
|
|
List<HierarchyItem> srcChildren = copySource.hierarchyItem.GetAll(true);
|
|
List<HierarchyItem> dstChildren = copyAsset.hierarchyItem.GetAll(true);
|
|
for (int k = 0; k < srcChildren.Count; k++)
|
|
{
|
|
ConnectedAsset childSource = connectedAssets.Find((x) => x.hierarchyItem == srcChildren[k]);
|
|
GameObject copyChildObject = Instantiate(renderObjectPrefab);
|
|
ConnectedAsset childAsset = new ConnectedAsset();
|
|
childAsset.assetData = childSource.assetData;
|
|
childAsset.hierarchyItem = dstChildren[k];
|
|
childAsset.renderObject = copyChildObject.GetComponent<CustomAssetRenderObject>(); ;
|
|
childAsset.renderObject.getBounds = childAsset.assetData.GetCombinedBoundary;
|
|
childAsset.renderObject.onTransformChanged = childAsset.assetData.OnTransformDataChanged;
|
|
childAsset.renderObject.instantiateObject = copySource.assetData.InstantiateLoadedObject;
|
|
childAsset.renderObject.CreateRenderObject();
|
|
childAsset.renderObject.transform.position = childSource.renderObject.transform.position;
|
|
childAsset.renderObject.transform.rotation = childSource.renderObject.transform.rotation;
|
|
childAsset.renderObject.transform.localScale = childSource.renderObject.transform.localScale;
|
|
childAsset.renderObject.transform.parent = lastParent[childAsset.hierarchyItem.layerNum - 1];
|
|
if (lastParent.Count <= childAsset.hierarchyItem.layerNum)
|
|
{
|
|
lastParent.Add(childAsset.renderObject.transform);
|
|
}
|
|
else
|
|
{
|
|
lastParent[childAsset.hierarchyItem.layerNum] = childAsset.renderObject.transform;
|
|
}
|
|
connectedAssets.Add(childAsset);
|
|
}
|
|
}
|
|
copyAsset.assetData.AddTransformToRender(copyAsset.renderObject.transform);
|
|
copyAsset.renderObject.gameObject.SetActive(true);
|
|
copyAsset.renderObject.Hide();
|
|
componentScrollView.AddItem(copyAsset.hierarchyItem);
|
|
}
|
|
for (int i = 0; i < copyList.Count; i++)
|
|
{
|
|
ConnectedAsset connectedAsset = copyList[i];
|
|
List<HierarchyItem> childItems = connectedAsset.hierarchyItem.GetAll(true);
|
|
for (int k = 0; k < childItems.Count; k++)
|
|
{
|
|
ConnectedAsset searchAsset = connectedAssets.Find((x) => x.hierarchyItem == childItems[k]);
|
|
searchAsset.assetData.AddTransformToRender(searchAsset.renderObject.transform);
|
|
searchAsset.renderObject.gameObject.SetActive(true);
|
|
}
|
|
}
|
|
},
|
|
() =>
|
|
{
|
|
for (int i = 0; i < copyList.Count; i++)
|
|
{
|
|
ConnectedAsset connectedAsset = copyList[i];
|
|
componentScrollView.RemoveItem(connectedAsset.hierarchyItem);
|
|
connectedAsset.assetData.RemoveTransform(connectedAsset.renderObject.transform);
|
|
connectedAsset.renderObject.gameObject.SetActive(false);
|
|
|
|
List<HierarchyItem> childItems = connectedAsset.hierarchyItem.GetAll(true);
|
|
for (int k = 0; k < childItems.Count; k++)
|
|
{
|
|
ConnectedAsset searchAsset = connectedAssets.Find((x) => x.hierarchyItem == childItems[k]);
|
|
searchAsset.assetData.RemoveTransform(searchAsset.renderObject.transform);
|
|
searchAsset.renderObject.gameObject.SetActive(false);
|
|
}
|
|
}
|
|
onRemoveObjects?.Invoke();
|
|
componentScrollView.DeselectAll();
|
|
});
|
|
CommandManager.I.ExecuteCommand(command);
|
|
}
|
|
public void OnParentChanged(HierarchyItem parentItem, HierarchyItem childItem)
|
|
{
|
|
ConnectedAsset parentAsset = connectedAssets.Find((x) => x.hierarchyItem == parentItem);
|
|
ConnectedAsset childAsset = connectedAssets.Find((x) => x.hierarchyItem == childItem);
|
|
if (childAsset == null || childAsset.renderObject == null)
|
|
{
|
|
return;
|
|
}
|
|
if (parentAsset == null || parentAsset.renderObject == null)
|
|
{
|
|
childAsset.renderObject.transform.parent = null;
|
|
return;
|
|
}
|
|
childAsset.renderObject.transform.parent = parentAsset.renderObject.transform;
|
|
}
|
|
public void OnDeselectAll()
|
|
{
|
|
onDeselectObjects?.Invoke();
|
|
componentScrollView.DeselectAll();
|
|
}
|
|
public void SaveSelectedAssetDatasToLocal()
|
|
{
|
|
saveLoadFBXData.SaveToLocalData(selectedAssetDatas);
|
|
}
|
|
public void LoadLocalAssetDatas()
|
|
{
|
|
saveLoadFBXData.LoadLocalData();
|
|
}
|
|
public void OrderByHierarchy(List<CustomAssetRenderObject> objectsToOrder)
|
|
{
|
|
SortedDictionary<int, CustomAssetRenderObject> itemToObject = new SortedDictionary<int, CustomAssetRenderObject>();
|
|
for (int i = 0; i < objectsToOrder.Count; i++)
|
|
{
|
|
CustomAssetRenderObject objectToOrder = objectsToOrder[i];
|
|
ConnectedAsset connectedAsset = connectedAssets.Find(x => x.renderObject == objectToOrder);
|
|
itemToObject.Add(componentScrollView.GetItemIndex(connectedAsset.hierarchyItem), objectToOrder);
|
|
}
|
|
objectsToOrder = itemToObject.Values.ToList();
|
|
}
|
|
Vector3? GetMousePointOnYPlane(float maxDistance)
|
|
{
|
|
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
|
Plane yPlane = new Plane(Vector3.up, Vector3.zero);
|
|
if (yPlane.Raycast(ray, out float distance))
|
|
{
|
|
if (distance <= maxDistance)
|
|
{
|
|
return ray.GetPoint(distance);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
public class ConnectedAsset
|
|
{
|
|
public HierarchyItem hierarchyItem;
|
|
public CustomAssetData assetData;
|
|
public CustomAssetRenderObject renderObject;
|
|
}
|
|
} |