using UnityEngine; using UnityEditor; public class LevelEditor : EditorWindow { private GameObject prefabToPlace; private bool paintMode = false; private float gridSize = 1f; [MenuItem("Window/My Level Editor")] public static void ShowWindow() { GetWindow("Level Editor"); } private void OnGUI() { GUILayout.Label("Настройки редактора", EditorStyles.boldLabel); prefabToPlace = (GameObject)EditorGUILayout.ObjectField("Префаб блока", prefabToPlace, typeof(GameObject), false); gridSize = EditorGUILayout.FloatField("Размер сетки", gridSize); paintMode = GUILayout.Toggle(paintMode, "Режим рисования", "Button", GUILayout.Height(30)); if (paintMode) { EditorGUILayout.HelpBox("Зажми CTRL и кликай в сцене, чтобы ставить блоки. Shift + Клик — удаление.", MessageType.Info); } } private void OnEnable() { // Подписываемся на события SceneView SceneView.duringSceneGui += OnSceneGUI; } private void OnDisable() { SceneView.duringSceneGui -= OnSceneGUI; } private void OnSceneGUI(SceneView sceneView) { if (!paintMode || prefabToPlace == null) return; Event e = Event.current; // Отключаем стандартный выбор объектов в Unity, если зажат Ctrl if (e.control) { HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive)); if (e.type == Event.current.type && (e.type == EventType.MouseDown || e.type == EventType.MouseDrag)) { PlaceObject(e.mousePosition); e.Use(); } } } private void PlaceObject(Vector2 mousePos) { // Переводим координаты мыши в мировые координаты Ray ray = HandleUtility.GUIPointToWorldRay(mousePos); Vector3 worldPos = ray.origin; worldPos.z = 0; // Снаппинг (сетка) float snapX = Mathf.Round(worldPos.x / gridSize) * gridSize; float snapY = Mathf.Round(worldPos.y / gridSize) * gridSize; Vector3 spawnPos = new Vector3(snapX, snapY, 0); // Проверка: нет ли там уже такого объекта? if (CheckIfEmpty(spawnPos)) { GameObject newObj = (GameObject)PrefabUtility.InstantiatePrefab(prefabToPlace); newObj.transform.position = spawnPos; // Регистрируем для Undo (Ctrl+Z) Undo.RegisterCreatedObjectUndo(newObj, "Place Block"); } } private bool CheckIfEmpty(Vector3 pos) { return !Physics2D.OverlapPoint(pos); // Нужен Collider2D на префабах } }