要实现一个 2D区域看上去很简单就是根据点x,y 或者 u,v绘制那么缩放要如何做呢//缩放的关键代码绘制的关键才对 private Vector2 UVToScreen(Rect rect, Vector2 uv) { float scale uvZoom * rect.width; float x rect.x (uv.x - uvPan.x) * scale; float y rect.y (1f - (uv.y - uvPan.y)) * scale; return new Vector2(x, y); }其实也没什么号解释的数学就是这么“奇妙”我也是多年之后才懂y k * x假如你看到这个公式就头疼说明你可能不太有理工科的思维加入你看到这个公式十个直线那么上面的代码你自然而然应该能理解 绘制一个个点就相等于绘制完整个2d平面2D平面绘制不好意思没有完整代码// 并非完整代码 // 裁剪绘制区域防止超出 GUI.BeginClip(viewRect); { Rect localRect new Rect(0, 0, viewRect.width, viewRect.height); // 网格 if (showGrid) DrawGrid(localRect); // 三角形线框 if (showTriangles cachedTriangles ! null cachedTriangles.Length 3) DrawTriangles(localRect, uvs); // UV点 if (showPoints) DrawPoints(localRect, uvs); // UV [0,1] 边界框 Color boundColor new Color(0.7f, 0.7f, 0.7f, 0.9f); DrawLine(UVToScreen(localRect, new Vector2(0, 0)), UVToScreen(localRect, new Vector2(1, 0)), boundColor, localRect); DrawLine(UVToScreen(localRect, new Vector2(1, 0)), UVToScreen(localRect, new Vector2(1, 1)), boundColor, localRect); DrawLine(UVToScreen(localRect, new Vector2(1, 1)), UVToScreen(localRect, new Vector2(0, 1)), boundColor, localRect); DrawLine(UVToScreen(localRect, new Vector2(0, 1)), UVToScreen(localRect, new Vector2(0, 0)), boundColor, localRect); // 坐标标签 DrawUVCornerLabels(localRect); } GUI.EndClip();鼠标滚轮 和拖放代码1.滚轮控制Zoom 这个参数2.按下滚轮中键控制 Pan 这个参数// 滚轮缩放以鼠标位置为中心 if (e.type EventType.ScrollWheel) { Vector2 mouseUV ScreenToUV(viewRect, e.mousePosition); float factor e.delta.y 0 ? 1.15f : 1f / 1.15f; uvZoom Mathf.Clamp(uvZoom * factor, 0.1f, 20f); // 调整 pan 使鼠标下的 UV 点不变 float newScale uvZoom * viewRect.width; uvPan.x mouseUV.x - (e.mousePosition.x - viewRect.x) / newScale; uvPan.y mouseUV.y - 1f (e.mousePosition.y - viewRect.y) / newScale; e.Use(); Repaint(); } // 中键拖动平移 else if (e.type EventType.MouseDown e.button 2) { isDragging true; dragStartMouse e.mousePosition; dragStartPan uvPan; e.Use(); } else if (e.type EventType.MouseDrag isDragging) { Vector2 delta e.mousePosition - dragStartMouse; float scale uvZoom * viewRect.width; uvPan.x dragStartPan.x - delta.x / scale; uvPan.y dragStartPan.y delta.y / scale; e.Use(); Repaint(); } else if (e.type EventType.MouseUp isDragging e.button 2) { isDragging false; e.Use(); }重点还是坐标转换现在用AI就很简单了uvToSceneSceneToUV参考一例子统计区域功能 x2 个:1.统计场景中的粒子2.Editor GetRect方法粒子代码一代码二GUILayoutUtility.GetRect 的方法GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); //var serObject new SerializedObject(player); //Debug.LogError(打印 go player.name); //FindRefPrintOutGameObject(serObject); OnPlayerDetailGUI(player as GameObject);//因为红色Awake()这行代码是在这里的只要把他Wrap一层就可以了 if (selecteRectIndex cursor) { Rect sectionRect GUILayoutUtility.GetLastRect(); Color prevColor GUI.color; GUI.color new Color(1f, 0f, 0f, 0.25f); GUI.DrawTexture(sectionRect, EditorGUIUtility.whiteTexture); GUI.color prevColor;Unity插件Linefy-Scene View Extension- drawing library for editor script-绘制矢量图参考二这哥们的Editor系列写的很清楚英文https://medium.com/dilaura_exp/unity-editor-scripting-series-chapter-8-reserving-and-retrieving-rects-999bf0cc4dfc