366 lines
12 KiB
C#
366 lines
12 KiB
C#
#if UNITY_EDITOR
|
||
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using Unity.Mathematics;
|
||
using UnityEngine;
|
||
using Sirenix.OdinInspector;
|
||
using static UguiToolkit.Editor.LayoutInfo;
|
||
using System.IO;
|
||
using UnityEditor;
|
||
using Sirenix.Utilities;
|
||
|
||
namespace UguiToolkit.Editor
|
||
{
|
||
[Serializable]
|
||
public class CacheScriptObject : SerializedScriptableObject
|
||
{
|
||
[SerializeField]
|
||
public Dictionary<GameObject, AllDirectionPanelCache> 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("\\", "/");
|
||
|
||
if (imgInfo.HaveSlice)
|
||
{
|
||
imgInfo.imgSlicePath = System.IO.Path.Join(targetImgDirPath, imgInfo.imgSlicePath) + ".png";
|
||
imgInfo.imgSlicePath = Path.GetRelativePath(projectPath, imgInfo.imgSlicePath).Replace("\\", "/");
|
||
}
|
||
}
|
||
}
|
||
|
||
return layoutInfo;
|
||
}
|
||
}
|
||
|
||
public static void CalcRotScaleInfos(string srcImgDirPath, string targetImgDirPath, float distanceDifference, Action<Dictionary<string, List<RotScaleInfoItem>>> callback)
|
||
{
|
||
// 执行cmd
|
||
CommandHelper.CalcRotScale(srcImgDirPath, targetImgDirPath, distanceDifference,(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[ImageUtils.FormatImgFilePath(kv.Key)] = rotScaleItemList;
|
||
foreach (var jsonItemData in kv.Value)
|
||
{
|
||
rotScaleItemList.Add(new()
|
||
{
|
||
imgPath = ImageUtils.FormatImgFilePath(jsonItemData.targetPath),
|
||
rotiation = jsonItemData.rot,
|
||
scale = new float2(jsonItemData.scale[0], jsonItemData.scale[1]),
|
||
similarityCalc = jsonItemData.similarityCalc
|
||
});
|
||
}
|
||
}
|
||
|
||
callback(rotScaleInfos);
|
||
});
|
||
}
|
||
}
|
||
|
||
[Serializable]
|
||
public class AllDirectionPanelCache
|
||
{
|
||
public PanelCache panelCacheOfVertical;
|
||
public PanelCache panelCacheOfHorizontal;
|
||
}
|
||
|
||
[Serializable]
|
||
public class PanelCache
|
||
{
|
||
[LabelText("项目内导出图片文件夹"), FolderPath]
|
||
public string srcImgDirPath;
|
||
[LabelText("目标图片信息文件(psd导出)"), Sirenix.OdinInspector.FilePath(AbsolutePath = true, Extensions = "layout.txt")]
|
||
public string layoutInfoFilePath; // Sample.layout.txt
|
||
[LabelText("目标图片文件夹路径")]
|
||
public string TargetImgDirPath => m_targetImgDirPath;
|
||
[LabelText("是否竖版")]
|
||
public bool isVertical;
|
||
|
||
|
||
// 通过ElementInfo创建所有Actor
|
||
// 1. 鼠标选中img或者text,1s 后触发助手
|
||
// img
|
||
// 2. 通过img的图片路径,查找rotScaleInfos,获得匹配的旋转缩放信息. 如果没有查找到则return
|
||
// 3. 通过img的图片路径, 查找ActorManager, 获得所有和图片路径匹配的Actor,并显示所有匹配的Actor
|
||
// 4. 每帧刷新,如果鼠标进入Actor的rect中,则播放scale动效。鼠标松开,则apply 该actor的 trasform
|
||
|
||
// text
|
||
// 2. 每帧刷新,查找圆形范围内,所有text Actor,并显示所有匹配的Actor
|
||
// 3. 每帧刷新,如果鼠标进入Actor的rect中,则播放scale动效。鼠标松开,则apply 该actor的 trasform
|
||
|
||
|
||
// 通过cmd计算获得 图片路径(源图) -> 旋转缩放信息(效果图)
|
||
[SerializeField]
|
||
private Dictionary<string, List<RotScaleInfoItem>> rotScaleInfos = new();
|
||
[SerializeField]
|
||
public LayoutInfo layoutInfo;
|
||
[SerializeField, HideInInspector]
|
||
private string m_targetImgDirPath;
|
||
[SerializeField]
|
||
public Dictionary<string, long> imgDirPathTimestamp = new();
|
||
|
||
private PanelCache() { }
|
||
|
||
// public PanelCache(string srcImgDirPath, string layoutInfoFilePath)
|
||
public PanelCache(string layoutInfoFilePath, string srcImgDirPath, bool isVertical = false)
|
||
{
|
||
this.srcImgDirPath = srcImgDirPath;
|
||
this.layoutInfoFilePath = layoutInfoFilePath;
|
||
this.isVertical = isVertical;
|
||
|
||
this.m_targetImgDirPath = GetTargetImgDirPath(layoutInfoFilePath);
|
||
}
|
||
|
||
public void Copy(PanelCache panelCache)
|
||
{
|
||
rotScaleInfos = panelCache.rotScaleInfos;
|
||
imgDirPathTimestamp = panelCache.imgDirPathTimestamp;
|
||
}
|
||
|
||
public bool HaveRotScaleInfo(string srcImgPath)
|
||
{
|
||
return rotScaleInfos.TryGetValue(srcImgPath, out var _);
|
||
}
|
||
|
||
public bool HaveRotScaleInfo(string srcImgPath, out List<RotScaleInfoItem> rotScaleInfo)
|
||
{
|
||
return rotScaleInfos.TryGetValue(srcImgPath, out rotScaleInfo);
|
||
}
|
||
|
||
public void AddRotScaleInfo(string srcImgPath, List<RotScaleInfoItem> rotScaleInfo)
|
||
{
|
||
rotScaleInfos[srcImgPath] = rotScaleInfo;
|
||
}
|
||
|
||
public bool IsValidOfImgDirPath(string imgDirPath)
|
||
{
|
||
if (!Directory.Exists(imgDirPath)) return false;
|
||
|
||
if (imgDirPathTimestamp.TryGetValue(imgDirPath, out var timestamp))
|
||
{
|
||
var curTimestamp = GetTimestampByDirPath(imgDirPath);
|
||
return curTimestamp == timestamp;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
public void ClearRotScaleInfoItem(string imgDirPath)
|
||
{
|
||
List<int> indeces = new();
|
||
foreach (var rotScaleInfo in rotScaleInfos.Values)
|
||
{
|
||
indeces.Clear();
|
||
for (var i = 0; i < rotScaleInfo.Count; i++)
|
||
{
|
||
var item = rotScaleInfo[i];
|
||
if (item.imgPath.StartsWith(imgDirPath))
|
||
{
|
||
indeces.Add(i);
|
||
}
|
||
}
|
||
|
||
indeces.Sort();
|
||
indeces.Reverse();
|
||
|
||
foreach (var index in indeces)
|
||
{
|
||
rotScaleInfo.RemoveAt(index);
|
||
}
|
||
}
|
||
}
|
||
|
||
public void AddImgDirPathTimestamp(string imgDirPath)
|
||
{
|
||
var curTimestamp = GetTimestampByDirPath(imgDirPath);
|
||
imgDirPathTimestamp[imgDirPath] = curTimestamp;
|
||
}
|
||
|
||
public void InitRotScaleInfos()
|
||
{
|
||
foreach(var dirPath in imgDirPathTimestamp.Keys)
|
||
{
|
||
if (!IsValidOfImgDirPath(dirPath))
|
||
{
|
||
ClearRotScaleInfoItem(dirPath);
|
||
}
|
||
}
|
||
}
|
||
|
||
public void ClearRotScaleInfos()
|
||
{
|
||
rotScaleInfos.Clear();
|
||
imgDirPathTimestamp.Clear();
|
||
}
|
||
|
||
public IEnumerable<T> GetLayoutElementInfos<T>() where T : LayoutInfo.ElementInfo
|
||
{
|
||
if (layoutInfo == null) yield break;
|
||
|
||
foreach (var e in layoutInfo)
|
||
{
|
||
if (e is T)
|
||
{
|
||
yield return e as T;
|
||
}
|
||
}
|
||
}
|
||
|
||
public static string GetTargetImgDirPath(in string layoutInfoFilePath)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(layoutInfoFilePath)) return "";
|
||
var dirName = System.IO.Path.GetDirectoryName(layoutInfoFilePath);
|
||
var fileName = System.IO.Path.GetFileName(layoutInfoFilePath);
|
||
var split = fileName.Split(".");
|
||
if (split.Length == 0) return "";
|
||
|
||
return System.IO.Path.Join(dirName, split[0]);
|
||
}
|
||
|
||
public static long GetTimestampByDirPath(string dirPath)
|
||
{
|
||
DirectoryInfo directoryInfo = new DirectoryInfo(dirPath);
|
||
// 获取文件夹的最后修改时间
|
||
DateTime lastModified = directoryInfo.LastWriteTime;
|
||
return new DateTimeOffset(lastModified).ToUnixTimeSeconds();
|
||
}
|
||
}
|
||
|
||
[Serializable]
|
||
public class LayoutInfo: IEnumerable<ElementInfo>
|
||
{
|
||
[SerializeField]
|
||
private List<ElementInfo> m_elementInfos;
|
||
[SerializeField]
|
||
private float m_w;
|
||
[SerializeField]
|
||
private float m_h;
|
||
|
||
public float W => m_w;
|
||
public float H => m_h;
|
||
public int Count => m_elementInfos == null ? 0 : m_elementInfos.Count;
|
||
|
||
public LayoutInfo(List<ElementInfo> elementInfos, float w, float h)
|
||
{
|
||
this.m_elementInfos = elementInfos;
|
||
this.m_w = w;
|
||
this.m_h = h;
|
||
}
|
||
|
||
public IEnumerator<ElementInfo> GetEnumerator()
|
||
{
|
||
return ((IEnumerable<ElementInfo>)m_elementInfos).GetEnumerator();
|
||
}
|
||
|
||
IEnumerator IEnumerable.GetEnumerator()
|
||
{
|
||
return ((IEnumerable)m_elementInfos).GetEnumerator();
|
||
}
|
||
|
||
[Serializable]
|
||
public class ElementInfo
|
||
{
|
||
public string name;
|
||
|
||
public float x;
|
||
public float y;
|
||
public float w;
|
||
public float h;
|
||
|
||
public LayoutInfo layoutInfo;
|
||
|
||
public float2 Position
|
||
{
|
||
get {
|
||
float x = (layoutInfo.W / 2f) * -1 + this.x + this.w / 2f;
|
||
float y = layoutInfo.H / 2f - this.y - this.h / 2f;
|
||
|
||
return new float2(x, y);
|
||
}
|
||
}
|
||
|
||
public Rect Rect {
|
||
get {
|
||
var pos = Position - new float2(this.w / 2f, this.h / 2f);
|
||
return new(pos.x, pos.y, this.w, this.h);
|
||
}
|
||
}
|
||
}
|
||
|
||
[Serializable]
|
||
public class ImageInfo : ElementInfo
|
||
{
|
||
public string imgPath;
|
||
public string imgSlicePath; // 九宫格图片路径
|
||
public bool HaveSlice => imgSlicePath != null; // 是否有九宫格
|
||
}
|
||
|
||
[Serializable]
|
||
public class PrefabInfo : ElementInfo
|
||
{
|
||
public string prefabName;
|
||
}
|
||
|
||
[Serializable]
|
||
public class TextInfo : ElementInfo
|
||
{
|
||
public string text;
|
||
public float size;
|
||
public Color color;
|
||
public string align;
|
||
public string font;
|
||
public float strokeSize;
|
||
public Color strokeColor;
|
||
|
||
public bool IsStroke => strokeSize != 0;
|
||
}
|
||
}
|
||
|
||
[Serializable]
|
||
public struct TargetImageTransformInfo
|
||
{
|
||
public float3 position;
|
||
public RotScaleInfoItem rotScaleInfo;
|
||
|
||
public string ImgPath => rotScaleInfo.imgPath;
|
||
}
|
||
|
||
[Serializable]
|
||
public struct RotScaleInfoItem
|
||
{
|
||
public string imgPath; //(效果图)
|
||
public float rotiation;
|
||
public float2 scale;
|
||
public bool similarityCalc;
|
||
}
|
||
}
|
||
#endif
|
||
|