| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352 |
- using UnityEngine;
- using UnityEditor;
- namespace MapEditor
- {
- /// <summary>
- /// 网格地图编辑器 - 全新实现
- /// </summary>
- public class GridMapEditor : EditorWindow
- {
- // Canvas相关
- private Canvas targetCanvas;
- private Vector2 canvasSize;
-
- // Sprite相关
- private Sprite currentSprite;
- private Vector2 spriteSize;
-
- // 图层系统
- [System.Serializable]
- public class SpriteLayer
- {
- public Sprite sprite;
- public string name;
- public bool isVisible = true;
- public bool isPreviewVisible = true; // 在预览窗体中是否可见
-
- public SpriteLayer(Sprite sprite)
- {
- this.sprite = sprite;
- this.name = sprite != null ? sprite.name : "未命名图层";
- }
- }
-
- private System.Collections.Generic.List<SpriteLayer> spriteLayersList = new System.Collections.Generic.List<SpriteLayer>();
- private int selectedLayerIndex = -1;
- private Vector2 layerListScrollPosition;
- private int draggedLayerIndex = -1;
-
- // 网格相关
- private int gridColumns = 0;
- private int gridRows = 0;
-
- // UI相关
- private Vector2 scrollPosition;
- private Rect previewRect;
- private float previewScale = 1f;
- private bool isPaintingEnabled = true; // 左键绘制,右键擦除
- private bool showOtherLayers = true; // 是否显示其他图层(半透明)
-
- // 颜色
- private Color gridColor = new Color(0.3f, 0.3f, 0.3f, 0.8f); // 更明显的网格线
- private Color backgroundColor = new Color(0.2f, 0.2f, 0.2f, 1f);
- // 配置数据模型(仅用于JSON序列化)
- [System.Serializable]
- private class MapConfig
- {
- public string canvasName;
- public float canvasWidth;
- public float canvasHeight;
- public System.Collections.Generic.List<LayerConfig> layers = new System.Collections.Generic.List<LayerConfig>();
- }
- [System.Serializable]
- private class LayerConfig
- {
- public string name;
- public string spriteAssetPath; // 仅编辑器可用
- public string resourcesPath; // 运行时可用(Assets/Resources 下)
- public bool isVisible;
- public bool isPreviewVisible;
- public System.Collections.Generic.List<ItemConfig> items = new System.Collections.Generic.List<ItemConfig>();
- }
- [System.Serializable]
- private class ItemConfig
- {
- public int cellX;
- public int cellY;
- public float posX; // Canvas坐标(以中心为原点)
- public float posY;
- }
- // 放置的数据:按Sprite区分的"图层"
- private System.Collections.Generic.Dictionary<Sprite, System.Collections.Generic.Dictionary<Vector2Int, GameObject>> spriteLayers = new System.Collections.Generic.Dictionary<Sprite, System.Collections.Generic.Dictionary<Vector2Int, GameObject>>();
-
- // 每个图层的Canvas绝对位置记录
- private System.Collections.Generic.Dictionary<Sprite, System.Collections.Generic.Dictionary<Vector2Int, Vector2>> layerCanvasPositions = new System.Collections.Generic.Dictionary<Sprite, System.Collections.Generic.Dictionary<Vector2Int, Vector2>>();
- // 单元格间距(Canvas单位,像素),默认0
- private Vector2 cellGap = Vector2.zero;
- [MenuItem("工具/网格地图编辑器")]
- public static void ShowWindow()
- {
- GridMapEditor window = GetWindow<GridMapEditor>("网格地图编辑器");
- window.minSize = new Vector2(600, 600);
- }
- private void OnGUI()
- {
- DrawToolbar();
- EditorGUILayout.Space(10);
-
- if (targetCanvas != null && spriteLayersList.Count > 0)
- {
- DrawPreviewArea();
- }
- else
- {
- DrawHelpBox();
- }
- }
- /// <summary>
- /// 绘制工具栏
- /// </summary>
- private void DrawToolbar()
- {
- EditorGUILayout.BeginVertical("box");
-
- GUILayout.Label("网格地图编辑器", EditorStyles.boldLabel);
- EditorGUILayout.Space(5);
-
- // Canvas选择
- EditorGUI.BeginChangeCheck();
- Canvas newCanvas = (Canvas)EditorGUILayout.ObjectField(
- "目标Canvas",
- targetCanvas,
- typeof(Canvas),
- true
- );
- if (EditorGUI.EndChangeCheck())
- {
- targetCanvas = newCanvas;
- UpdateCanvasSize();
- CalculateGrid();
- }
-
- if (targetCanvas != null)
- {
- EditorGUILayout.LabelField("Canvas大小", $"{canvasSize.x} x {canvasSize.y}");
- }
-
- EditorGUILayout.Space(5);
-
- // 图层管理
- DrawLayerManagement();
-
- EditorGUILayout.Space(5);
-
- // 网格信息
- if (gridColumns > 0 && gridRows > 0)
- {
- EditorGUILayout.LabelField("网格信息", $"{gridColumns} 列 x {gridRows} 行 = {gridColumns * gridRows} 个单元格");
- }
-
- EditorGUILayout.Space(5);
- // 单元间距设置
- EditorGUI.BeginChangeCheck();
- Vector2 newGap = EditorGUILayout.Vector2Field("单元间距", cellGap);
- if (EditorGUI.EndChangeCheck())
- {
- newGap.x = Mathf.Max(0, newGap.x);
- newGap.y = Mathf.Max(0, newGap.y);
- cellGap = newGap;
- CalculateGrid();
- }
-
- // 预览缩放
- previewScale = EditorGUILayout.Slider("预览缩放", previewScale, 0.1f, 2f);
-
- // 其他图层显示开关
- showOtherLayers = EditorGUILayout.Toggle("显示其他图层", showOtherLayers);
-
- EditorGUILayout.Space(10);
-
- // 配置保存/加载
- EditorGUILayout.BeginHorizontal();
- if (GUILayout.Button("保存配置", GUILayout.Height(24)))
- {
- SaveConfigToFile();
- }
- if (GUILayout.Button("加载配置", GUILayout.Height(24)))
- {
- LoadConfigFromFile();
- }
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.Space(5);
- // 保存按钮
- GUI.enabled = targetCanvas != null && HasPlacedSprites();
- if (GUILayout.Button("保存为纹理贴图", GUILayout.Height(30)))
- {
- SaveAsTexture();
- }
- GUI.enabled = true;
-
- EditorGUILayout.EndVertical();
- }
- /// <summary>
- /// 绘制图层管理UI
- /// </summary>
- private void DrawLayerManagement()
- {
- EditorGUILayout.BeginVertical("box");
- GUILayout.Label("图层管理", EditorStyles.boldLabel);
-
- // 添加新图层按钮
- EditorGUILayout.BeginHorizontal();
- if (GUILayout.Button("添加图层", GUILayout.Height(25)))
- {
- // 打开Sprite选择对话框
- string path = EditorUtility.OpenFilePanel("选择Sprite", "Assets", "png");
- if (!string.IsNullOrEmpty(path))
- {
- // 将绝对路径转换为相对路径
- if (path.StartsWith(Application.dataPath))
- {
- path = "Assets" + path.Substring(Application.dataPath.Length);
- }
-
- // 加载Sprite
- Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path);
- if (sprite != null)
- {
- AddLayer(sprite);
- }
- else
- {
- EditorUtility.DisplayDialog("错误", "无法加载Sprite,请确保选择的是有效的图片文件", "确定");
- }
- }
- }
- if (GUILayout.Button("清空所有图层", GUILayout.Height(25)))
- {
- if (EditorUtility.DisplayDialog("确认清空", "确定要清空所有图层吗?", "确定", "取消"))
- {
- ClearAllLayers();
- }
- }
- EditorGUILayout.EndHorizontal();
-
- EditorGUILayout.Space(5);
-
- // 图层列表
- if (spriteLayersList.Count > 0)
- {
- layerListScrollPosition = EditorGUILayout.BeginScrollView(layerListScrollPosition, GUILayout.Height(150));
-
- for (int i = 0; i < spriteLayersList.Count; i++)
- {
- DrawLayerItem(i);
- }
-
- EditorGUILayout.EndScrollView();
- }
- else
- {
- EditorGUILayout.HelpBox("暂无图层,请添加图层开始编辑", MessageType.Info);
- }
-
- EditorGUILayout.EndVertical();
- }
-
- /// <summary>
- /// 绘制单个图层项
- /// </summary>
- private void DrawLayerItem(int index)
- {
- if (index >= spriteLayersList.Count) return;
-
- var layer = spriteLayersList[index];
- bool isSelected = selectedLayerIndex == index;
-
- EditorGUILayout.BeginHorizontal();
-
- // 选择按钮
- if (GUILayout.Button(isSelected ? "●" : "○", GUILayout.Width(20), GUILayout.Height(20)))
- {
- selectedLayerIndex = index;
- currentSprite = layer.sprite;
- UpdateSpriteSize();
- CalculateGrid();
- Repaint();
- }
-
- // 场景可见性切换
- EditorGUILayout.LabelField("场景", GUILayout.Width(30));
- layer.isVisible = EditorGUILayout.Toggle(layer.isVisible, GUILayout.Width(20));
-
- // 预览可见性切换
- EditorGUILayout.LabelField("预览", GUILayout.Width(30));
- layer.isPreviewVisible = EditorGUILayout.Toggle(layer.isPreviewVisible, GUILayout.Width(20));
-
- // 图层名称
- EditorGUILayout.LabelField(layer.name, isSelected ? EditorStyles.boldLabel : EditorStyles.label);
-
- // 上下移动按钮
- EditorGUILayout.BeginVertical();
- if (GUILayout.Button("↑", GUILayout.Width(20), GUILayout.Height(15)))
- {
- MoveLayerUp(index);
- }
- if (GUILayout.Button("↓", GUILayout.Width(20), GUILayout.Height(15)))
- {
- MoveLayerDown(index);
- }
- EditorGUILayout.EndVertical();
-
- // 删除按钮
- if (GUILayout.Button("×", GUILayout.Width(20), GUILayout.Height(20)))
- {
- if (EditorUtility.DisplayDialog("删除图层", $"确定要删除图层 '{layer.name}' 吗?", "确定", "取消"))
- {
- RemoveLayer(index);
- }
- }
-
- EditorGUILayout.EndHorizontal();
-
- // 拖拽处理
- HandleLayerDrag(index);
-
- EditorGUILayout.Space(2);
- }
-
- /// <summary>
- /// 处理图层拖拽(简化版本)
- /// </summary>
- private void HandleLayerDrag(int index)
- {
- // 暂时禁用拖拽功能,避免卡顿
- // 可以通过上下箭头按钮来调整顺序
- }
- /// <summary>
- /// 绘制预览区域
- /// </summary>
- private void DrawPreviewArea()
- {
- EditorGUILayout.BeginVertical("box");
- GUILayout.Label("预览区域", EditorStyles.boldLabel);
-
- // 计算预览区域(取Canvas与网格尺寸中较大者)
- Vector2 cellSizeCanvas = new Vector2(spriteSize.x + cellGap.x, spriteSize.y + cellGap.y);
- float gridCanvasWidth = Mathf.Max(1, gridColumns) * cellSizeCanvas.x;
- float gridCanvasHeight = Mathf.Max(1, gridRows) * cellSizeCanvas.y;
- float drawCanvasWidth = Mathf.Max(canvasSize.x, gridCanvasWidth);
- float drawCanvasHeight = Mathf.Max(canvasSize.y, gridCanvasHeight);
- float scaledWidth = drawCanvasWidth * previewScale;
- float scaledHeight = drawCanvasHeight * previewScale;
-
- // 创建滚动视图
- scrollPosition = EditorGUILayout.BeginScrollView(
- scrollPosition,
- GUILayout.ExpandWidth(true),
- GUILayout.ExpandHeight(true)
- );
-
- // 获取预览区域的矩形
- previewRect = GUILayoutUtility.GetRect(
- scaledWidth,
- scaledHeight,
- GUILayout.ExpandWidth(false),
- GUILayout.ExpandHeight(false)
- );
-
- // 绘制背景(保持透明,不覆盖网格线)
- // EditorGUI.DrawRect(previewRect, backgroundColor);
-
- // 绘制网格
- DrawGrid(previewRect);
-
- // 处理鼠标
- HandleMouseInPreview(previewRect);
-
- EditorGUILayout.EndScrollView();
- EditorGUILayout.EndVertical();
- }
- /// <summary>
- /// 绘制网格
- /// </summary>
- private void DrawGrid(Rect rect)
- {
- if (gridColumns <= 0 || gridRows <= 0) return;
-
- Handles.BeginGUI();
-
- // 将Canvas单位映射到预览区域,保持等比(使用绘制区域的Canvas尺寸)
- Vector2 cellSizeCanvas = new Vector2(spriteSize.x + cellGap.x, spriteSize.y + cellGap.y);
- float gridCanvasWidth = Mathf.Max(1, gridColumns) * cellSizeCanvas.x;
- float gridCanvasHeight = Mathf.Max(1, gridRows) * cellSizeCanvas.y;
- float drawCanvasWidth = Mathf.Max(canvasSize.x, gridCanvasWidth);
- float drawCanvasHeight = Mathf.Max(canvasSize.y, gridCanvasHeight);
- float scaleX = rect.width / drawCanvasWidth;
- float scaleY = rect.height / drawCanvasHeight;
-
- // 计算Canvas在预览区域中的位置(居中显示)
- float canvasOffsetX = (rect.width - drawCanvasWidth * scaleX) / 2f;
- float canvasOffsetY = (rect.height - drawCanvasHeight * scaleY) / 2f;
-
- float cellWidthCanvas = spriteSize.x + cellGap.x;
- float cellHeightCanvas = spriteSize.y + cellGap.y;
- float cellWidth = cellWidthCanvas * scaleX;
- float cellHeight = cellHeightCanvas * scaleY;
- float gridWidth = gridColumns * cellWidth;
- float gridHeight = gridRows * cellHeight;
-
- // 网格起始位置(考虑Canvas偏移)
- float gridStartX = rect.x + canvasOffsetX;
- float gridStartY = rect.y + canvasOffsetY;
-
- // 绘制垂直线
- for (int x = 0; x <= gridColumns; x++)
- {
- float xPos = gridStartX + x * cellWidth;
- Handles.color = gridColor;
- Handles.DrawLine(
- new Vector3(xPos, gridStartY, 0),
- new Vector3(xPos, gridStartY + gridHeight, 0)
- );
- }
-
- // 绘制水平线
- for (int y = 0; y <= gridRows; y++)
- {
- float yPos = gridStartY + y * cellHeight;
- Handles.color = gridColor;
- Handles.DrawLine(
- new Vector3(gridStartX, yPos, 0),
- new Vector3(gridStartX + gridWidth, yPos, 0)
- );
- }
-
- // 绘制已放置的Sprite预览
- if (currentSprite != null)
- {
- DrawSpriteGrid(rect, cellWidth, cellHeight);
- }
-
- Handles.EndGUI();
- }
- /// <summary>
- /// 在网格中绘制Sprite
- /// </summary>
- private void DrawSpriteGrid(Rect rect, float cellWidth, float cellHeight)
- {
- if (spriteLayersList.Count == 0) return;
-
- // 计算Canvas在预览区域中的缩放和偏移
- Vector2 cellSizeCanvas = new Vector2(spriteSize.x + cellGap.x, spriteSize.y + cellGap.y);
- float gridCanvasWidth = Mathf.Max(1, gridColumns) * cellSizeCanvas.x;
- float gridCanvasHeight = Mathf.Max(1, gridRows) * cellSizeCanvas.y;
- float drawCanvasWidth = Mathf.Max(canvasSize.x, gridCanvasWidth);
- float drawCanvasHeight = Mathf.Max(canvasSize.y, gridCanvasHeight);
- float scaleX = rect.width / drawCanvasWidth;
- float scaleY = rect.height / drawCanvasHeight;
-
- // 计算Canvas在预览区域中的位置(居中显示)
- float canvasOffsetX = (rect.width - drawCanvasWidth * scaleX) / 2f;
- float canvasOffsetY = (rect.height - drawCanvasHeight * scaleY) / 2f;
-
- // 渲染所有图层(按顺序,从下到上)
- for (int layerIndex = 0; layerIndex < spriteLayersList.Count; layerIndex++)
- {
- var layer = spriteLayersList[layerIndex];
- if (!layer.isVisible || !layer.isPreviewVisible || layer.sprite == null) continue;
-
- bool isSelectedLayer = layerIndex == selectedLayerIndex;
-
- // 根据开关决定是否显示其他图层
- if (!isSelectedLayer && !showOtherLayers) continue;
-
- float layerOpacity = isSelectedLayer ? 1f : 0.5f; // 非选中图层半透明
-
- // 设置透明度
- Color originalColor = GUI.color;
- GUI.color = new Color(1f, 1f, 1f, layerOpacity);
-
- // 绘制该图层的所有Sprite(使用原始尺寸)
- DrawLayerSpritesWithOriginalSize(rect, layer, canvasOffsetX, canvasOffsetY, scaleX, scaleY);
-
- // 恢复颜色
- GUI.color = originalColor;
- }
- }
-
- /// <summary>
- /// 绘制单个图层的所有Sprite(使用记录的Canvas绝对位置)
- /// </summary>
- private void DrawLayerSpritesWithOriginalSize(Rect rect, SpriteLayer layer, float canvasOffsetX, float canvasOffsetY, float scaleX, float scaleY)
- {
- if (layer.sprite == null) return;
-
- Texture2D texture = layer.sprite.texture;
- Rect spriteRect = layer.sprite.rect;
-
- // 计算UV坐标
- Rect uv = new Rect(
- spriteRect.x / texture.width,
- spriteRect.y / texture.height,
- spriteRect.width / texture.width,
- spriteRect.height / texture.height
- );
-
- // 获取该图层的Sprite数据
- if (!spriteLayers.ContainsKey(layer.sprite)) return;
- var layerData = spriteLayers[layer.sprite];
-
- // 绘制该图层中已放置的Sprite
- foreach (var kvp in layerData)
- {
- Vector2Int cell = kvp.Key;
-
- // 使用记录的Canvas绝对位置
- if (!layerCanvasPositions.ContainsKey(layer.sprite) || !layerCanvasPositions[layer.sprite].ContainsKey(cell))
- {
- continue; // 没有位置记录,跳过
- }
-
- Vector2 canvasPosition = layerCanvasPositions[layer.sprite][cell];
-
- // 将Canvas坐标转换为预览区域坐标
- // Canvas坐标系:中心为原点,向右为+X,向上为+Y
- // 预览区域坐标系:左上角为原点,向右为+X,向下为+Y
- float previewX = rect.x + canvasOffsetX + (canvasPosition.x + canvasSize.x / 2f) * scaleX;
- float previewY = rect.y + canvasOffsetY + (canvasSize.y / 2f - canvasPosition.y) * scaleY;
-
- // 使用该图层Sprite的原始尺寸
- Vector2 originalSpriteSize = new Vector2(spriteRect.width, spriteRect.height);
-
- // 计算Sprite在预览区域中的实际尺寸(保持原始比例)
- float spriteScaleX = originalSpriteSize.x * scaleX;
- float spriteScaleY = originalSpriteSize.y * scaleY;
-
- // 计算居中位置
- float centerX = previewX - spriteScaleX / 2f;
- float centerY = previewY - spriteScaleY / 2f;
-
- Rect cellRect = new Rect(centerX, centerY, spriteScaleX, spriteScaleY);
-
- GUI.DrawTextureWithTexCoords(cellRect, texture, uv);
- }
- }
-
- /// <summary>
- /// 绘制单个图层的所有Sprite(旧方法,保持兼容)
- /// </summary>
- private void DrawLayerSprites(Rect rect, SpriteLayer layer, float canvasOffsetX, float canvasOffsetY, float scaleX, float scaleY)
- {
- if (layer.sprite == null) return;
-
- Texture2D texture = layer.sprite.texture;
- Rect spriteRect = layer.sprite.rect;
-
- // 计算UV坐标
- Rect uv = new Rect(
- spriteRect.x / texture.width,
- spriteRect.y / texture.height,
- spriteRect.width / texture.width,
- spriteRect.height / texture.height
- );
-
- // 获取该图层的Sprite数据
- if (!spriteLayers.ContainsKey(layer.sprite)) return;
- var layerData = spriteLayers[layer.sprite];
-
- float cellWidthCanvas = spriteSize.x + cellGap.x;
- float cellHeightCanvas = spriteSize.y + cellGap.y;
-
- // 绘制该图层中已放置的Sprite
- foreach (var kvp in layerData)
- {
- Vector2Int cell = kvp.Key;
- Rect cellRect = new Rect(
- rect.x + canvasOffsetX + cell.x * cellWidthCanvas * scaleX,
- rect.y + canvasOffsetY + cell.y * cellHeightCanvas * scaleY,
- spriteSize.x * scaleX,
- spriteSize.y * scaleY
- );
-
- GUI.DrawTextureWithTexCoords(cellRect, texture, uv);
- }
- }
- /// <summary>
- /// 处理预览区域内的鼠标事件(左键放置,右键删除)
- /// </summary>
- private void HandleMouseInPreview(Rect rect)
- {
- if (!isPaintingEnabled || selectedLayerIndex < 0 || selectedLayerIndex >= spriteLayersList.Count || targetCanvas == null) return;
-
- var selectedLayer = spriteLayersList[selectedLayerIndex];
- if (selectedLayer.sprite == null) return;
-
- Event e = Event.current;
- if (e == null) return;
- if (e.isMouse && (e.type == EventType.MouseDown || e.type == EventType.MouseDrag))
- {
- if (!rect.Contains(e.mousePosition)) return;
- // 只在MouseDown或按住拖动时响应
- int button = e.button; // 0左 1右
- Vector2Int? cell = ScreenToCell(rect, e.mousePosition);
- if (!cell.HasValue) return;
- if (button == 0)
- {
- PlaceSpriteAtCell(cell.Value, selectedLayer.sprite);
- e.Use();
- }
- else if (button == 1)
- {
- RemoveSpriteAtCell(cell.Value, selectedLayer.sprite);
- e.Use();
- }
- }
- }
- /// <summary>
- /// 将预览坐标转换为网格坐标
- /// </summary>
- private Vector2Int? ScreenToCell(Rect rect, Vector2 mousePos)
- {
- if (gridColumns <= 0 || gridRows <= 0) return null;
-
- Vector2 cellSizeCanvas = new Vector2(spriteSize.x + cellGap.x, spriteSize.y + cellGap.y);
- float gridCanvasWidth = Mathf.Max(1, gridColumns) * cellSizeCanvas.x;
- float gridCanvasHeight = Mathf.Max(1, gridRows) * cellSizeCanvas.y;
- float drawCanvasWidth = Mathf.Max(canvasSize.x, gridCanvasWidth);
- float drawCanvasHeight = Mathf.Max(canvasSize.y, gridCanvasHeight);
- float scaleX = rect.width / drawCanvasWidth;
- float scaleY = rect.height / drawCanvasHeight;
-
- // 计算Canvas在预览区域中的位置(居中显示)
- float canvasOffsetX = (rect.width - drawCanvasWidth * scaleX) / 2f;
- float canvasOffsetY = (rect.height - drawCanvasHeight * scaleY) / 2f;
-
- float cellWidthCanvas = cellSizeCanvas.x;
- float cellHeightCanvas = cellSizeCanvas.y;
-
- // 转换为Canvas坐标系
- float localXCanvas = (mousePos.x - rect.x - canvasOffsetX) / scaleX;
- float localYCanvas = (mousePos.y - rect.y - canvasOffsetY) / scaleY;
-
- int col = Mathf.FloorToInt(localXCanvas / cellWidthCanvas);
- int row = Mathf.FloorToInt(localYCanvas / cellHeightCanvas);
- col = Mathf.Clamp(col, 0, gridColumns - 1);
- row = Mathf.Clamp(row, 0, gridRows - 1);
- return new Vector2Int(col, row);
- }
- /// <summary>
- /// 在Canvas上指定单元放置一个Image
- /// </summary>
- private void PlaceSpriteAtCell(Vector2Int cell, Sprite sprite)
- {
- if (sprite == null) return;
-
- if (!spriteLayers.ContainsKey(sprite))
- {
- spriteLayers[sprite] = new System.Collections.Generic.Dictionary<Vector2Int, GameObject>();
- layerCanvasPositions[sprite] = new System.Collections.Generic.Dictionary<Vector2Int, Vector2>();
- }
- if (spriteLayers[sprite].ContainsKey(cell)) return; // 已存在
- GameObject parent = GetOrCreateLayerParent(sprite);
- GameObject go = new GameObject($"Cell_{cell.x}_{cell.y}");
- go.transform.SetParent(parent.transform, false);
- var img = go.AddComponent<UnityEngine.UI.Image>();
- img.sprite = sprite;
- RectTransform rectTransform = go.GetComponent<RectTransform>();
- rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
- rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
-
- // 使用该Sprite的原始尺寸
- Vector2 spriteSize = new Vector2(sprite.rect.width, sprite.rect.height);
- rectTransform.sizeDelta = spriteSize;
- // 计算该单元在Canvas中的锚定位置(以Canvas中心为原点,右为+X,上为+Y)
- // 使用当前选中图层的网格尺寸来计算位置
- float cellWCanvas = this.spriteSize.x + cellGap.x;
- float cellHCanvas = this.spriteSize.y + cellGap.y;
- float x = -canvasSize.x / 2f + cell.x * cellWCanvas + this.spriteSize.x / 2f;
- float y = canvasSize.y / 2f - cell.y * cellHCanvas - this.spriteSize.y / 2f;
-
- // 记录Canvas绝对位置
- Vector2 canvasPosition = new Vector2(x, y);
- layerCanvasPositions[sprite][cell] = canvasPosition;
- rectTransform.anchoredPosition = canvasPosition;
- spriteLayers[sprite][cell] = go;
- Repaint();
- }
- /// <summary>
- /// 删除指定单元的Image
- /// </summary>
- private void RemoveSpriteAtCell(Vector2Int cell, Sprite sprite)
- {
- if (sprite == null || !spriteLayers.ContainsKey(sprite)) return;
- if (!spriteLayers[sprite].ContainsKey(cell)) return;
- var go = spriteLayers[sprite][cell];
- if (go != null)
- {
- GameObject.DestroyImmediate(go);
- }
- spriteLayers[sprite].Remove(cell);
-
- // 清理位置记录
- if (layerCanvasPositions.ContainsKey(sprite) && layerCanvasPositions[sprite].ContainsKey(cell))
- {
- layerCanvasPositions[sprite].Remove(cell);
- }
-
- Repaint();
- }
- /// <summary>
- /// 按当前Sprite获取或创建一个层级父节点
- /// </summary>
- private GameObject GetOrCreateLayerParent(Sprite sprite)
- {
- string parentName = $"GridLayer_{sprite.name}";
- Transform existing = targetCanvas.transform.Find(parentName);
- if (existing != null) return existing.gameObject;
- GameObject parent = new GameObject(parentName);
- parent.transform.SetParent(targetCanvas.transform, false);
- return parent;
- }
- /// <summary>
- /// 绘制帮助框
- /// </summary>
- private void DrawHelpBox()
- {
- EditorGUILayout.BeginVertical("box");
- EditorGUILayout.HelpBox(
- "请先完成以下设置:\n\n" +
- "1. 选择一个Canvas(用于确定画布大小)\n" +
- "2. 添加图层并选择Sprite图片(用于确定网格单元大小)\n\n" +
- "编辑器会自动计算网格数量并铺满Canvas",
- MessageType.Info
- );
- EditorGUILayout.EndVertical();
- }
- /// <summary>
- /// 更新Canvas大小
- /// </summary>
- private void UpdateCanvasSize()
- {
- if (targetCanvas == null)
- {
- canvasSize = Vector2.zero;
- return;
- }
-
- RectTransform rectTransform = targetCanvas.GetComponent<RectTransform>();
- if (rectTransform != null)
- {
- canvasSize = rectTransform.sizeDelta;
- }
- else
- {
- canvasSize = new Vector2(800, 600); // 默认值
- }
- }
- /// <summary>
- /// 更新Sprite大小
- /// </summary>
- private void UpdateSpriteSize()
- {
- if (currentSprite == null)
- {
- spriteSize = Vector2.zero;
- return;
- }
-
- // 使用Sprite的像素大小
- spriteSize = new Vector2(currentSprite.rect.width, currentSprite.rect.height);
- }
- /// <summary>
- /// 计算网格
- /// </summary>
- private void CalculateGrid()
- {
- if (targetCanvas == null || currentSprite == null)
- {
- gridColumns = 0;
- gridRows = 0;
- return;
- }
-
- if (spriteSize.x <= 0 || spriteSize.y <= 0)
- {
- gridColumns = 0;
- gridRows = 0;
- return;
- }
-
- // 计算需要多少个单元以覆盖至少Canvas尺寸(向上取整)
- float cellW = spriteSize.x + cellGap.x;
- float cellH = spriteSize.y + cellGap.y;
- gridColumns = Mathf.Max(1, Mathf.CeilToInt(canvasSize.x / Mathf.Max(1f, cellW)));
- gridRows = Mathf.Max(1, Mathf.CeilToInt(canvasSize.y / Mathf.Max(1f, cellH)));
-
- Repaint();
- }
- /// <summary>
- /// 检查是否有放置的Sprite
- /// </summary>
- private bool HasPlacedSprites()
- {
- foreach (var layer in spriteLayers.Values)
- {
- if (layer.Count > 0) return true;
- }
- return false;
- }
- /// <summary>
- /// 保存为纹理贴图
- /// </summary>
- private void SaveAsTexture()
- {
- if (targetCanvas == null || currentSprite == null) return;
- // 直接使用Canvas的实际尺寸作为纹理尺寸,不进行任何缩放
- int textureWidth = Mathf.RoundToInt(canvasSize.x);
- int textureHeight = Mathf.RoundToInt(canvasSize.y);
- // Canvas坐标系:中心为原点,向右为+X,向上为+Y
- // 纹理坐标系:左下角为原点,向右为+X,向上为+Y
- float minX = -canvasSize.x / 2f;
- float minY = -canvasSize.y / 2f;
- float maxX = canvasSize.x / 2f;
- float maxY = canvasSize.y / 2f;
- // 收集所有已放置的Sprite信息(按图层顺序)
- var entries = new System.Collections.Generic.List<(Sprite sprite, Texture2D tex, Rect spriteRect, Vector2 size, Vector2 center)>();
- // 按图层列表的顺序收集Sprite(确保渲染顺序正确)
- foreach (var layerInfo in spriteLayersList)
- {
- if (!layerInfo.isVisible || layerInfo.sprite == null) continue;
-
- if (spriteLayers.ContainsKey(layerInfo.sprite))
- {
- var dict = spriteLayers[layerInfo.sprite];
- foreach (var kvp in dict)
- {
- GameObject go = kvp.Value;
- if (go == null) continue;
- var rt = go.GetComponent<RectTransform>();
- var img = go.GetComponent<UnityEngine.UI.Image>();
- if (rt == null || img == null || img.sprite == null) continue;
- Vector2 size = rt.sizeDelta; // 实际显示尺寸(像素)
- Vector2 center = rt.anchoredPosition; // 以Canvas中心为原点
- var sp = img.sprite;
- entries.Add((sp, sp.texture, sp.rect, size, center));
- }
- }
- }
- // 创建纹理
- Texture2D finalTexture = new Texture2D(textureWidth, textureHeight, TextureFormat.RGBA32, false);
- // 填充透明背景(确保整个Canvas范围都是透明的)
- Color[] pixels = new Color[textureWidth * textureHeight];
- for (int i = 0; i < pixels.Length; i++) pixels[i] = Color.clear;
- finalTexture.SetPixels(pixels);
- // 2) 绘制每个已放置的Sprite元素:只渲染在Canvas范围内的部分
- foreach (var e in entries)
- {
- // 计算Sprite在Canvas坐标系中的边界
- float spriteLeft = e.center.x - e.size.x / 2f;
- float spriteRight = e.center.x + e.size.x / 2f;
- float spriteBottom = e.center.y - e.size.y / 2f;
- float spriteTop = e.center.y + e.size.y / 2f;
- // 检查Sprite是否与Canvas范围有交集
- if (spriteRight <= minX || spriteLeft >= maxX || spriteTop <= minY || spriteBottom >= maxY)
- {
- continue; // 完全超出Canvas范围,跳过
- }
- // 计算在Canvas范围内的裁剪区域
- float clipLeft = Mathf.Max(spriteLeft, minX);
- float clipRight = Mathf.Min(spriteRight, maxX);
- float clipBottom = Mathf.Max(spriteBottom, minY);
- float clipTop = Mathf.Min(spriteTop, maxY);
- // 转换为纹理坐标(左下角为原点)
- int startX = Mathf.RoundToInt(clipLeft - minX);
- int startY = Mathf.RoundToInt(clipBottom - minY);
- int endX = Mathf.RoundToInt(clipRight - minX);
- int endY = Mathf.RoundToInt(clipTop - minY);
- // 计算源纹理的UV偏移(由于裁剪)
- float uvOffsetX = (clipLeft - spriteLeft) / e.size.x;
- float uvOffsetY = (clipBottom - spriteBottom) / e.size.y;
- float uvScaleX = (clipRight - clipLeft) / e.size.x;
- float uvScaleY = (clipTop - clipBottom) / e.size.y;
- // 源UV
- Rect spriteRect = e.spriteRect;
- Texture2D spriteTexture = e.tex;
- Rect baseUv = new Rect(
- spriteRect.x / spriteTexture.width,
- spriteRect.y / spriteTexture.height,
- spriteRect.width / spriteTexture.width,
- spriteRect.height / spriteTexture.height
- );
- // 应用裁剪后的UV
- Rect uv = new Rect(
- baseUv.x + uvOffsetX * baseUv.width,
- baseUv.y + uvOffsetY * baseUv.height,
- baseUv.width * uvScaleX,
- baseUv.height * uvScaleY
- );
- // 确保坐标在有效范围内
- startX = Mathf.Clamp(startX, 0, textureWidth - 1);
- startY = Mathf.Clamp(startY, 0, textureHeight - 1);
- endX = Mathf.Clamp(endX, 0, textureWidth);
- endY = Mathf.Clamp(endY, 0, textureHeight);
- for (int y = startY; y < endY; y++)
- {
- for (int x = startX; x < endX; x++)
- {
- float u = (x - startX) / (float)(endX - startX) * uv.width + uv.x;
- float v = (y - startY) / (float)(endY - startY) * uv.height + uv.y;
- int sx = Mathf.Clamp(Mathf.RoundToInt(u * spriteTexture.width), 0, spriteTexture.width - 1);
- int sy = Mathf.Clamp(Mathf.RoundToInt(v * spriteTexture.height), 0, spriteTexture.height - 1);
- Color pc = spriteTexture.GetPixel(sx, sy);
- int fi = y * textureWidth + x;
- if (pc.a > 0)
- {
- pixels[fi] = Color.Lerp(pixels[fi], pc, pc.a);
- }
- }
- }
- }
- // 应用像素到纹理
- finalTexture.SetPixels(pixels);
- finalTexture.Apply();
- // 保存纹理文件
- string fileName = $"GridMap_{System.DateTime.Now:yyyyMMdd_HHmmss}.png";
- string filePath = EditorUtility.SaveFilePanel("保存网格地图纹理", "Assets", fileName, "png");
-
- if (!string.IsNullOrEmpty(filePath))
- {
- byte[] pngData = finalTexture.EncodeToPNG();
- System.IO.File.WriteAllBytes(filePath, pngData);
-
- // 刷新资源数据库
- AssetDatabase.Refresh();
-
- // 自动清理生成的GameObject和图层数据
- CleanupAllData();
-
- EditorUtility.DisplayDialog("保存成功", $"网格地图已保存为纹理贴图:\n{filePath}\n\n纹理尺寸:{textureWidth}x{textureHeight}\n(与Canvas尺寸完全一致,超出部分不渲染)\n\n已自动清理生成的GameObject和图层数据", "确定");
- }
- // 清理临时纹理
- if (finalTexture != null)
- {
- DestroyImmediate(finalTexture);
- }
- }
- /// <summary>
- /// 添加新图层
- /// </summary>
- public void AddLayer(Sprite sprite)
- {
- if (sprite == null) return;
-
- var newLayer = new SpriteLayer(sprite);
- spriteLayersList.Add(newLayer);
- selectedLayerIndex = spriteLayersList.Count - 1;
- currentSprite = sprite;
- UpdateSpriteSize();
- CalculateGrid();
-
- // 更新GameObject的渲染顺序
- UpdateGameObjectRenderOrder();
-
- Repaint();
- }
-
- /// <summary>
- /// 删除图层
- /// </summary>
- private void RemoveLayer(int index)
- {
- if (index < 0 || index >= spriteLayersList.Count) return;
-
- var layer = spriteLayersList[index];
-
- // 清理该图层的GameObject
- if (targetCanvas != null)
- {
- string parentName = $"GridLayer_{layer.sprite.name}";
- Transform existing = targetCanvas.transform.Find(parentName);
- if (existing != null)
- {
- DestroyImmediate(existing.gameObject);
- }
- }
-
- // 从列表中移除
- spriteLayersList.RemoveAt(index);
-
- // 更新选中索引
- if (selectedLayerIndex == index)
- {
- selectedLayerIndex = -1;
- currentSprite = null;
- }
- else if (selectedLayerIndex > index)
- {
- selectedLayerIndex--;
- }
-
- // 如果还有图层,选择第一个
- if (spriteLayersList.Count > 0 && selectedLayerIndex == -1)
- {
- selectedLayerIndex = 0;
- currentSprite = spriteLayersList[0].sprite;
- UpdateSpriteSize();
- CalculateGrid();
- }
-
- Repaint();
- }
-
- /// <summary>
- /// 向上移动图层
- /// </summary>
- private void MoveLayerUp(int index)
- {
- if (index <= 0) return;
-
- var layer = spriteLayersList[index];
- spriteLayersList.RemoveAt(index);
- spriteLayersList.Insert(index - 1, layer);
-
- // 更新选中索引
- if (selectedLayerIndex == index)
- {
- selectedLayerIndex = index - 1;
- }
- else if (selectedLayerIndex == index - 1)
- {
- selectedLayerIndex = index;
- }
-
- // 更新GameObject的渲染顺序
- UpdateGameObjectRenderOrder();
-
- Repaint();
- }
-
- /// <summary>
- /// 向下移动图层
- /// </summary>
- private void MoveLayerDown(int index)
- {
- if (index >= spriteLayersList.Count - 1) return;
-
- var layer = spriteLayersList[index];
- spriteLayersList.RemoveAt(index);
- spriteLayersList.Insert(index + 1, layer);
-
- // 更新选中索引
- if (selectedLayerIndex == index)
- {
- selectedLayerIndex = index + 1;
- }
- else if (selectedLayerIndex == index + 1)
- {
- selectedLayerIndex = index;
- }
-
- // 更新GameObject的渲染顺序
- UpdateGameObjectRenderOrder();
-
- Repaint();
- }
-
- /// <summary>
- /// 更新GameObject的渲染顺序
- /// </summary>
- private void UpdateGameObjectRenderOrder()
- {
- if (targetCanvas == null) return;
-
- // 按照图层列表的顺序重新排列GameObject
- for (int i = 0; i < spriteLayersList.Count; i++)
- {
- var layer = spriteLayersList[i];
- if (layer.sprite == null) continue;
-
- string parentName = $"GridLayer_{layer.sprite.name}";
- Transform layerParent = targetCanvas.transform.Find(parentName);
- if (layerParent != null)
- {
- // 设置SiblingIndex来控制渲染顺序
- layerParent.SetSiblingIndex(i);
- }
- }
- }
- /// <summary>
- /// 清空所有图层
- /// </summary>
- private void ClearAllLayers()
- {
- // 使用统一的清理方法
- CleanupAllData();
- }
- /// <summary>
- /// 清理所有数据(保存后自动清理)
- /// </summary>
- private void CleanupAllData()
- {
- // 清理生成的GameObject
- CleanupGeneratedObjects();
-
- // 清理图层列表
- spriteLayersList.Clear();
- selectedLayerIndex = -1;
- currentSprite = null;
- spriteSize = Vector2.zero;
- gridColumns = 0;
- gridRows = 0;
-
- Repaint();
- }
- /// <summary>
- /// 清理生成的GameObject
- /// </summary>
- private void CleanupGeneratedObjects()
- {
- if (targetCanvas == null) return;
- // 删除所有以"GridLayer_"开头的子对象
- for (int i = targetCanvas.transform.childCount - 1; i >= 0; i--)
- {
- Transform child = targetCanvas.transform.GetChild(i);
- if (child.name.StartsWith("GridLayer_"))
- {
- DestroyImmediate(child.gameObject);
- }
- }
- // 清空数据
- spriteLayers.Clear();
- layerCanvasPositions.Clear();
- Repaint();
- }
- // -------- 配置保存/加载 --------
- private void SaveConfigToFile()
- {
- if (targetCanvas == null)
- {
- EditorUtility.DisplayDialog("提示", "请先选择Canvas后再保存配置", "确定");
- return;
- }
- var cfg = BuildCurrentConfig();
- string fileName = $"GridMapConfig_{System.DateTime.Now:yyyyMMdd_HHmmss}.json";
- string path = EditorUtility.SaveFilePanel("保存配置", "Assets", fileName, "json");
- if (string.IsNullOrEmpty(path)) return;
- string json = JsonUtility.ToJson(cfg, true);
- System.IO.File.WriteAllText(path, json, System.Text.Encoding.UTF8);
- AssetDatabase.Refresh();
- // 保存后自动清理
- CleanupAllData();
- EditorUtility.DisplayDialog("保存成功", "配置已保存并已自动清理现场。", "确定");
- }
- private MapConfig BuildCurrentConfig()
- {
- var cfg = new MapConfig
- {
- canvasName = targetCanvas != null ? targetCanvas.name : string.Empty,
- canvasWidth = canvasSize.x,
- canvasHeight = canvasSize.y
- };
- for (int i = 0; i < spriteLayersList.Count; i++)
- {
- var layer = spriteLayersList[i];
- if (layer.sprite == null) continue;
- var layerCfg = new LayerConfig
- {
- name = layer.name,
- isVisible = layer.isVisible,
- isPreviewVisible = layer.isPreviewVisible,
- spriteAssetPath = AssetDatabase.GetAssetPath(layer.sprite),
- resourcesPath = GetResourcesPath(layer.sprite)
- };
- if (spriteLayers.ContainsKey(layer.sprite))
- {
- var dict = spriteLayers[layer.sprite];
- foreach (var kv in dict)
- {
- Vector2Int cell = kv.Key;
- Vector2 pos;
- if (layerCanvasPositions.ContainsKey(layer.sprite) && layerCanvasPositions[layer.sprite].TryGetValue(cell, out pos))
- {
- layerCfg.items.Add(new ItemConfig
- {
- cellX = cell.x,
- cellY = cell.y,
- posX = pos.x,
- posY = pos.y
- });
- }
- }
- }
- cfg.layers.Add(layerCfg);
- }
- return cfg;
- }
- private void LoadConfigFromFile()
- {
- string path = EditorUtility.OpenFilePanel("加载配置", "Assets", "json");
- if (string.IsNullOrEmpty(path)) return;
- string json = System.IO.File.ReadAllText(path, System.Text.Encoding.UTF8);
- LoadConfigFromJson(json);
- }
- // 可在运行时调用
- public void LoadConfigFromJson(string json)
- {
- if (string.IsNullOrEmpty(json)) return;
- var cfg = JsonUtility.FromJson<MapConfig>(json);
- if (cfg == null) return;
- // 清空现有
- ClearAllLayers();
- // 恢复Canvas尺寸(仅编辑器显示用)
- canvasSize = new Vector2(cfg.canvasWidth, cfg.canvasHeight);
- // 重建图层
- foreach (var layerCfg in cfg.layers)
- {
- Sprite sp = null;
- // 优先从Asset路径加载(编辑器)
- if (!string.IsNullOrEmpty(layerCfg.spriteAssetPath))
- {
- sp = AssetDatabase.LoadAssetAtPath<Sprite>(layerCfg.spriteAssetPath);
- }
- // 其次尝试Resources路径(运行时)
- if (sp == null && !string.IsNullOrEmpty(layerCfg.resourcesPath))
- {
- sp = Resources.Load<Sprite>(layerCfg.resourcesPath);
- }
- if (sp == null) continue;
- AddLayer(sp);
- var layer = spriteLayersList[spriteLayersList.Count - 1];
- layer.name = string.IsNullOrEmpty(layerCfg.name) ? sp.name : layerCfg.name;
- layer.isVisible = layerCfg.isVisible;
- layer.isPreviewVisible = layerCfg.isPreviewVisible;
- // 以当前选中图层的网格基准进行单元计算,但位置使用记录的Canvas位置
- foreach (var item in layerCfg.items)
- {
- Vector2Int cell = new Vector2Int(item.cellX, item.cellY);
- if (!spriteLayers.ContainsKey(sp))
- {
- spriteLayers[sp] = new System.Collections.Generic.Dictionary<Vector2Int, GameObject>();
- }
- if (!layerCanvasPositions.ContainsKey(sp))
- {
- layerCanvasPositions[sp] = new System.Collections.Generic.Dictionary<Vector2Int, Vector2>();
- }
- // 创建GO
- GameObject parent = GetOrCreateLayerParent(sp);
- GameObject go = new GameObject($"Cell_{cell.x}_{cell.y}");
- go.transform.SetParent(parent.transform, false);
- var img = go.AddComponent<UnityEngine.UI.Image>();
- img.sprite = sp;
- var rt = go.GetComponent<RectTransform>();
- rt.anchorMin = new Vector2(0.5f, 0.5f);
- rt.anchorMax = new Vector2(0.5f, 0.5f);
- rt.sizeDelta = new Vector2(sp.rect.width, sp.rect.height);
- rt.anchoredPosition = new Vector2(item.posX, item.posY);
- spriteLayers[sp][cell] = go;
- layerCanvasPositions[sp][cell] = new Vector2(item.posX, item.posY);
- }
- }
- // 刷新
- UpdateSpriteSize();
- CalculateGrid();
- UpdateGameObjectRenderOrder();
- Repaint();
- }
- private static string GetResourcesPath(Sprite sprite)
- {
- string assetPath = AssetDatabase.GetAssetPath(sprite);
- if (string.IsNullOrEmpty(assetPath)) return string.Empty;
- const string key = "/Resources/";
- int idx = assetPath.LastIndexOf(key, System.StringComparison.OrdinalIgnoreCase);
- if (idx < 0) return string.Empty;
- string rel = assetPath.Substring(idx + key.Length);
- int dot = rel.LastIndexOf('.');
- if (dot >= 0) rel = rel.Substring(0, dot);
- return rel.Replace('\\', '/');
- }
- }
- }
|