#if UNITY_EDITOR using Sirenix.OdinInspector; using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; 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 m_imageEntities; private List m_textEntities; private List m_selectionEntities; [LabelText("脱离选择控制"), ShowInInspector] private bool m_noSelection; private StageManager m_stageManager; private HashSet 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(out var image)) { entity.ApplyData(image); } else if (tf.TryGetComponent(out var text)) { entity.ApplyData(text); } else if (tf.TryGetComponent(out var temp)) { entity.ApplyData(temp); } 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(); 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(); //var images = m_stageManager.PrefabContentsRoot.GetComponentsInChildren(); //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() { if (m_noSelection) return; m_curSelectionGo = null; m_selectionEntities.Clear(); m_entityRoot.gameObject.SetActive(false); if (Selection.activeGameObject != null && m_panelCache != null) { var activeGameObject = Selection.activeGameObject; if (activeGameObject.transform.parent == m_entityRoot) return; if (activeGameObject.TryGetComponent(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.HaveSlice && imgInfo.imgSlicePath == rotScale.imgPath) || 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.ApplyTransform(imgEntity.transform); 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); } } else if (activeGameObject.TryGetComponent(out var _) || activeGameObject.TryGetComponent(out var _)) { 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); } } } } 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); } 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; var canvas = m_entityRoot.gameObject.AddComponent(); canvas.pixelPerfect = true; canvas.overrideSorting = true; canvas.sortingOrder = 200; m_imageEntities = new(m_panelCache.layoutInfo.Count); m_textEntities = new(m_panelCache.layoutInfo.Count); m_selectionEntities = new(m_panelCache.layoutInfo.Count); foreach (var elementInfo in m_panelCache.GetLayoutElementInfos()) { var imgInfo = elementInfo as LayoutInfo.ImageInfo; if (imgInfo != null) // Image { go = new GameObject(imgInfo.name, typeof(RectTransform)); var entity = go.AddComponent(); entity.transform.SetParent(m_entityRoot); entity.transform.SetSiblingIndex(0); entity.SetData(imgInfo); entity.InitPreview(); 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(); entity.transform.SetParent(m_entityRoot); entity.transform.SetSiblingIndex(0); entity.SetData(textInfo); entity.InitPreview(); m_textEntities.Add(entity); UpdateHierarchyOfEntity(false, entity.gameObject); continue; } else { go = new GameObject(textInfo.text, typeof(RectTransform)); var entity = go.AddComponent(); entity.transform.SetParent(m_entityRoot); entity.transform.SetSiblingIndex(0); entity.SetData(textInfo); entity.InitPreview(); m_textEntities.Add(entity); UpdateHierarchyOfEntity(false, entity.gameObject); continue; } } } m_entityRoot.gameObject.SetActive(false); } } } #endif