添加 图片旋转和缩放计算试试更新
Before Width: | Height: | Size: 850 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.4 MiB |
Before Width: | Height: | Size: 265 KiB |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 878 KiB |
Before Width: | Height: | Size: 665 KiB |
Before Width: | Height: | Size: 92 KiB |
Before Width: | Height: | Size: 127 KiB |
Before Width: | Height: | Size: 665 KiB |
@ -16,6 +16,7 @@ namespace UguiToolkit.Editor
|
||||
public string targetPath;
|
||||
public float rot;
|
||||
public float[] scale;
|
||||
public bool similarityCalc;
|
||||
}
|
||||
}
|
||||
#endif
|
@ -8,7 +8,7 @@ namespace UguiToolkit.Editor
|
||||
{
|
||||
public interface IEntity
|
||||
{
|
||||
void SetTransform(float rotiation, float2 scale);
|
||||
void SetTransform(float rotiation, float2 scale, bool similarityCalc);
|
||||
void ApplyTransform(Transform tf);
|
||||
bool IsInside(Transform tf);
|
||||
}
|
||||
@ -23,6 +23,8 @@ namespace UguiToolkit.Editor
|
||||
[ShowInInspector]
|
||||
private float2 scale;
|
||||
[ShowInInspector]
|
||||
private bool similarityCalc;
|
||||
[ShowInInspector]
|
||||
private bool needFillTransform;
|
||||
private UnityEngine.UI.Image m_selectionImg;
|
||||
|
||||
@ -47,18 +49,31 @@ namespace UguiToolkit.Editor
|
||||
{
|
||||
if (needFillTransform)
|
||||
{
|
||||
tf.rotation = Quaternion.Euler(0, 0, rotiation);
|
||||
if (similarityCalc)
|
||||
{
|
||||
if (m_selectionImg)
|
||||
{
|
||||
var rt = tf as RectTransform;
|
||||
var rtSelectionImg = m_selectionImg.transform as RectTransform;
|
||||
rt.anchorMax = rt.anchorMin;
|
||||
rt.sizeDelta = new Vector2(rtSelectionImg.sizeDelta.x, rtSelectionImg.sizeDelta.y);
|
||||
}
|
||||
}
|
||||
else {
|
||||
tf.rotation = Quaternion.Euler(0, 0, rotiation * -1);
|
||||
tf.localScale = new Vector3(scale.x, scale.y, 1);
|
||||
}
|
||||
}
|
||||
var position = m_elementInfo.Position;
|
||||
tf.position = StageManager.Instance.PrefabContentsRoot.transform.TransformPoint(new Vector3(position.x, position.y, 0));
|
||||
}
|
||||
|
||||
// 查找时调用
|
||||
public void SetTransform(float rotiation, float2 scale)
|
||||
public void SetTransform(float rotiation, float2 scale, bool similarityCalc)
|
||||
{
|
||||
this.rotiation = rotiation;
|
||||
this.scale = scale;
|
||||
this.similarityCalc = similarityCalc;
|
||||
|
||||
this.needFillTransform = true;
|
||||
}
|
||||
|
@ -1,37 +1,42 @@
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
|
||||
namespace UguiToolkit.Editor
|
||||
{
|
||||
public static class CommandHelper
|
||||
{
|
||||
public static RotScaleJsonData CalcRotScale(in string srcImgDirPath, in string targetImgDirPath)
|
||||
public static void CalcRotScale(string srcImgDirPath, string targetImgDirPath, Action<RotScaleJsonData> callback)
|
||||
{
|
||||
var rotScaleInfoFilePath = Path.GetFullPath(EditorConst.RotScaleInfoFilePath);
|
||||
var rotScaleInfoToolFilePath = Path.GetFullPath(EditorConst.RotScaleInfoToolFilePath);
|
||||
if (File.Exists(rotScaleInfoFilePath)) File.Delete(rotScaleInfoFilePath);
|
||||
|
||||
RunCmd(string.Format("{0} -src {1} -target {2} -distance_difference 0.06 -output_path {3}",
|
||||
_ = RunCmdAsync(string.Format("{0} -src {1} -target {2} -distance_difference 0.06 -output_path {3}",
|
||||
rotScaleInfoToolFilePath,
|
||||
Path.GetFullPath(srcImgDirPath),
|
||||
Path.GetFullPath(targetImgDirPath),
|
||||
Path.GetFullPath(rotScaleInfoFilePath)));
|
||||
Path.GetFullPath(rotScaleInfoFilePath)), (output, error) =>
|
||||
{
|
||||
Debug.Log(output);
|
||||
if (!File.Exists(rotScaleInfoFilePath))
|
||||
{
|
||||
Debug.LogError($"[E] 文件{rotScaleInfoFilePath} 未能正确获得");
|
||||
return null;
|
||||
Debug.LogError(error);
|
||||
return;
|
||||
}
|
||||
|
||||
using (StreamReader reader = File.OpenText(rotScaleInfoFilePath))
|
||||
{
|
||||
var jsonData = reader.ReadToEnd();
|
||||
RotScaleJsonData rotScaleJsonData = JsonConvert.DeserializeObject<RotScaleJsonData>(jsonData);
|
||||
return rotScaleJsonData;
|
||||
callback(rotScaleJsonData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 执行 cmd 命令
|
||||
@ -50,8 +55,30 @@ namespace UguiToolkit.Editor
|
||||
var error = p.StandardError.ReadToEnd();
|
||||
p.WaitForExit();
|
||||
|
||||
Debug.Log("cmd output : " + output);
|
||||
Debug.Log("cmd error : " + error);
|
||||
UnityEngine.Debug.Log("cmd output : " + output);
|
||||
UnityEngine.Debug.Log("cmd error : " + error);
|
||||
}
|
||||
|
||||
// 异步执行 cmd 命令
|
||||
public static async Task RunCmdAsync(string cmd, Action<string, string> callback = null)
|
||||
{
|
||||
var p = new System.Diagnostics.Process();
|
||||
p.StartInfo.FileName = "cmd.exe";
|
||||
p.StartInfo.Arguments = "/c " + cmd; // 使用 /c 参数执行命令并关闭 cmd 窗口
|
||||
p.StartInfo.UseShellExecute = false;
|
||||
p.StartInfo.CreateNoWindow = true;
|
||||
p.StartInfo.RedirectStandardOutput = true;
|
||||
p.StartInfo.RedirectStandardError = true;
|
||||
|
||||
p.Start();
|
||||
|
||||
var output = await p.StandardOutput.ReadToEndAsync();
|
||||
var error = await p.StandardError.ReadToEndAsync();
|
||||
// 异步等待进程退出
|
||||
await Task.Run(() => p.WaitForExit());
|
||||
|
||||
// 在主线程上调用回调函数
|
||||
UnityMainThreadDispatcher.Instance().Enqueue(() => callback?.Invoke(output, error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
68
Assets/Editor/Helper/UnityMainThreadDispatcher.cs
Normal file
@ -0,0 +1,68 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UguiToolkit.Editor
|
||||
{
|
||||
[ExecuteAlways]
|
||||
public class UnityMainThreadDispatcher : MonoBehaviour
|
||||
{
|
||||
private static readonly Queue<Action> _executionQueue = new Queue<Action>();
|
||||
|
||||
private static UnityMainThreadDispatcher _instance = null;
|
||||
|
||||
public static UnityMainThreadDispatcher Instance()
|
||||
{
|
||||
if (!_instance)
|
||||
{
|
||||
_instance = FindObjectOfType<UnityMainThreadDispatcher>();
|
||||
if (!_instance)
|
||||
{
|
||||
var obj = new GameObject("UnityMainThreadDispatcher");
|
||||
_instance = obj.AddComponent<UnityMainThreadDispatcher>();
|
||||
}
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
lock (_executionQueue)
|
||||
{
|
||||
while (_executionQueue.Count > 0)
|
||||
{
|
||||
_executionQueue.Dequeue().Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Enqueue(IEnumerator action)
|
||||
{
|
||||
lock (_executionQueue)
|
||||
{
|
||||
_executionQueue.Enqueue(() => { StartCoroutine(action); });
|
||||
}
|
||||
}
|
||||
|
||||
public void Enqueue(Action action)
|
||||
{
|
||||
Enqueue(ActionWrapper(action));
|
||||
}
|
||||
|
||||
IEnumerator ActionWrapper(Action a)
|
||||
{
|
||||
a();
|
||||
yield return null;
|
||||
}
|
||||
|
||||
public static void EnqueueMainThread(Action action)
|
||||
{
|
||||
Instance().Enqueue(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
11
Assets/Editor/Helper/UnityMainThreadDispatcher.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e505c77cd7b45c40a053189072de6d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,9 +1,11 @@
|
||||
#if UNITY_EDITOR
|
||||
using Sirenix.OdinInspector;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using static UnityEngine.EventSystems.EventTrigger;
|
||||
using static UguiToolkit.Editor.LayoutInfo;
|
||||
|
||||
namespace UguiToolkit.Editor
|
||||
{
|
||||
@ -11,22 +13,29 @@ namespace UguiToolkit.Editor
|
||||
public class EntityManager : MonoBehaviour, IManager
|
||||
{
|
||||
private PanelCache m_panelCache;
|
||||
private Transform entityRoot;
|
||||
private GameObject lastSelectionGo;
|
||||
private IEntity lastSelectionEntity;
|
||||
private Transform m_entityRoot;
|
||||
private GameObject m_lastSelectionGo;
|
||||
private IEntity m_lastSelectionEntity;
|
||||
|
||||
private List<ImageEntity> imageEntities;
|
||||
private List<TextEntity> textEntities;
|
||||
private List<IEntity> selectionEntities;
|
||||
private List<ImageEntity> m_imageEntities;
|
||||
private List<TextEntity> m_textEntities;
|
||||
private List<IEntity> m_selectionEntities;
|
||||
|
||||
[LabelText("脱离选择控制"), ShowInInspector]
|
||||
private bool noSelection;
|
||||
private bool m_noSelection;
|
||||
|
||||
private StageManager m_stageManager;
|
||||
private HashSet<string> m_checkImgPaths;
|
||||
private float m_lastCheckTime;
|
||||
private const float m_checkInterval = 2f;
|
||||
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
GlobalManager.Instance.showHierarchyOfEntityChanged += OnUpdateHierarchyOfEntityAllEntity;
|
||||
Selection.selectionChanged += OnSelectionChanged;
|
||||
|
||||
m_stageManager = StageManager.Instance;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
@ -38,28 +47,28 @@ namespace UguiToolkit.Editor
|
||||
private void Update()
|
||||
{
|
||||
// 检测是否到达可选实例矩形内部
|
||||
if (selectionEntities != null && Selection.activeGameObject != null)
|
||||
if (m_selectionEntities != null && Selection.activeGameObject != null)
|
||||
{
|
||||
if (lastSelectionGo && lastSelectionGo == Selection.activeGameObject)
|
||||
if (m_lastSelectionGo && m_lastSelectionGo == Selection.activeGameObject)
|
||||
{
|
||||
if (lastSelectionEntity != null && !lastSelectionEntity.IsInside(lastSelectionGo.transform))
|
||||
if (m_lastSelectionEntity != null && !m_lastSelectionEntity.IsInside(m_lastSelectionGo.transform))
|
||||
{
|
||||
lastSelectionGo = null;
|
||||
lastSelectionEntity = null;
|
||||
m_lastSelectionGo = null;
|
||||
m_lastSelectionEntity = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool isApplyTransform = false;
|
||||
foreach (var entity in selectionEntities)
|
||||
foreach (var entity in m_selectionEntities)
|
||||
{
|
||||
var tf = Selection.activeGameObject.transform;
|
||||
if (entity.IsInside(tf))
|
||||
{
|
||||
entity.ApplyTransform(tf);
|
||||
|
||||
lastSelectionGo = Selection.activeGameObject;
|
||||
lastSelectionEntity = entity;
|
||||
m_lastSelectionGo = Selection.activeGameObject;
|
||||
m_lastSelectionEntity = entity;
|
||||
|
||||
Selection.activeGameObject = null;
|
||||
|
||||
@ -67,21 +76,89 @@ namespace UguiToolkit.Editor
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isApplyTransform) selectionEntities.Clear();
|
||||
if (isApplyTransform) m_selectionEntities.Clear();
|
||||
}
|
||||
|
||||
// 检测是否有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)
|
||||
{
|
||||
CacheScriptObject.CalcRotScaleInfos(srcImgDirPath, targetImgDirPath, (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 (noSelection) return;
|
||||
entityRoot.gameObject.SetActive(false);
|
||||
selectionEntities.Clear();
|
||||
if (m_noSelection) return;
|
||||
m_entityRoot.gameObject.SetActive(false);
|
||||
m_selectionEntities.Clear();
|
||||
|
||||
if (Selection.activeGameObject != null && m_panelCache != null)
|
||||
{
|
||||
var activeGameObject = Selection.activeGameObject;
|
||||
if (activeGameObject.transform.parent == entityRoot) return;
|
||||
if (activeGameObject.transform.parent == m_entityRoot) return;
|
||||
|
||||
if (activeGameObject.TryGetComponent<UnityEngine.UI.Image>(out var image))
|
||||
{
|
||||
@ -91,9 +168,9 @@ namespace UguiToolkit.Editor
|
||||
var srcImgPath = AssetDatabase.GetAssetPath(image.sprite);
|
||||
if (!rotScaleInfos.TryGetValue(srcImgPath, out var rotScaleInfoItems)) return;
|
||||
|
||||
entityRoot.gameObject.SetActive(true);
|
||||
m_entityRoot.gameObject.SetActive(true);
|
||||
bool isFind;
|
||||
foreach (var imgEntity in imageEntities)
|
||||
foreach (var imgEntity in m_imageEntities)
|
||||
{
|
||||
isFind = false;
|
||||
foreach (var rotScale in rotScaleInfoItems)
|
||||
@ -101,9 +178,16 @@ namespace UguiToolkit.Editor
|
||||
var imgInfo = imgEntity.ElementInfo;
|
||||
if (imgInfo.imgPath == rotScale.imgPath)
|
||||
{
|
||||
imgEntity.SetTransform(rotScale.rotiation, rotScale.scale);
|
||||
if (rotScale.similarityCalc)
|
||||
{
|
||||
imgEntity.SetTransform(0, new Unity.Mathematics.float2(1, 1), true);
|
||||
}
|
||||
else {
|
||||
imgEntity.SetTransform(rotScale.rotiation, rotScale.scale, false);
|
||||
}
|
||||
|
||||
imgEntity.ShowSelectionImg(true);
|
||||
selectionEntities.Add(imgEntity);
|
||||
m_selectionEntities.Add(imgEntity);
|
||||
|
||||
isFind = true;
|
||||
break;
|
||||
@ -112,7 +196,7 @@ namespace UguiToolkit.Editor
|
||||
imgEntity.gameObject.SetActive(isFind);
|
||||
}
|
||||
|
||||
foreach (var textEntity in textEntities)
|
||||
foreach (var textEntity in m_textEntities)
|
||||
{
|
||||
textEntity.gameObject.SetActive(false);
|
||||
}
|
||||
@ -131,13 +215,14 @@ namespace UguiToolkit.Editor
|
||||
|
||||
// 创建所有实例
|
||||
CreateAllEntity();
|
||||
InitCheckImgPaths();
|
||||
}
|
||||
|
||||
private void OnUpdateHierarchyOfEntityAllEntity(bool show)
|
||||
{
|
||||
UpdateHierarchyOfEntity(show, entityRoot.gameObject);
|
||||
foreach (var entity in imageEntities) UpdateHierarchyOfEntity(show, entity.gameObject);
|
||||
foreach (var entity in textEntities) UpdateHierarchyOfEntity(show, entity.gameObject);
|
||||
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)
|
||||
@ -148,17 +233,17 @@ namespace UguiToolkit.Editor
|
||||
private void CreateAllEntity()
|
||||
{
|
||||
if (this.m_panelCache == null) return;
|
||||
var go = new GameObject("_entityRoot_", typeof(RectTransform));
|
||||
var go = new GameObject("__entityRoot__", typeof(RectTransform));
|
||||
UpdateHierarchyOfEntity(false, go);
|
||||
entityRoot = go.transform;
|
||||
entityRoot.SetParent(transform);
|
||||
entityRoot.localPosition = Vector3.zero;
|
||||
entityRoot.localRotation = Quaternion.identity;
|
||||
entityRoot.localScale = Vector3.one;
|
||||
m_entityRoot = go.transform;
|
||||
m_entityRoot.SetParent(transform);
|
||||
m_entityRoot.localPosition = Vector3.zero;
|
||||
m_entityRoot.localRotation = Quaternion.identity;
|
||||
m_entityRoot.localScale = Vector3.one;
|
||||
|
||||
imageEntities = new(m_panelCache.layoutInfo.Count);
|
||||
textEntities = new(m_panelCache.layoutInfo.Count);
|
||||
selectionEntities = new(m_panelCache.layoutInfo.Count);
|
||||
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<LayoutInfo.ElementInfo>())
|
||||
{
|
||||
@ -167,13 +252,13 @@ namespace UguiToolkit.Editor
|
||||
{
|
||||
go = new GameObject("",typeof(RectTransform));
|
||||
var entity = go.AddComponent<ImageEntity>();
|
||||
entity.transform.SetParent(entityRoot);
|
||||
entity.transform.SetParent(m_entityRoot);
|
||||
entity.transform.SetSiblingIndex(0);
|
||||
|
||||
entity.SetData(imgInfo);
|
||||
entity.InitPreviewImage();
|
||||
|
||||
imageEntities.Add(entity);
|
||||
m_imageEntities.Add(entity);
|
||||
UpdateHierarchyOfEntity(false, entity.gameObject);
|
||||
continue;
|
||||
}
|
||||
@ -182,20 +267,20 @@ namespace UguiToolkit.Editor
|
||||
{
|
||||
go = new GameObject("", typeof(RectTransform));
|
||||
var entity = go.AddComponent<TextEntity>();
|
||||
entity.transform.SetParent(entityRoot);
|
||||
entity.transform.SetParent(m_entityRoot);
|
||||
entity.transform.SetSiblingIndex(0);
|
||||
|
||||
entity.SetData(textInfo);
|
||||
entity.InitPreviewText();
|
||||
|
||||
textEntities.Add(entity);
|
||||
m_textEntities.Add(entity);
|
||||
UpdateHierarchyOfEntity(false, entity.gameObject);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
entityRoot.gameObject.SetActive(false);
|
||||
m_entityRoot.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
using System;
|
||||
using UguiToolkit.Editor;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UguiToolkit
|
||||
{
|
||||
@ -30,6 +31,11 @@ namespace UguiToolkit
|
||||
/// </summary>
|
||||
public Action<bool> showHierarchyOfEntityChanged;
|
||||
|
||||
public void SaveCache(GameObject asset, PanelCache panelCache)
|
||||
{
|
||||
cache.panelCaches[asset] = panelCache;
|
||||
SaveCache();
|
||||
}
|
||||
|
||||
public void SaveCache()
|
||||
{
|
||||
|
@ -16,6 +16,8 @@ namespace UguiToolkit
|
||||
public GameObject PrefabContentsRoot => m_prefabContentsRoot;
|
||||
private Dictionary<Type, IManager> m_mngMap = new Dictionary<Type, IManager>();
|
||||
|
||||
public GameObject PrefabAsset => m_prefabAsset;
|
||||
private GameObject m_prefabAsset;
|
||||
|
||||
private static StageManager m_instance;
|
||||
public static StageManager Instance
|
||||
@ -46,9 +48,9 @@ namespace UguiToolkit
|
||||
EntityHelper.UpdateHierarchyOfEntity(show, m_instance.gameObject);
|
||||
}
|
||||
|
||||
public static StageManager CreateStageManager(Scene scene, GameObject prefabContentsRoot)
|
||||
public static StageManager CreateStageManager(Scene scene, GameObject prefabContentsRoot, GameObject prefabAsset)
|
||||
{
|
||||
var go = new GameObject("_StageManager_", typeof(RectTransform));
|
||||
var go = new GameObject("__StageManager__", typeof(RectTransform));
|
||||
go.transform.parent = prefabContentsRoot.transform;
|
||||
go.transform.localPosition = Vector3.zero;
|
||||
go.transform.localRotation= Quaternion.identity;
|
||||
@ -57,6 +59,7 @@ namespace UguiToolkit
|
||||
m_instance = go.AddComponent<StageManager>();
|
||||
m_instance.m_scene = scene;
|
||||
m_instance.m_prefabContentsRoot = prefabContentsRoot;
|
||||
m_instance.m_prefabAsset = prefabAsset;
|
||||
|
||||
go.hideFlags = HideFlags.DontSave;
|
||||
|
||||
|
@ -6,6 +6,7 @@ using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
using Sirenix.OdinInspector;
|
||||
using static UguiToolkit.Editor.LayoutInfo;
|
||||
using System.IO;
|
||||
|
||||
namespace UguiToolkit.Editor
|
||||
{
|
||||
@ -14,6 +15,65 @@ namespace UguiToolkit.Editor
|
||||
{
|
||||
[SerializeField]
|
||||
public Dictionary<GameObject, PanelCache> panelCaches = new();
|
||||
|
||||
public static LayoutInfo PaserLayout(string layoutInfoFilePath, string targetImgDirPath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(layoutInfoFilePath))
|
||||
{
|
||||
Debug.LogError("layoutInfoFilePath 为空");
|
||||
return null;
|
||||
}
|
||||
ILayoutParser layoutParser = new DefaultLayoutParser();
|
||||
using (StreamReader reader = File.OpenText(layoutInfoFilePath))
|
||||
{
|
||||
var jsonData = reader.ReadToEnd();
|
||||
var layoutInfo = layoutParser.Parser(jsonData);
|
||||
|
||||
// 对img路径进行修正
|
||||
string projectPath = Directory.GetParent(Application.dataPath).FullName;
|
||||
|
||||
foreach (var elementInfo in layoutInfo)
|
||||
{
|
||||
var imgInfo = elementInfo as LayoutInfo.ImageInfo;
|
||||
if (imgInfo != null)
|
||||
{
|
||||
imgInfo.imgPath = System.IO.Path.Join(targetImgDirPath, imgInfo.imgPath) + ".png";
|
||||
imgInfo.imgPath = Path.GetRelativePath(projectPath, imgInfo.imgPath).Replace("\\", "/");
|
||||
}
|
||||
}
|
||||
|
||||
return layoutInfo;
|
||||
}
|
||||
}
|
||||
|
||||
public static void CalcRotScaleInfos(string srcImgDirPath, string targetImgDirPath, Action<Dictionary<string, List<RotScaleInfoItem>>> callback)
|
||||
{
|
||||
// 执行cmd
|
||||
CommandHelper.CalcRotScale(srcImgDirPath, targetImgDirPath, (jsonData) =>
|
||||
{
|
||||
if (jsonData == null || jsonData.data == null) return;
|
||||
Dictionary<string, List<RotScaleInfoItem>> rotScaleInfos = new();
|
||||
|
||||
string projectPath = Directory.GetParent(Application.dataPath).FullName;
|
||||
foreach (var kv in jsonData.data)
|
||||
{
|
||||
List<RotScaleInfoItem> rotScaleItemList = new();
|
||||
rotScaleInfos[Path.GetRelativePath(projectPath, kv.Key).Replace("\\", "/")] = rotScaleItemList;
|
||||
foreach (var jsonItemData in kv.Value)
|
||||
{
|
||||
rotScaleItemList.Add(new()
|
||||
{
|
||||
imgPath = Path.GetRelativePath(projectPath, jsonItemData.targetPath).Replace("\\", "/"),
|
||||
rotiation = jsonItemData.rot,
|
||||
scale = new float2(jsonItemData.scale[0], jsonItemData.scale[1]),
|
||||
similarityCalc = jsonItemData.similarityCalc
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
callback(rotScaleInfos);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
@ -23,9 +83,8 @@ namespace UguiToolkit.Editor
|
||||
public string srcImgDirPath;
|
||||
[LabelText("目标图片信息文件(psd导出)"), FolderPath]
|
||||
public string layoutInfoFilePath; // Sample.layout.txt
|
||||
|
||||
[LabelText("目标图片文件夹路径")]
|
||||
public string TargetImgDirPath => GetTargetImgDirPath(layoutInfoFilePath);
|
||||
public string TargetImgDirPath => m_targetImgDirPath;
|
||||
|
||||
|
||||
// 通过ElementInfo创建所有Actor
|
||||
@ -48,6 +107,17 @@ namespace UguiToolkit.Editor
|
||||
public Dictionary<string, List<RotScaleInfoItem>> rotScaleInfos = new();
|
||||
[SerializeField]
|
||||
public LayoutInfo layoutInfo;
|
||||
[SerializeField, HideInInspector]
|
||||
private string m_targetImgDirPath;
|
||||
private PanelCache() { }
|
||||
|
||||
public PanelCache(string srcImgDirPath, string layoutInfoFilePath)
|
||||
{
|
||||
this.srcImgDirPath = srcImgDirPath;
|
||||
this.layoutInfoFilePath = layoutInfoFilePath;
|
||||
|
||||
this.m_targetImgDirPath = GetTargetImgDirPath(layoutInfoFilePath);
|
||||
}
|
||||
|
||||
public IEnumerable<T> GetLayoutElementInfos<T>() where T : LayoutInfo.ElementInfo
|
||||
{
|
||||
@ -167,6 +237,7 @@ namespace UguiToolkit.Editor
|
||||
public string imgPath; //(效果图)
|
||||
public float rotiation;
|
||||
public float2 scale;
|
||||
public bool similarityCalc;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1,4 +1,5 @@
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Sirenix.OdinInspector;
|
||||
@ -7,7 +8,6 @@ using Unity.Mathematics;
|
||||
using UnityEditor;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace UguiToolkit.Editor.Windows
|
||||
{
|
||||
@ -21,87 +21,43 @@ namespace UguiToolkit.Editor.Windows
|
||||
|
||||
private PrefabStage m_prefabStage;
|
||||
private GameObject m_prefab;
|
||||
private bool m_cacheExist;
|
||||
private PanelCache panelCache;
|
||||
private PanelCache m_panelCache;
|
||||
|
||||
[Button("开启助手", ButtonSizes.Medium)]
|
||||
private void DoStart()
|
||||
{
|
||||
panelCache.srcImgDirPath = m_srcImgDirPath;
|
||||
panelCache.layoutInfoFilePath = m_layoutInfoFilePath;
|
||||
if (!m_cacheExist)
|
||||
{
|
||||
CalcRotScaleInfos();
|
||||
PaserLayout();
|
||||
}
|
||||
|
||||
var cache = GlobalManager.Instance.cache;
|
||||
cache.panelCaches[m_prefab] = panelCache;
|
||||
GlobalManager.Instance.SaveCache();
|
||||
|
||||
var stageManager = UguiToolkit.StageManager.CreateStageManager(m_prefabStage.scene, m_prefabStage.prefabContentsRoot);
|
||||
var entityManager = stageManager.CreateSubManager<EntityManager>();
|
||||
entityManager.InitAllEntity(panelCache);
|
||||
CloseWindow();
|
||||
var stageManager = UguiToolkit.StageManager.CreateStageManager(m_prefabStage.scene, m_prefabStage.prefabContentsRoot, m_prefab);
|
||||
stageManager.gameObject.AddComponent<UnityMainThreadDispatcher>();
|
||||
|
||||
// 打开编辑界面
|
||||
EditWindow.ShowWindow(null);
|
||||
}
|
||||
|
||||
[Button("解析Layout.txt", ButtonSizes.Medium), ShowIf(nameof(m_cacheExist))]
|
||||
private void PaserLayout()
|
||||
if (m_panelCache == null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(m_layoutInfoFilePath))
|
||||
var targetImgDirPath = PanelCache.GetTargetImgDirPath(m_layoutInfoFilePath);
|
||||
CacheScriptObject.CalcRotScaleInfos(m_srcImgDirPath, targetImgDirPath, (rotScaleInfos) =>
|
||||
{
|
||||
Debug.LogError("layoutInfoFilePath 为空");
|
||||
return;
|
||||
}
|
||||
ILayoutParser layoutParser = new DefaultLayoutParser();
|
||||
using (StreamReader reader = File.OpenText(m_layoutInfoFilePath))
|
||||
{
|
||||
var jsonData = reader.ReadToEnd();
|
||||
var layoutInfo = layoutParser.Parser(jsonData);
|
||||
if (!stageManager) return;
|
||||
|
||||
// 对img路径进行修正
|
||||
string projectPath = Directory.GetParent(Application.dataPath).FullName;
|
||||
var panelCache = new PanelCache(m_srcImgDirPath, m_layoutInfoFilePath);
|
||||
|
||||
foreach (var elementInfo in layoutInfo)
|
||||
{
|
||||
var imgInfo = elementInfo as LayoutInfo.ImageInfo;
|
||||
if (imgInfo != null)
|
||||
{
|
||||
imgInfo.imgPath = System.IO.Path.Join(panelCache.TargetImgDirPath, imgInfo.imgPath) + ".png";
|
||||
imgInfo.imgPath = Path.GetRelativePath(projectPath, imgInfo.imgPath).Replace("\\", "/");
|
||||
}
|
||||
}
|
||||
panelCache.rotScaleInfos = rotScaleInfos;
|
||||
panelCache.layoutInfo = CacheScriptObject.PaserLayout(m_layoutInfoFilePath, targetImgDirPath);
|
||||
|
||||
panelCache.layoutInfo = layoutInfo;
|
||||
}
|
||||
}
|
||||
// 保存缓存
|
||||
GlobalManager.Instance.SaveCache(m_prefab, panelCache);
|
||||
|
||||
[Button("重新计算旋转和缩放信息", ButtonSizes.Medium), ShowIf(nameof(m_cacheExist))]
|
||||
private void CalcRotScaleInfos()
|
||||
{
|
||||
// 执行cmd
|
||||
var jsonData = CommandHelper.CalcRotScale(panelCache.srcImgDirPath, panelCache.TargetImgDirPath);
|
||||
if (jsonData == null || jsonData.data == null) return;
|
||||
var rotScaleInfos = panelCache.rotScaleInfos;
|
||||
rotScaleInfos.Clear();
|
||||
var entityManager = stageManager.CreateSubManager<EntityManager>();
|
||||
entityManager.InitAllEntity(panelCache);
|
||||
|
||||
string projectPath = Directory.GetParent(Application.dataPath).FullName;
|
||||
foreach (var kv in jsonData.data)
|
||||
{
|
||||
List<RotScaleInfoItem> rotScaleItemList = new();
|
||||
rotScaleInfos[Path.GetRelativePath(projectPath, kv.Key).Replace("\\", "/")] = rotScaleItemList;
|
||||
foreach (var jsonItemData in kv.Value)
|
||||
{
|
||||
rotScaleItemList.Add(new ()
|
||||
{
|
||||
imgPath = Path.GetRelativePath(projectPath, jsonItemData.targetPath).Replace("\\", "/"),
|
||||
rotiation = jsonItemData.rot,
|
||||
scale = new float2(jsonItemData.scale[0], jsonItemData.scale[1])
|
||||
});
|
||||
|
||||
CloseWindow();
|
||||
}
|
||||
else {
|
||||
var entityManager = stageManager.CreateSubManager<EntityManager>();
|
||||
entityManager.InitAllEntity(m_panelCache);
|
||||
CloseWindow();
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,16 +73,10 @@ namespace UguiToolkit.Editor.Windows
|
||||
m_prefab = AssetDatabase.LoadAssetAtPath<GameObject>(_args.stage.assetPath);
|
||||
|
||||
var cache = GlobalManager.Instance.cache;
|
||||
if (cache.panelCaches.TryGetValue(m_prefab, out panelCache))
|
||||
if (cache.panelCaches.TryGetValue(m_prefab, out m_panelCache))
|
||||
{
|
||||
m_srcImgDirPath = panelCache.srcImgDirPath;
|
||||
m_layoutInfoFilePath = panelCache.layoutInfoFilePath;
|
||||
|
||||
m_cacheExist = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
panelCache = new PanelCache();
|
||||
m_srcImgDirPath = m_panelCache.srcImgDirPath;
|
||||
m_layoutInfoFilePath = m_panelCache.layoutInfoFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
|