com.soviby.unity.ui.ugui-to.../Assets/Editor/Manager/EntityManager.cs

555 lines
21 KiB
C#
Raw Normal View History

2024-10-23 17:30:59 +00:00
#if UNITY_EDITOR
2024-10-29 17:51:06 +00:00
using Sirenix.OdinInspector;
2024-12-03 05:05:13 +00:00
using System;
2024-10-28 16:31:38 +00:00
using System.Collections.Generic;
2024-12-02 17:47:50 +00:00
using System.Globalization;
using System.IO;
2024-12-03 05:05:13 +00:00
using TMPro;
2024-10-29 17:51:06 +00:00
using UnityEditor;
using UnityEditor.SceneManagement;
2024-10-23 17:30:59 +00:00
using UnityEngine;
2024-12-02 17:47:50 +00:00
using UnityEngine.UI;
2024-12-06 10:46:00 +00:00
using UguiToolkit.Editor.Windows;
2024-10-23 17:30:59 +00:00
namespace UguiToolkit.Editor
{
2024-10-28 16:31:38 +00:00
[ExecuteAlways]
2024-10-23 17:30:59 +00:00
public class EntityManager : MonoBehaviour, IManager
{
private PanelCache m_panelCache;
private Transform m_entityRoot;
2024-12-02 17:47:50 +00:00
private Transform m_background;
private GameObject m_lastSelectionGo;
private IEntity m_lastSelectionEntity;
2024-11-06 17:45:57 +00:00
private GameObject m_curSelectionGo;
2024-10-23 17:30:59 +00:00
private List<ImageEntity> m_imageEntities;
2024-12-01 16:33:27 +00:00
private List<IEntity> m_textEntities;
2024-12-06 10:46:00 +00:00
private List<PrefabEntity> m_prefabEntities;
private List<IEntity> m_selectionEntities;
2024-10-28 16:31:38 +00:00
2024-12-06 10:46:00 +00:00
[LabelText("脱离选择控制"), ShowInInspector, SerializeField]
private bool m_noSelection;
private StageManager m_stageManager;
2024-12-06 10:46:00 +00:00
2024-11-28 10:34:17 +00:00
private bool m_useTMP;
2024-12-06 10:46:00 +00:00
private EditWindow editWindow;
private string m_runningImgDirPath = null;
private List<string> m_preCheckImgDirPaths = new ();
public Transform Background => m_background;
2024-10-29 17:51:06 +00:00
private void OnEnable()
2024-10-28 16:31:38 +00:00
{
2024-11-28 10:34:17 +00:00
var globalMng = GlobalManager.Instance;
m_useTMP = globalMng.setting.useTMP;
2024-10-29 17:51:06 +00:00
Selection.selectionChanged += OnSelectionChanged;
m_stageManager = StageManager.Instance;
2024-12-06 10:46:00 +00:00
editWindow = EditWindow.Window;
if (editWindow != null)
{
editWindow.showHierarchyOfEntityChanged += OnUpdateHierarchyOfEntityAllEntity;
editWindow.showBackgroundChanged += OnUpdateBackgroundShow;
editWindow.createAllTextEntity += CreateAllTextEntity;
}
2024-10-29 17:51:06 +00:00
}
private void OnDisable()
{
Selection.selectionChanged -= OnSelectionChanged;
2024-12-06 10:46:00 +00:00
if (editWindow != null)
{
editWindow.showHierarchyOfEntityChanged -= OnUpdateHierarchyOfEntityAllEntity;
editWindow.showBackgroundChanged -= OnUpdateBackgroundShow;
editWindow.createAllTextEntity -= CreateAllTextEntity;
}
2024-10-29 17:51:06 +00:00
}
private void Update()
{
// 检测是否到达可选实例矩形内部
2024-11-06 17:45:57 +00:00
if (m_selectionEntities != null && m_curSelectionGo)
2024-10-29 17:51:06 +00:00
{
2024-11-06 17:45:57 +00:00
if (m_lastSelectionGo && m_lastSelectionGo == m_curSelectionGo)
2024-10-29 17:51:06 +00:00
{
if (m_lastSelectionEntity != null && !m_lastSelectionEntity.IsInside(m_lastSelectionGo.transform))
2024-10-29 17:51:06 +00:00
{
m_lastSelectionGo = null;
m_lastSelectionEntity = null;
2024-10-29 17:51:06 +00:00
}
return;
}
foreach (var entity in m_selectionEntities)
2024-10-29 17:51:06 +00:00
{
2024-11-06 17:45:57 +00:00
var tf = m_curSelectionGo.transform;
2024-10-29 17:51:06 +00:00
if (entity.IsInside(tf))
{
entity.ApplyTransform(tf);
2024-12-06 10:46:00 +00:00
if (PrefabEntity.IsPrefab(tf.gameObject))
{
entity.ApplyData(tf);
}
else if(tf.TryGetComponent<UnityEngine.UI.Image>(out var image))
2024-11-06 17:45:57 +00:00
{
entity.ApplyData(image);
}
else if (tf.TryGetComponent<UnityEngine.UI.Text>(out var text))
{
entity.ApplyData(text);
}
2024-12-02 14:14:39 +00:00
else if (tf.TryGetComponent<TMPro.TextMeshProUGUI>(out var temp))
{
entity.ApplyData(temp);
}
2024-10-29 17:51:06 +00:00
2024-12-06 10:46:00 +00:00
2024-11-06 17:45:57 +00:00
m_lastSelectionGo = m_curSelectionGo;
m_lastSelectionEntity = entity;
2024-10-29 17:51:06 +00:00
Selection.activeGameObject = null;
break;
}
}
}
2024-12-06 10:46:00 +00:00
// 及时更新PanelCache
2024-12-02 17:47:50 +00:00
CheckPanelCache();
}
2024-12-06 10:46:00 +00:00
public void AddCheckImgDirPath(string dirPath)
2024-12-02 17:47:50 +00:00
{
2024-12-06 10:46:00 +00:00
if (string.IsNullOrEmpty(dirPath)) return;
dirPath = dirPath.Replace("\\", "/");
if (m_runningImgDirPath != null && m_runningImgDirPath == dirPath) return;
2024-12-06 10:46:00 +00:00
if (m_panelCache.IsValidOfImgDirPath(dirPath))
{
return;
}
if (Directory.Exists(dirPath))
{
if (m_preCheckImgDirPaths.Contains(dirPath))
{
2024-12-06 10:46:00 +00:00
m_preCheckImgDirPaths.Remove(dirPath);
}
2024-12-06 10:46:00 +00:00
Debug.Log($"[I] AddCheckImgDirPath {dirPath}");
m_preCheckImgDirPaths.Insert(0, dirPath);
}
}
private string GetCheckImgDirPath()
{
if (m_preCheckImgDirPaths.Count > 0)
{
string dirPath = m_preCheckImgDirPaths[0];
m_preCheckImgDirPaths.RemoveAt(0);
if (Directory.Exists(dirPath))
{
return dirPath;
}
}
return null;
}
private void CheckPanelCache()
{
if (m_runningImgDirPath == null)
{
var srcImgDirPath = GetCheckImgDirPath();
if (srcImgDirPath != null)
{
UpdatePanelCache(srcImgDirPath, m_panelCache.TargetImgDirPath);
}
2024-10-29 17:51:06 +00:00
}
2024-10-28 16:31:38 +00:00
}
2024-12-03 05:05:13 +00:00
private void CreateAllTextEntity()
{
var root = m_stageManager.PrefabContentsRoot;
var textsTf = root.transform.Find("__texts__");
if (textsTf) DestroyImmediate(textsTf.gameObject);
if (m_textEntities == null) return;
var textsGo = new GameObject("__texts__", typeof(RectTransform));
textsGo.transform.parent = root.transform;
Type textType = m_useTMP ? typeof(TextMeshProUGUI) : typeof(Text);
foreach (var textEntity in m_textEntities)
{
var newText = new GameObject(textEntity.gameObject.name, typeof(RectTransform), textType);
newText.transform.parent = textsGo.transform;
textEntity.ApplyData(newText.GetComponent(textType));
textEntity.ApplyTransform(newText.transform);
}
}
2024-12-02 17:47:50 +00:00
private void InitBackground()
{
if (m_background) DestroyImmediate(m_background.gameObject);
var go = new GameObject("__background__", typeof(RectTransform));
UpdateHierarchyOfEntity(false, go);
m_background = go.transform;
m_background.SetParent(transform);
m_background.localPosition = Vector3.zero;
m_background.localRotation = Quaternion.identity;
m_background.localScale = Vector3.one;
var canvas = m_background.gameObject.AddComponent<Canvas>();
canvas.pixelPerfect = true;
canvas.overrideSorting = true;
canvas.sortingOrder = -100;
var imgGo = new GameObject("_", typeof(RectTransform));
var imgTf = imgGo.transform;
imgTf.SetParent(m_background);
imgTf.localPosition = Vector3.zero;
imgTf.localRotation = Quaternion.identity;
imgTf.localScale = Vector3.one;
var img = imgGo.AddComponent<Image>();
var imgPath = System.IO.Path.Join(m_panelCache.TargetImgDirPath, "__background__.png");
if (System.IO.File.Exists(imgPath))
{
byte[] fileData = System.IO.File.ReadAllBytes(imgPath);
Texture2D texture = new Texture2D(2, 2);
texture.LoadImage(fileData); // 加载图片数据到Texture2D
Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
img.sprite = sprite;
2024-12-06 10:46:00 +00:00
img.color = new Color(1, 1, 1, 0.2f);
2024-12-02 17:47:50 +00:00
img.SetNativeSize();
}
2024-12-06 10:46:00 +00:00
UpdateHierarchyOfEntity(false, imgGo);
}
2024-12-06 10:46:00 +00:00
public void UpdatePanelCache(string srcImgDirPath, string targetImgDirPath)
{
2024-11-07 16:16:28 +00:00
float distanceDifference = GlobalManager.Instance.setting.distanceDifference;
2024-12-06 10:46:00 +00:00
m_runningImgDirPath = srcImgDirPath;
2024-11-07 16:16:28 +00:00
CacheScriptObject.CalcRotScaleInfos(srcImgDirPath, targetImgDirPath, distanceDifference,(rotScaleInfoMap) =>
{
2024-12-06 10:46:00 +00:00
m_runningImgDirPath = null;
if (!m_stageManager) return;
2024-12-06 10:46:00 +00:00
m_panelCache.AddImgDirPathTimestamp(srcImgDirPath);
m_panelCache.ClearRotScaleInfoItem(srcImgDirPath);
// 拷贝数据
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);
});
}
2024-10-29 17:51:06 +00:00
private void OnSelectionChanged()
2024-10-28 16:31:38 +00:00
{
2024-12-06 10:46:00 +00:00
if (m_noSelection || !Selection.activeGameObject || Selection.gameObjects.Length > 1) return;
if (Selection.activeGameObject == m_curSelectionGo || !Selection.activeGameObject.activeSelf) return;
2024-12-02 14:14:39 +00:00
2024-12-06 10:46:00 +00:00
var activeGameObject = Selection.activeGameObject;
if (activeGameObject.transform.parent == m_entityRoot || activeGameObject.transform.parent == m_background)
return;
2024-11-06 17:45:57 +00:00
m_curSelectionGo = null;
m_selectionEntities.Clear();
2024-11-06 17:45:57 +00:00
m_entityRoot.gameObject.SetActive(false);
2024-10-29 17:51:06 +00:00
2024-12-06 10:46:00 +00:00
2024-10-29 17:51:06 +00:00
if (Selection.activeGameObject != null && m_panelCache != null)
{
2024-12-06 10:46:00 +00:00
if (PrefabEntity.IsCommonPrefab(activeGameObject))
2024-10-29 17:51:06 +00:00
{
2024-11-06 17:45:57 +00:00
bool IsInside = false;
2024-12-06 10:46:00 +00:00
m_entityRoot.gameObject.SetActive(true);
foreach (var prefabEntity in m_prefabEntities)
2024-10-29 17:51:06 +00:00
{
2024-12-06 10:46:00 +00:00
prefabEntity.ShowSelectionImg(true);
prefabEntity.gameObject.SetActive(true);
2024-10-29 17:51:06 +00:00
2024-12-06 10:46:00 +00:00
m_selectionEntities.Add(prefabEntity);
2024-11-06 17:45:57 +00:00
2024-12-06 10:46:00 +00:00
if (!IsInside && prefabEntity.IsInside(activeGameObject.transform)) IsInside = true;
2024-10-29 17:51:06 +00:00
}
2024-11-06 17:45:57 +00:00
if (IsInside)
{
if (m_lastSelectionGo && m_lastSelectionGo == activeGameObject)
{
m_curSelectionGo = activeGameObject;
}
}
2024-12-06 10:46:00 +00:00
else
{
2024-11-06 17:45:57 +00:00
m_curSelectionGo = activeGameObject;
}
2024-12-06 10:46:00 +00:00
foreach (var imgEntity in m_imageEntities)
{
imgEntity.gameObject.SetActive(false);
}
foreach (var textEntity in m_textEntities)
2024-10-29 17:51:06 +00:00
{
textEntity.gameObject.SetActive(false);
}
}
2024-12-06 10:46:00 +00:00
else if (activeGameObject.TryGetComponent<Image>(out var image))
{
var rotScaleInfos = m_panelCache.rotScaleInfos;
var srcImgPath = AssetDatabase.GetAssetPath(image.sprite);
if (rotScaleInfos != null && image.sprite != null && rotScaleInfos.TryGetValue(srcImgPath, out var rotScaleInfoItems))
{
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);
}
foreach (var prefabEntity in m_prefabEntities)
{
prefabEntity.gameObject.SetActive(false);
}
}
}
else if (activeGameObject.TryGetComponent<UnityEngine.UI.Text>(out var _)
2024-12-02 14:14:39 +00:00
|| activeGameObject.TryGetComponent<TMPro.TextMeshProUGUI>(out var _))
2024-10-29 17:51:06 +00:00
{
2024-11-06 17:45:57 +00:00
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;
}
2024-10-29 17:51:06 +00:00
2024-11-06 17:45:57 +00:00
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);
}
2024-12-06 10:46:00 +00:00
foreach (var prefabEntity in m_prefabEntities)
{
prefabEntity.gameObject.SetActive(false);
}
}
}
if (activeGameObject.transform.parent != m_entityRoot && activeGameObject.transform.parent != m_background)
{
if (activeGameObject.TryGetComponent<Image>(out var image) && image.IsActive() && image.sprite)
{
var srcImgPath = AssetDatabase.GetAssetPath(image.sprite);
if (!string.IsNullOrEmpty(srcImgPath))
{
var srcImgDirPath = System.IO.Path.GetDirectoryName(srcImgPath);
AddCheckImgDirPath(srcImgDirPath);
}
2024-10-29 17:51:06 +00:00
}
}
2024-10-28 16:31:38 +00:00
}
2024-10-23 17:30:59 +00:00
public void InitAllEntity(PanelCache panelCache)
{
this.m_panelCache = panelCache;
2024-12-03 05:05:13 +00:00
this.m_stageManager = StageManager.Instance;
2024-10-23 17:30:59 +00:00
// 创建所有实例
CreateAllEntity();
2024-12-02 17:47:50 +00:00
InitBackground();
2024-10-23 17:30:59 +00:00
}
2024-12-03 05:05:13 +00:00
private void OnUpdateBackgroundShow(bool show)
{
if (m_background)
{
m_background.gameObject.SetActive(show);
}
}
2024-10-29 17:51:06 +00:00
private void OnUpdateHierarchyOfEntityAllEntity(bool show)
2024-10-28 16:31:38 +00:00
{
UpdateHierarchyOfEntity(show, m_entityRoot.gameObject);
2024-12-02 17:47:50 +00:00
UpdateHierarchyOfEntity(show, m_background.gameObject);
foreach (var entity in m_imageEntities) UpdateHierarchyOfEntity(show, entity.gameObject);
foreach (var entity in m_textEntities) UpdateHierarchyOfEntity(show, entity.gameObject);
2024-10-28 16:31:38 +00:00
}
private void UpdateHierarchyOfEntity(in bool show, in GameObject entity)
{
2024-10-29 17:51:06 +00:00
EntityHelper.UpdateHierarchyAndSceneVisibilityOfEntity(show, entity.gameObject);
2024-10-28 16:31:38 +00:00
}
2024-10-23 17:30:59 +00:00
private void CreateAllEntity()
{
if (this.m_panelCache == null) return;
2024-12-06 10:46:00 +00:00
var go = new GameObject("__entityRoot__", typeof(RectTransform));
2024-10-28 16:31:38 +00:00
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;
2024-10-28 16:31:38 +00:00
2024-12-02 14:14:39 +00:00
var canvas = m_entityRoot.gameObject.AddComponent<Canvas>();
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);
2024-12-06 10:46:00 +00:00
m_prefabEntities = new(m_panelCache.layoutInfo.Count);
2024-10-28 16:31:38 +00:00
foreach (var elementInfo in m_panelCache.GetLayoutElementInfos<LayoutInfo.ElementInfo>())
2024-10-23 17:30:59 +00:00
{
2024-10-28 16:31:38 +00:00
var imgInfo = elementInfo as LayoutInfo.ImageInfo;
if (imgInfo != null) // Image
{
2024-11-28 10:34:17 +00:00
go = new GameObject(imgInfo.name, typeof(RectTransform));
2024-10-28 16:31:38 +00:00
var entity = go.AddComponent<ImageEntity>();
entity.transform.SetParent(m_entityRoot);
2024-10-28 16:31:38 +00:00
entity.transform.SetSiblingIndex(0);
2024-10-23 17:30:59 +00:00
2024-10-28 16:31:38 +00:00
entity.SetData(imgInfo);
2024-12-01 16:33:27 +00:00
entity.InitPreview();
2024-10-28 16:31:38 +00:00
m_imageEntities.Add(entity);
2024-10-28 16:31:38 +00:00
UpdateHierarchyOfEntity(false, entity.gameObject);
2024-12-06 10:46:00 +00:00
continue;
}
2024-12-01 16:33:27 +00:00
2024-12-06 10:46:00 +00:00
var prefabInfo = elementInfo as LayoutInfo.PrefabInfo;
if (prefabInfo != null) // 预制体
{
go = new GameObject(prefabInfo.name, typeof(RectTransform));
var entity = go.AddComponent<PrefabEntity>();
entity.transform.SetParent(m_entityRoot);
entity.transform.SetSiblingIndex(0);
entity.SetData(prefabInfo);
entity.InitPreview();
m_prefabEntities.Add(entity);
UpdateHierarchyOfEntity(false, entity.gameObject);
2024-10-28 16:31:38 +00:00
continue;
}
2024-12-06 10:46:00 +00:00
2024-10-28 16:31:38 +00:00
var textInfo = elementInfo as LayoutInfo.TextInfo;
if (textInfo != null) // Text
{
2024-11-28 10:34:17 +00:00
if (m_useTMP)
{
go = new GameObject(textInfo.text, typeof(RectTransform));
var entity = go.AddComponent<TextMeshProEntity>();
entity.transform.SetParent(m_entityRoot);
entity.transform.SetSiblingIndex(0);
2024-10-28 16:31:38 +00:00
2024-11-28 10:34:17 +00:00
entity.SetData(textInfo);
2024-12-01 16:33:27 +00:00
entity.InitPreview();
2024-10-23 17:30:59 +00:00
2024-12-01 16:33:27 +00:00
m_textEntities.Add(entity);
2024-11-28 10:34:17 +00:00
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);
2024-10-28 16:31:38 +00:00
2024-11-28 10:34:17 +00:00
entity.SetData(textInfo);
2024-12-01 16:33:27 +00:00
entity.InitPreview();
2024-11-28 10:34:17 +00:00
m_textEntities.Add(entity);
UpdateHierarchyOfEntity(false, entity.gameObject);
continue;
}
}
2024-10-28 16:31:38 +00:00
}
2024-10-29 17:51:06 +00:00
m_entityRoot.gameObject.SetActive(false);
2024-10-23 17:30:59 +00:00
}
}
}
#endif