PJ/Assets/scripts/Editor/LevelEditor.cs

88 lines
No EOL
2.9 KiB
C#

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<LevelEditor>("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 на префабах
}
}