88 lines
No EOL
2.9 KiB
C#
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 на префабах
|
|
}
|
|
} |