多轮审查和修复

This commit is contained in:
2026-05-12 15:34:08 +08:00
parent f55d2a57c3
commit ebbbb7332e
805 changed files with 838724 additions and 1905 deletions

View File

@@ -0,0 +1,140 @@
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
using BaseGames.World.Map;
namespace BaseGames.Editor.Map
{
/// <summary>
/// MapRoomDataSO 自定义编辑器(架构 15_MapShopModule §5
/// 在 Scene View 中直接拖拽调整房间格子位置/大小;提供一键居中 SceneView 快捷按钮。
/// 拖动自动吸附到整格精度;左下/右上角可独立拖动(含反转保护);支持 Undo。
/// </summary>
[CustomEditor(typeof(MapRoomDataSO))]
public class MapRoomDataEditor : UnityEditor.Editor
{
private const float CELL_SIZE = 1f; // 每格在 Scene 中的世界单位尺寸
private static readonly Color FillColor = new Color(0.2f, 0.6f, 1f, 0.15f);
private static readonly Color OutlineColor = new Color(0.2f, 0.6f, 1f, 0.9f);
private static readonly Color HandleColor = new Color(1f, 0.85f, 0.2f, 1f);
private static readonly GUIStyle LabelStyle = new GUIStyle
{
alignment = TextAnchor.MiddleCenter,
fontStyle = FontStyle.Bold,
normal = { textColor = Color.white },
};
private MapRoomDataSO _target;
private void OnEnable() => _target = (MapRoomDataSO)target;
// ── Inspector ─────────────────────────────────────────────────────────
public override void OnInspectorGUI()
{
DrawDefaultInspector();
EditorGUILayout.Space(8);
EditorGUILayout.HelpBox(
"在 Scene View 中可直接拖拽房间角点调整 GridPosition / GridSize。\n" +
"拖动自动吸附到 1 格精度,支持 Undo。",
MessageType.Info);
if (GUILayout.Button("居中 Scene View 到此房间", GUILayout.Height(28)))
CenterSceneViewOnRoom(_target);
}
// ── Scene GUI ─────────────────────────────────────────────────────────
private void OnSceneGUI()
{
if (_target == null) return;
Vector3 origin = new Vector3(
_target.GridPosition.x * CELL_SIZE,
_target.GridPosition.y * CELL_SIZE, 0f);
Vector3 size = new Vector3(
_target.GridSize.x * CELL_SIZE,
_target.GridSize.y * CELL_SIZE, 0f);
// 绘制半透明矩形Vector3[] 重载正确)
Handles.DrawSolidRectangleWithOutline(GetRectCorners(origin, size), FillColor, OutlineColor);
// 房间 ID 标签(居中、加粗、白色)
Handles.Label(origin + size * 0.5f,
string.IsNullOrEmpty(_target.RoomId) ? "(No RoomId)" : _target.RoomId,
LabelStyle);
// ── 双角控制点(左下 = BL右上 = TR────────────────────────────
EditorGUI.BeginChangeCheck();
Vector3 newBL = DragHandle(origin, "BL");
Vector3 newTR = DragHandle(origin + size, "TR");
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(_target, "Resize MapRoom");
// 防反转:确保 BL ≤ TR
float minX = Mathf.Min(newBL.x, newTR.x);
float minY = Mathf.Min(newBL.y, newTR.y);
float maxX = Mathf.Max(newBL.x, newTR.x);
float maxY = Mathf.Max(newBL.y, newTR.y);
_target.GridPosition = ToGrid(new Vector2(minX, minY));
var newSize = ToGrid(new Vector2(maxX, maxY)) - _target.GridPosition;
_target.GridSize = new Vector2Int(Mathf.Max(1, newSize.x), Mathf.Max(1, newSize.y));
EditorUtility.SetDirty(_target);
}
}
// ── 帮助方法 ──────────────────────────────────────────────────────────
private static Vector3 DragHandle(Vector3 pos, string label)
{
float sz = HandleUtility.GetHandleSize(pos) * 0.12f;
Color prev = Handles.color;
Handles.color = HandleColor;
var result = Handles.FreeMoveHandle(pos, sz, Vector3.zero, Handles.DotHandleCap);
Handles.color = prev;
return SnapToGrid(result);
}
/// <summary>将世界坐标吸附到最近格点。</summary>
private static Vector3 SnapToGrid(Vector3 world)
=> new(Mathf.Round(world.x / CELL_SIZE) * CELL_SIZE,
Mathf.Round(world.y / CELL_SIZE) * CELL_SIZE,
0f);
private static Vector2Int ToGrid(Vector2 world)
=> new(Mathf.RoundToInt(world.x / CELL_SIZE),
Mathf.RoundToInt(world.y / CELL_SIZE));
private static void CenterSceneViewOnRoom(MapRoomDataSO room)
{
if (room == null) return;
var sv = SceneView.lastActiveSceneView;
if (sv == null) return;
Vector3 center = new Vector3(
(room.GridPosition.x + room.GridSize.x * 0.5f) * CELL_SIZE,
(room.GridPosition.y + room.GridSize.y * 0.5f) * CELL_SIZE, 0f);
sv.Frame(new Bounds(center, new Vector3(
room.GridSize.x * CELL_SIZE * 2f,
room.GridSize.y * CELL_SIZE * 2f, 1f)), false);
}
private static Vector3[] GetRectCorners(Vector3 origin, Vector3 size)
=> new[]
{
origin,
origin + new Vector3(size.x, 0f, 0f),
origin + size,
origin + new Vector3(0f, size.y, 0f),
};
}
}
#endif