633 lines
23 KiB
C#
633 lines
23 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
using OfficeOpenXml;
|
||
using ArtResource;
|
||
|
||
namespace DesignTools.Scene
|
||
{
|
||
/// <summary>
|
||
/// 场景标题和预览图配置工具
|
||
/// 读取 Docs/config/SceneData.xlsx 的 SceneData Sheet
|
||
/// 关联 ArtTableSO "SceneDataPic" 提供预览图选择
|
||
/// </summary>
|
||
public class SceneDataEditor : BaseDesignToolEditor
|
||
{
|
||
#region 常量
|
||
|
||
private const string SCENE_EXCEL_NAME = "SceneData.xlsx";
|
||
private const string SCENE_SHEET_NAME = "SceneData";
|
||
private const string RESOURCES_PATH_PREFIX = "Assets/Art_SubModule/GameMain/UI/UISprites/Area/";
|
||
private const string SCENE_DATA_PIC_TABLE_NAME = "SceneDataPic";
|
||
|
||
#endregion
|
||
|
||
#region 数据
|
||
|
||
private List<SceneRowData> sceneDataList = new List<SceneRowData>();
|
||
private ArtTableSO sceneDataPicSO;
|
||
private Dictionary<string, Sprite> spriteCache = new Dictionary<string, Sprite>();
|
||
private Dictionary<string, Texture2D> textureCache = new Dictionary<string, Texture2D>();
|
||
|
||
#endregion
|
||
|
||
#region 打开窗口
|
||
|
||
[MenuItem("策划工具/场景/场景标题和预览图配置")]
|
||
public static void ShowWindow()
|
||
{
|
||
var window = GetWindow<SceneDataEditor>("场景标题和预览图配置");
|
||
window.minSize = window.GetMinWindowSize();
|
||
window.Show();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region BaseDesignToolEditor 实现
|
||
|
||
protected override string GetDocsPathPrefKey() => "SceneDataEditor_DocsPath";
|
||
protected override string GetWindowTitle() => "场景标题和预览图配置";
|
||
protected override Vector2 GetMinWindowSize() => new Vector2(1300, 600);
|
||
|
||
protected override void LoadConfigData()
|
||
{
|
||
spriteCache.Clear();
|
||
textureCache.Clear();
|
||
LoadSceneDataPicSO();
|
||
LoadSceneDataExcel();
|
||
}
|
||
|
||
protected override void DrawDataEditor()
|
||
{
|
||
if (sceneDataPicSO == null)
|
||
{
|
||
EditorGUILayout.HelpBox(
|
||
$"未找到 ArtTableSO \"{SCENE_DATA_PIC_TABLE_NAME}\",预览图选择功能不可用。\n请先在美术资源工具中创建名为 \"{SCENE_DATA_PIC_TABLE_NAME}\" 的资源表。",
|
||
MessageType.Warning);
|
||
}
|
||
|
||
EditorGUILayout.BeginVertical("box");
|
||
|
||
// 标题 + 新增按钮
|
||
EditorGUILayout.BeginHorizontal();
|
||
EditorGUILayout.LabelField($"场景数据列表(共 {sceneDataList.Count} 条)", EditorStyles.boldLabel);
|
||
GUILayout.FlexibleSpace();
|
||
GUI.backgroundColor = Color.cyan;
|
||
if (GUILayout.Button("+ 新增行", GUILayout.Height(25), GUILayout.Width(100)))
|
||
{
|
||
AddNewRow();
|
||
}
|
||
GUI.backgroundColor = Color.white;
|
||
EditorGUILayout.EndHorizontal();
|
||
|
||
EditorGUILayout.Space(5);
|
||
|
||
// 表头
|
||
DrawTableHeader();
|
||
|
||
// 数据行
|
||
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
|
||
|
||
SceneRowData toDelete = null;
|
||
foreach (var data in sceneDataList)
|
||
{
|
||
DrawDataRow(data, ref toDelete);
|
||
}
|
||
|
||
if (toDelete != null)
|
||
{
|
||
sceneDataList.Remove(toDelete);
|
||
}
|
||
|
||
EditorGUILayout.EndScrollView();
|
||
EditorGUILayout.EndVertical();
|
||
}
|
||
|
||
protected override void SaveDataToExcel()
|
||
{
|
||
try
|
||
{
|
||
string excelPath = GetDocsConfigFilePath(SCENE_EXCEL_NAME);
|
||
if (!File.Exists(excelPath))
|
||
{
|
||
EditorUtility.DisplayDialog("错误", $"文件不存在: {excelPath}", "确定");
|
||
return;
|
||
}
|
||
|
||
using (var package = new ExcelPackage(new FileInfo(excelPath)))
|
||
{
|
||
var ws = package.Workbook.Worksheets[SCENE_SHEET_NAME];
|
||
if (ws == null)
|
||
{
|
||
EditorUtility.DisplayDialog("错误", $"未找到 Sheet: {SCENE_SHEET_NAME}", "确定");
|
||
return;
|
||
}
|
||
|
||
// 查找列索引
|
||
int idCol = -1, sceneIdCol = -1, areaIdCol = -1, titleCol = -1;
|
||
int iconCol = -1, iconGrayCol = -1, resPathCol = -1;
|
||
int colCount = ws.Dimension?.Columns ?? 0;
|
||
|
||
for (int c = 1; c <= colCount; c++)
|
||
{
|
||
string h = ws.Cells[1, c].Text;
|
||
switch (h)
|
||
{
|
||
case "Id": idCol = c; break;
|
||
case "SceneId": sceneIdCol = c; break;
|
||
case "AreaId": areaIdCol = c; break;
|
||
case "Title": titleCol = c; break;
|
||
case "Icon": iconCol = c; break;
|
||
case "IconGray": iconGrayCol = c; break;
|
||
case "ResourcesPath": resPathCol = c; break;
|
||
}
|
||
}
|
||
|
||
if (idCol < 0)
|
||
{
|
||
EditorUtility.DisplayDialog("错误", "表结构不正确,缺少 Id 列", "确定");
|
||
return;
|
||
}
|
||
|
||
// 清除现有数据行(从底部向上删除,保留前两行表头)
|
||
int existingRows = ws.Dimension?.Rows ?? 2;
|
||
for (int row = existingRows; row >= 3; row--)
|
||
{
|
||
ws.DeleteRow(row);
|
||
}
|
||
|
||
// 写入所有数据
|
||
for (int i = 0; i < sceneDataList.Count; i++)
|
||
{
|
||
int row = i + 3;
|
||
var data = sceneDataList[i];
|
||
|
||
ws.Cells[row, idCol].Value = data.Id;
|
||
if (sceneIdCol > 0) ws.Cells[row, sceneIdCol].Value = GetSceneId(data.Id);
|
||
if (areaIdCol > 0) ws.Cells[row, areaIdCol].Value = GetAreaId(data.Id);
|
||
if (titleCol > 0) ws.Cells[row, titleCol].Value = GetTitle(data.Id);
|
||
if (iconCol > 0) ws.Cells[row, iconCol].Value = data.Icon ?? "";
|
||
if (iconGrayCol > 0) ws.Cells[row, iconGrayCol].Value = data.IconGray ?? "";
|
||
if (resPathCol > 0) ws.Cells[row, resPathCol].Value = GetResourcesPath(data.Icon);
|
||
}
|
||
|
||
package.Save();
|
||
}
|
||
|
||
EditorUtility.DisplayDialog("保存成功",
|
||
"配置已保存到Excel文件!\n\n" +
|
||
"⚠️ 重要提醒:\n" +
|
||
"请及时在SourceTree或GitHubDesktop中:\n" +
|
||
"1. 提交(Commit)本次修改\n" +
|
||
"2. 推送(Push)到远程仓库\n\n" +
|
||
"避免与其他策划产生冲突!",
|
||
"我知道了");
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
EditorUtility.DisplayDialog("错误", $"保存失败: {e.Message}\n{e.StackTrace}", "确定");
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 数据加载
|
||
|
||
private void LoadSceneDataPicSO()
|
||
{
|
||
sceneDataPicSO = null;
|
||
|
||
string[] guids = AssetDatabase.FindAssets("t:ArtTableSO");
|
||
foreach (var guid in guids)
|
||
{
|
||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||
var so = AssetDatabase.LoadAssetAtPath<ArtTableSO>(path);
|
||
if (so != null && so.TableName == SCENE_DATA_PIC_TABLE_NAME)
|
||
{
|
||
sceneDataPicSO = so;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (sceneDataPicSO == null)
|
||
{
|
||
Debug.LogWarning($"未找到 ArtTableSO: {SCENE_DATA_PIC_TABLE_NAME},预览图选择功能将不可用");
|
||
}
|
||
}
|
||
|
||
private void LoadSceneDataExcel()
|
||
{
|
||
sceneDataList.Clear();
|
||
|
||
string excelPath = GetDocsConfigFilePath(SCENE_EXCEL_NAME);
|
||
if (!File.Exists(excelPath))
|
||
{
|
||
throw new Exception($"未找到文件: {excelPath}");
|
||
}
|
||
|
||
using (var package = new ExcelPackage(new FileInfo(excelPath)))
|
||
{
|
||
var ws = package.Workbook.Worksheets[SCENE_SHEET_NAME];
|
||
if (ws == null)
|
||
{
|
||
throw new Exception($"未找到 Sheet: {SCENE_SHEET_NAME}");
|
||
}
|
||
|
||
// 查找列
|
||
int idCol = -1, iconCol = -1, iconGrayCol = -1;
|
||
int colCount = ws.Dimension?.Columns ?? 0;
|
||
|
||
for (int c = 1; c <= colCount; c++)
|
||
{
|
||
string h = ws.Cells[1, c].Text;
|
||
if (h == "Id") idCol = c;
|
||
else if (h == "Icon") iconCol = c;
|
||
else if (h == "IconGray") iconGrayCol = c;
|
||
}
|
||
|
||
if (idCol < 0)
|
||
{
|
||
throw new Exception("表结构不正确,缺少 Id 列");
|
||
}
|
||
|
||
int rowCount = ws.Dimension?.Rows ?? 0;
|
||
for (int row = 3; row <= rowCount; row++)
|
||
{
|
||
string idText = ws.Cells[row, idCol].Text;
|
||
if (string.IsNullOrEmpty(idText)) continue;
|
||
if (!int.TryParse(idText, out int id)) continue;
|
||
|
||
sceneDataList.Add(new SceneRowData
|
||
{
|
||
Id = id,
|
||
Icon = iconCol > 0 ? (ws.Cells[row, iconCol].Text ?? "") : "",
|
||
IconGray = iconGrayCol > 0 ? (ws.Cells[row, iconGrayCol].Text ?? "") : "",
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region UI 绘制
|
||
|
||
private void DrawTableHeader()
|
||
{
|
||
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||
EditorGUILayout.LabelField("Id", EditorStyles.miniLabel, GUILayout.Width(35));
|
||
EditorGUILayout.LabelField("SceneId", EditorStyles.miniLabel, GUILayout.Width(55));
|
||
EditorGUILayout.LabelField("AreaId", EditorStyles.miniLabel, GUILayout.Width(45));
|
||
EditorGUILayout.LabelField("Title", EditorStyles.miniLabel, GUILayout.Width(170));
|
||
EditorGUILayout.LabelField("Icon", EditorStyles.miniLabel, GUILayout.Width(168));
|
||
EditorGUILayout.LabelField("预览", EditorStyles.miniLabel, GUILayout.Width(55));
|
||
EditorGUILayout.LabelField("IconGray", EditorStyles.miniLabel, GUILayout.Width(168));
|
||
EditorGUILayout.LabelField("预览", EditorStyles.miniLabel, GUILayout.Width(55));
|
||
EditorGUILayout.LabelField("ResourcesPath", EditorStyles.miniLabel);
|
||
EditorGUILayout.LabelField("", GUILayout.Width(60));
|
||
EditorGUILayout.EndHorizontal();
|
||
}
|
||
|
||
private void DrawDataRow(SceneRowData data, ref SceneRowData toDelete)
|
||
{
|
||
EditorGUILayout.BeginHorizontal();
|
||
|
||
// Id(只读)
|
||
EditorGUILayout.LabelField(data.Id.ToString(), GUILayout.Width(35));
|
||
|
||
// SceneId(自动)
|
||
EditorGUILayout.LabelField(GetSceneId(data.Id).ToString(), GUILayout.Width(55));
|
||
|
||
// AreaId(自动)
|
||
EditorGUILayout.LabelField(GetAreaId(data.Id).ToString(), GUILayout.Width(45));
|
||
|
||
// Title(自动)
|
||
EditorGUILayout.LabelField(GetTitle(data.Id), GUILayout.Width(170));
|
||
|
||
// Icon + 选择按钮
|
||
EditorGUILayout.BeginHorizontal(GUILayout.Width(168));
|
||
data.Icon = EditorGUILayout.TextField(data.Icon, GUILayout.Width(120));
|
||
GUI.enabled = sceneDataPicSO != null;
|
||
if (GUILayout.Button("设置预览图", EditorStyles.miniButton, GUILayout.Width(60)))
|
||
{
|
||
var capturedData = data;
|
||
SceneDataPicPickerWindow.Show(sceneDataPicSO, "选择 Icon 预览图", name =>
|
||
{
|
||
capturedData.Icon = name;
|
||
// 清除缓存以便刷新
|
||
spriteCache.Remove(name);
|
||
textureCache.Remove(name);
|
||
Repaint();
|
||
});
|
||
}
|
||
GUI.enabled = true;
|
||
EditorGUILayout.EndHorizontal();
|
||
|
||
// Icon 预览
|
||
DrawSpritePreview(data.Icon, 50);
|
||
|
||
// IconGray + 选择按钮
|
||
EditorGUILayout.BeginHorizontal(GUILayout.Width(168));
|
||
data.IconGray = EditorGUILayout.TextField(data.IconGray, GUILayout.Width(120));
|
||
GUI.enabled = sceneDataPicSO != null;
|
||
if (GUILayout.Button("设置预览图", EditorStyles.miniButton, GUILayout.Width(60)))
|
||
{
|
||
var capturedData = data;
|
||
SceneDataPicPickerWindow.Show(sceneDataPicSO, "选择 IconGray 预览图", name =>
|
||
{
|
||
capturedData.IconGray = name;
|
||
spriteCache.Remove(name);
|
||
textureCache.Remove(name);
|
||
Repaint();
|
||
});
|
||
}
|
||
GUI.enabled = true;
|
||
EditorGUILayout.EndHorizontal();
|
||
|
||
// IconGray 预览
|
||
DrawSpritePreview(data.IconGray, 50);
|
||
|
||
// ResourcesPath(自动,只读)
|
||
EditorGUILayout.LabelField(GetResourcesPath(data.Icon), EditorStyles.miniLabel);
|
||
|
||
// 删除按钮
|
||
GUI.backgroundColor = Color.red;
|
||
if (GUILayout.Button("删除", GUILayout.Width(60)))
|
||
{
|
||
if (EditorUtility.DisplayDialog("确认删除",
|
||
$"确定要删除 Id={data.Id} 的行吗?", "删除", "取消"))
|
||
{
|
||
toDelete = data;
|
||
}
|
||
}
|
||
GUI.backgroundColor = Color.white;
|
||
|
||
EditorGUILayout.EndHorizontal();
|
||
}
|
||
|
||
private void DrawSpritePreview(string spriteName, float size)
|
||
{
|
||
Rect previewRect = GUILayoutUtility.GetRect(size, size, GUILayout.Width(size), GUILayout.Height(size));
|
||
|
||
if (string.IsNullOrEmpty(spriteName))
|
||
{
|
||
EditorGUI.DrawRect(previewRect, new Color(0.3f, 0.3f, 0.3f, 1f));
|
||
return;
|
||
}
|
||
|
||
// 优先从 ArtTableSO 获取 Sprite
|
||
Sprite sprite = GetCachedSprite(spriteName);
|
||
if (sprite != null && sprite.texture != null)
|
||
{
|
||
EditorGUI.DrawRect(previewRect, new Color(0.5f, 0.5f, 0.5f, 1f));
|
||
|
||
Rect texCoords = sprite.textureRect;
|
||
Texture2D tex = sprite.texture;
|
||
Rect normalizedCoords = new Rect(
|
||
texCoords.x / tex.width,
|
||
texCoords.y / tex.height,
|
||
texCoords.width / tex.width,
|
||
texCoords.height / tex.height
|
||
);
|
||
|
||
float aspect = texCoords.width / texCoords.height;
|
||
Rect drawRect = previewRect;
|
||
if (aspect > 1)
|
||
{
|
||
float newHeight = previewRect.height / aspect;
|
||
drawRect.y += (previewRect.height - newHeight) * 0.5f;
|
||
drawRect.height = newHeight;
|
||
}
|
||
else
|
||
{
|
||
float newWidth = previewRect.width * aspect;
|
||
drawRect.x += (previewRect.width - newWidth) * 0.5f;
|
||
drawRect.width = newWidth;
|
||
}
|
||
|
||
GUI.DrawTextureWithTexCoords(drawRect, tex, normalizedCoords);
|
||
return;
|
||
}
|
||
|
||
// 回退:尝试直接从路径加载 Texture2D
|
||
Texture2D fallbackTex = GetCachedTexture(spriteName);
|
||
if (fallbackTex != null)
|
||
{
|
||
EditorGUI.DrawRect(previewRect, new Color(0.5f, 0.5f, 0.5f, 1f));
|
||
GUI.DrawTexture(previewRect, fallbackTex, ScaleMode.ScaleToFit);
|
||
}
|
||
else
|
||
{
|
||
EditorGUI.DrawRect(previewRect, new Color(0.3f, 0.3f, 0.3f, 1f));
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 数据操作
|
||
|
||
private void AddNewRow()
|
||
{
|
||
int newId = 1;
|
||
if (sceneDataList.Count > 0)
|
||
{
|
||
newId = sceneDataList.Max(x => x.Id) + 1;
|
||
}
|
||
|
||
sceneDataList.Add(new SceneRowData
|
||
{
|
||
Id = newId,
|
||
Icon = "",
|
||
IconGray = "",
|
||
});
|
||
|
||
scrollPosition = new Vector2(0, float.MaxValue);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 自动计算
|
||
|
||
private static int GetSceneId(int id) => ((id - 1) / 5) + 1;
|
||
private static int GetAreaId(int id) => ((id - 1) % 5) + 1;
|
||
private static string GetTitle(int id) => $"CS_ScenePanel_Scene{id}";
|
||
|
||
private static string GetResourcesPath(string icon)
|
||
{
|
||
if (string.IsNullOrEmpty(icon)) return "";
|
||
return $"{RESOURCES_PATH_PREFIX}{icon}.png";
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Sprite 缓存
|
||
|
||
private Sprite GetCachedSprite(string name)
|
||
{
|
||
if (string.IsNullOrEmpty(name)) return null;
|
||
if (spriteCache.ContainsKey(name)) return spriteCache[name];
|
||
|
||
Sprite result = null;
|
||
if (sceneDataPicSO != null)
|
||
{
|
||
var item = sceneDataPicSO.Items.FirstOrDefault(x => x.Name == name);
|
||
if (item != null) result = item.Sprite;
|
||
}
|
||
|
||
spriteCache[name] = result;
|
||
return result;
|
||
}
|
||
|
||
private Texture2D GetCachedTexture(string name)
|
||
{
|
||
if (string.IsNullOrEmpty(name)) return null;
|
||
if (textureCache.ContainsKey(name)) return textureCache[name];
|
||
|
||
string path = GetResourcesPath(name);
|
||
var tex = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
|
||
textureCache[name] = tex;
|
||
return tex;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 数据类
|
||
|
||
private class SceneRowData
|
||
{
|
||
public int Id;
|
||
public string Icon = "";
|
||
public string IconGray = "";
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|
||
/// <summary>
|
||
/// 场景预览图选择弹窗
|
||
/// 展示 SceneDataPic ArtTableSO 中的所有图片,点击选择后回调
|
||
/// </summary>
|
||
public class SceneDataPicPickerWindow : EditorWindow
|
||
{
|
||
private ArtTableSO tableSO;
|
||
private Action<string> onSelect;
|
||
private string searchFilter = "";
|
||
private Vector2 scrollPos;
|
||
|
||
private const float CELL_WIDTH = 120;
|
||
private const float CELL_HEIGHT = 130;
|
||
private const float IMAGE_SIZE = 80;
|
||
|
||
public static void Show(ArtTableSO tableSO, string title, Action<string> onSelect)
|
||
{
|
||
if (tableSO == null || tableSO.Items == null || tableSO.Items.Count == 0)
|
||
{
|
||
EditorUtility.DisplayDialog("错误", "SceneDataPic 资源表为空或不存在", "确定");
|
||
return;
|
||
}
|
||
|
||
var window = CreateInstance<SceneDataPicPickerWindow>();
|
||
window.titleContent = new GUIContent(title);
|
||
window.tableSO = tableSO;
|
||
window.onSelect = onSelect;
|
||
window.minSize = new Vector2(650, 450);
|
||
window.ShowUtility();
|
||
}
|
||
|
||
private void OnGUI()
|
||
{
|
||
if (tableSO == null)
|
||
{
|
||
EditorGUILayout.HelpBox("资源表未加载", MessageType.Error);
|
||
return;
|
||
}
|
||
|
||
// 搜索栏
|
||
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
|
||
EditorGUILayout.LabelField("搜索:", GUILayout.Width(40));
|
||
searchFilter = EditorGUILayout.TextField(searchFilter, EditorStyles.toolbarSearchField);
|
||
if (GUILayout.Button("×", EditorStyles.miniButton, GUILayout.Width(20)))
|
||
{
|
||
searchFilter = "";
|
||
GUI.FocusControl(null);
|
||
}
|
||
EditorGUILayout.EndHorizontal();
|
||
|
||
// 过滤
|
||
var items = tableSO.Items;
|
||
if (!string.IsNullOrEmpty(searchFilter))
|
||
{
|
||
string filter = searchFilter.ToLower();
|
||
items = items.Where(x => x.Name != null && x.Name.ToLower().Contains(filter)).ToList();
|
||
}
|
||
|
||
EditorGUILayout.LabelField($"共 {items.Count} 个资源(点击选择)", EditorStyles.miniLabel);
|
||
|
||
// 网格展示
|
||
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
|
||
|
||
float windowWidth = position.width - 30;
|
||
int columns = Mathf.Max(1, Mathf.FloorToInt(windowWidth / CELL_WIDTH));
|
||
|
||
for (int i = 0; i < items.Count; i += columns)
|
||
{
|
||
EditorGUILayout.BeginHorizontal();
|
||
for (int j = 0; j < columns && (i + j) < items.Count; j++)
|
||
{
|
||
DrawItemCell(items[i + j]);
|
||
}
|
||
GUILayout.FlexibleSpace();
|
||
EditorGUILayout.EndHorizontal();
|
||
}
|
||
|
||
EditorGUILayout.EndScrollView();
|
||
}
|
||
|
||
private void DrawItemCell(ArtItemData item)
|
||
{
|
||
EditorGUILayout.BeginVertical("box", GUILayout.Width(CELL_WIDTH), GUILayout.Height(CELL_HEIGHT));
|
||
|
||
// 图片预览
|
||
Rect imageRect = GUILayoutUtility.GetRect(IMAGE_SIZE, IMAGE_SIZE,
|
||
GUILayout.Width(IMAGE_SIZE), GUILayout.Height(IMAGE_SIZE));
|
||
|
||
if (item.Sprite != null && item.Sprite.texture != null)
|
||
{
|
||
Sprite sprite = item.Sprite;
|
||
Rect texCoords = sprite.textureRect;
|
||
Texture2D tex = sprite.texture;
|
||
Rect normalizedCoords = new Rect(
|
||
texCoords.x / tex.width,
|
||
texCoords.y / tex.height,
|
||
texCoords.width / tex.width,
|
||
texCoords.height / tex.height
|
||
);
|
||
|
||
EditorGUI.DrawRect(imageRect, new Color(0.4f, 0.4f, 0.4f, 1f));
|
||
GUI.DrawTextureWithTexCoords(imageRect, tex, normalizedCoords);
|
||
}
|
||
else
|
||
{
|
||
EditorGUI.DrawRect(imageRect, new Color(0.3f, 0.3f, 0.3f, 1f));
|
||
GUI.Label(imageRect, "无图片", EditorStyles.centeredGreyMiniLabel);
|
||
}
|
||
|
||
// 名称按钮(点击选择)
|
||
string displayName = item.Name ?? "???";
|
||
if (displayName.Length > 16)
|
||
{
|
||
displayName = displayName.Substring(0, 14) + "..";
|
||
}
|
||
if (GUILayout.Button(displayName, EditorStyles.miniButton))
|
||
{
|
||
onSelect?.Invoke(item.Name);
|
||
Close();
|
||
}
|
||
|
||
EditorGUILayout.EndVertical();
|
||
}
|
||
}
|
||
}
|