com.soviby.unity.ui.ugui-to.../Assets/Editor/Manager/EntityManager.cs
2024-11-28 18:34:17 +08:00

401 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#if UNITY_EDITOR
using Sirenix.OdinInspector;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using static UguiToolkit.Editor.LayoutInfo;
namespace UguiToolkit.Editor
{
[ExecuteAlways]
public class EntityManager : MonoBehaviour, IManager
{
private PanelCache m_panelCache;
private Transform m_entityRoot;
private GameObject m_lastSelectionGo;
private IEntity m_lastSelectionEntity;
private GameObject m_curSelectionGo;
private List<ImageEntity> m_imageEntities;
private List<TextEntity> m_textEntities;
private List<TextMeshProEntity> m_tmpEntities;
private List<IEntity> m_selectionEntities;
[LabelText("脱离选择控制"), ShowInInspector]
private bool m_noSelection;
private StageManager m_stageManager;
private HashSet<string> m_checkImgPaths;
private float m_lastCheckTime;
private bool m_useTMP;
private const float m_checkInterval = 2f;
private void OnEnable()
{
var globalMng = GlobalManager.Instance;
globalMng.showHierarchyOfEntityChanged += OnUpdateHierarchyOfEntityAllEntity;
m_useTMP = globalMng.setting.useTMP;
Selection.selectionChanged += OnSelectionChanged;
m_stageManager = StageManager.Instance;
}
private void OnDisable()
{
GlobalManager.Instance.showHierarchyOfEntityChanged -= OnUpdateHierarchyOfEntityAllEntity;
Selection.selectionChanged -= OnSelectionChanged;
}
private void Update()
{
// 检测是否到达可选实例矩形内部
if (m_selectionEntities != null && m_curSelectionGo)
{
if (m_lastSelectionGo && m_lastSelectionGo == m_curSelectionGo)
{
if (m_lastSelectionEntity != null && !m_lastSelectionEntity.IsInside(m_lastSelectionGo.transform))
{
m_lastSelectionGo = null;
m_lastSelectionEntity = null;
}
return;
}
foreach (var entity in m_selectionEntities)
{
var tf = m_curSelectionGo.transform;
if (entity.IsInside(tf))
{
entity.ApplyTransform(tf);
if (tf.TryGetComponent<UnityEngine.UI.Image>(out var image))
{
entity.ApplyData(image);
}
else if (tf.TryGetComponent<UnityEngine.UI.Text>(out var text))
{
entity.ApplyData(text);
}
m_lastSelectionGo = m_curSelectionGo;
m_lastSelectionEntity = entity;
Selection.activeGameObject = null;
break;
}
}
}
// 检测是否有image变更及时更新PanelCache
m_lastCheckTime += Time.deltaTime;
if (m_lastCheckTime > m_checkInterval)
{
m_lastCheckTime = 0;
if (m_checkImgPaths != null)
{
var images = m_stageManager.PrefabContentsRoot.GetComponentsInChildren<UnityEngine.UI.Image>();
foreach (var image in images)
{
if (image.transform.parent == m_entityRoot || image.sprite == null) continue;
var srcImgPath = AssetDatabase.GetAssetPath(image.sprite);
if (!m_checkImgPaths.Contains(srcImgPath))
{
var srcImgDirPath = System.IO.Path.GetDirectoryName(srcImgPath);
string projectPath = Directory.GetParent(Application.dataPath).FullName;
foreach (var filePath in System.IO.Directory.GetFiles(srcImgDirPath))
{
var _filePath = Path.GetRelativePath(projectPath, filePath).Replace("\\", "/");
m_checkImgPaths.Add(_filePath);
}
UpdatePanelCache(srcImgDirPath, m_panelCache.TargetImgDirPath);
break;
}
}
}
}
}
private void InitCheckImgPaths()
{
if (m_checkImgPaths == null) m_checkImgPaths = new HashSet<string>();
var images = m_stageManager.PrefabContentsRoot.GetComponentsInChildren<UnityEngine.UI.Image>();
foreach (var image in images)
{
if (image.sprite == null) continue;
var srcImgPath = AssetDatabase.GetAssetPath(image.sprite);
m_checkImgPaths.Add(srcImgPath);
}
}
private void UpdatePanelCache(string srcImgDirPath, string targetImgDirPath)
{
float distanceDifference = GlobalManager.Instance.setting.distanceDifference;
CacheScriptObject.CalcRotScaleInfos(srcImgDirPath, targetImgDirPath, distanceDifference,(rotScaleInfoMap) =>
{
if (!m_stageManager) return;
// 拷贝数据
if (m_panelCache.rotScaleInfos != null)
{
foreach (var kv in rotScaleInfoMap)
{
if (!m_panelCache.rotScaleInfos.TryGetValue(kv.Key, out var rotScaleInfos))
{
m_panelCache.rotScaleInfos[kv.Key] = kv.Value;
}
}
} else
{
m_panelCache.rotScaleInfos = rotScaleInfoMap;
}
// 保存缓存
GlobalManager.Instance.SaveCache(m_stageManager.PrefabAsset, m_panelCache);
});
}
private void OnSelectionChanged()
{
m_curSelectionGo = null;
m_selectionEntities.Clear();
m_entityRoot.gameObject.SetActive(false);
if (m_noSelection) return;
if (Selection.activeGameObject != null && m_panelCache != null)
{
var activeGameObject = Selection.activeGameObject;
if (activeGameObject.transform.parent == m_entityRoot) return;
if (activeGameObject.TryGetComponent<UnityEngine.UI.Image>(out var image))
{
var rotScaleInfos = m_panelCache.rotScaleInfos;
if (rotScaleInfos == null) return;
if (image.sprite == null) return;
var srcImgPath = AssetDatabase.GetAssetPath(image.sprite);
if (!rotScaleInfos.TryGetValue(srcImgPath, out var rotScaleInfoItems)) return;
m_entityRoot.gameObject.SetActive(true);
bool isFind;
bool IsInside = false;
foreach (var imgEntity in m_imageEntities)
{
isFind = false;
foreach (var rotScale in rotScaleInfoItems)
{
var imgInfo = imgEntity.ElementInfo;
if (imgInfo.imgPath == rotScale.imgPath)
{
if (rotScale.similarityCalc)
{
imgEntity.SetTransform(0, new Unity.Mathematics.float2(1, 1), true);
}
else {
imgEntity.SetTransform(rotScale.rotiation, rotScale.scale, false);
}
imgEntity.ShowSelectionImg(true);
m_selectionEntities.Add(imgEntity);
if (!IsInside && imgEntity.IsInside(activeGameObject.transform)) IsInside = true;
isFind = true;
break;
}
}
imgEntity.gameObject.SetActive(isFind);
}
if (IsInside)
{
if (m_lastSelectionGo && m_lastSelectionGo == activeGameObject)
{
m_curSelectionGo = activeGameObject;
}
}
else {
m_curSelectionGo = activeGameObject;
}
foreach (var textEntity in m_textEntities)
{
textEntity.gameObject.SetActive(false);
}
foreach (var textEntity in m_tmpEntities)
{
textEntity.gameObject.SetActive(false);
}
}
else if (activeGameObject.TryGetComponent<UnityEngine.UI.Text>(out var text))
{
bool IsInside = false;
m_entityRoot.gameObject.SetActive(true);
foreach (var textEntity in m_textEntities)
{
textEntity.ShowSelectionImg(true);
textEntity.gameObject.SetActive(true);
m_selectionEntities.Add(textEntity);
if (!IsInside && textEntity.IsInside(activeGameObject.transform)) IsInside = true;
}
if (IsInside)
{
if (m_lastSelectionGo && m_lastSelectionGo == activeGameObject)
{
m_curSelectionGo = activeGameObject;
}
}
else
{
m_curSelectionGo = activeGameObject;
}
foreach (var imgEntity in m_imageEntities)
{
imgEntity.gameObject.SetActive(false);
}
foreach (var textEntity in m_tmpEntities)
{
textEntity.gameObject.SetActive(false);
}
}
else if (activeGameObject.TryGetComponent<TMPro.TextMeshProUGUI>(out var tmp))
{
bool IsInside = false;
m_entityRoot.gameObject.SetActive(true);
foreach (var tmpEntity in m_tmpEntities)
{
tmpEntity.ShowSelectionImg(true);
tmpEntity.gameObject.SetActive(true);
m_selectionEntities.Add(tmpEntity);
if (!IsInside && tmpEntity.IsInside(activeGameObject.transform)) IsInside = true;
}
if (IsInside)
{
if (m_lastSelectionGo && m_lastSelectionGo == activeGameObject)
{
m_curSelectionGo = activeGameObject;
}
}
else
{
m_curSelectionGo = activeGameObject;
}
foreach (var imgEntity in m_imageEntities)
{
imgEntity.gameObject.SetActive(false);
}
foreach (var textEntity in m_textEntities)
{
textEntity.gameObject.SetActive(false);
}
}
}
}
public void InitAllEntity(PanelCache panelCache)
{
this.m_panelCache = panelCache;
// 创建所有实例
CreateAllEntity();
InitCheckImgPaths();
}
private void OnUpdateHierarchyOfEntityAllEntity(bool show)
{
UpdateHierarchyOfEntity(show, m_entityRoot.gameObject);
foreach (var entity in m_imageEntities) UpdateHierarchyOfEntity(show, entity.gameObject);
foreach (var entity in m_textEntities) UpdateHierarchyOfEntity(show, entity.gameObject);
foreach (var entity in m_tmpEntities) UpdateHierarchyOfEntity(show, entity.gameObject);
}
private void UpdateHierarchyOfEntity(in bool show, in GameObject entity)
{
EntityHelper.UpdateHierarchyAndSceneVisibilityOfEntity(show, entity.gameObject);
}
private void CreateAllEntity()
{
if (this.m_panelCache == null) return;
var go = new GameObject("__entityRoot__", typeof(RectTransform));
UpdateHierarchyOfEntity(false, go);
m_entityRoot = go.transform;
m_entityRoot.SetParent(transform);
m_entityRoot.localPosition = Vector3.zero;
m_entityRoot.localRotation = Quaternion.identity;
m_entityRoot.localScale = Vector3.one;
m_imageEntities = new(m_panelCache.layoutInfo.Count);
m_textEntities = new(m_panelCache.layoutInfo.Count);
m_tmpEntities = new(m_panelCache.layoutInfo.Count);
m_selectionEntities = new(m_panelCache.layoutInfo.Count);
foreach (var elementInfo in m_panelCache.GetLayoutElementInfos<LayoutInfo.ElementInfo>())
{
var imgInfo = elementInfo as LayoutInfo.ImageInfo;
if (imgInfo != null) // Image
{
go = new GameObject(imgInfo.name, typeof(RectTransform));
var entity = go.AddComponent<ImageEntity>();
entity.transform.SetParent(m_entityRoot);
entity.transform.SetSiblingIndex(0);
entity.SetData(imgInfo);
entity.InitPreviewImage();
m_imageEntities.Add(entity);
UpdateHierarchyOfEntity(false, entity.gameObject);
continue;
}
var textInfo = elementInfo as LayoutInfo.TextInfo;
if (textInfo != null) // Text
{
if (m_useTMP)
{
go = new GameObject(textInfo.text, typeof(RectTransform));
var entity = go.AddComponent<TextMeshProEntity>();
entity.transform.SetParent(m_entityRoot);
entity.transform.SetSiblingIndex(0);
entity.SetData(textInfo);
entity.InitPreviewText();
m_tmpEntities.Add(entity);
UpdateHierarchyOfEntity(false, entity.gameObject);
continue;
}
else
{
go = new GameObject(textInfo.text, typeof(RectTransform));
var entity = go.AddComponent<TextEntity>();
entity.transform.SetParent(m_entityRoot);
entity.transform.SetSiblingIndex(0);
entity.SetData(textInfo);
entity.InitPreviewText();
m_textEntities.Add(entity);
UpdateHierarchyOfEntity(false, entity.gameObject);
continue;
}
}
}
m_entityRoot.gameObject.SetActive(false);
}
}
}
#endif