97 lines
3.4 KiB
C#
97 lines
3.4 KiB
C#
using UnityEngine;
|
|
using UnityEditor;
|
|
using UnityEngine.AI;
|
|
|
|
public class SpawnEdgeMarkerTool2D : EditorWindow {
|
|
public Transform IslandCenter;
|
|
public GameObject MarkerPrefab;
|
|
|
|
public float SearchRadius = 10f;
|
|
public int RayCount = 16;
|
|
public float StepSize = 0.25f;
|
|
public float RayDepth = 2f;
|
|
public bool ShowSceneGizmos = true;
|
|
|
|
[MenuItem("Tools/2D Spawn Edge Marker Tool")]
|
|
public static void ShowWindow() => GetWindow<SpawnEdgeMarkerTool2D>("2D Spawn Edge Tool");
|
|
private void OnEnable() => SceneView.duringSceneGui += OnSceneGUI;
|
|
private void OnDisable() => SceneView.duringSceneGui -= OnSceneGUI;
|
|
|
|
private void OnGUI() {
|
|
IslandCenter = (Transform)EditorGUILayout.ObjectField("Island Center", IslandCenter, typeof(Transform), true);
|
|
MarkerPrefab = (GameObject)EditorGUILayout.ObjectField("Spawn Marker Prefab", MarkerPrefab, typeof(GameObject), false);
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
SearchRadius = EditorGUILayout.FloatField("Start Radius", SearchRadius);
|
|
RayCount = EditorGUILayout.IntField("Ray Count", RayCount);
|
|
StepSize = EditorGUILayout.FloatField("Step Size", StepSize);
|
|
RayDepth = EditorGUILayout.FloatField("NavMesh Sample Depth", RayDepth);
|
|
|
|
ShowSceneGizmos = EditorGUILayout.Toggle("Visualize in Scene", ShowSceneGizmos);
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
if (GUILayout.Button("Place Spawn Markers")) {
|
|
if (IslandCenter == null) {
|
|
Debug.LogError("Island Center must be assigned!");
|
|
return;
|
|
}
|
|
|
|
PlaceSpawnMarkers2D();
|
|
}
|
|
}
|
|
|
|
private void OnSceneGUI(SceneView sceneView) {
|
|
if (!ShowSceneGizmos || IslandCenter == null) return;
|
|
|
|
Vector3 center = IslandCenter.position;
|
|
Handles.color = Color.cyan;
|
|
|
|
for (int i = 0; i < RayCount; i++) {
|
|
float angle = (360f / RayCount) * i;
|
|
|
|
Vector3 direction = new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad), Mathf.Sin(angle * Mathf.Deg2Rad), 0f);
|
|
Vector3 start = center + direction * SearchRadius;
|
|
|
|
Handles.SphereHandleCap(0, start, Quaternion.identity, 0.2f, EventType.Repaint);
|
|
Handles.DrawLine(start, start - direction * 1.5f, 2);
|
|
}
|
|
|
|
SceneView.RepaintAll();
|
|
}
|
|
|
|
private void PlaceSpawnMarkers2D() {
|
|
Vector3 center = IslandCenter.position;
|
|
GameObject parent = new GameObject("EdgeSpawnMarkers2D");
|
|
Undo.RegisterCreatedObjectUndo(parent, "Create Spawn Markers");
|
|
|
|
for (int i = 0; i < RayCount; i++) {
|
|
float angle = (360f / RayCount) * i;
|
|
Vector3 direction = new Vector3(Mathf.Cos(angle * Mathf.Deg2Rad), Mathf.Sin(angle * Mathf.Deg2Rad), 0f);
|
|
Vector3 start = center + direction * SearchRadius;
|
|
|
|
for (float d = 0; d < SearchRadius; d += StepSize) {
|
|
Vector3 probe = start - direction * d;
|
|
|
|
// You can change this check based on your environment:
|
|
if (NavMesh.SamplePosition(probe, out NavMeshHit hit, RayDepth, NavMesh.AllAreas)) {
|
|
GameObject spawnPoint = MarkerPrefab != null
|
|
? (GameObject)PrefabUtility.InstantiatePrefab(MarkerPrefab)
|
|
: new GameObject($"SpawnPoint_{i}");
|
|
|
|
spawnPoint.transform.position = hit.position;
|
|
spawnPoint.transform.SetParent(parent.transform);
|
|
Undo.RegisterCreatedObjectUndo(spawnPoint, "Place SpawnPoint");
|
|
break;
|
|
}
|
|
|
|
// Optional: For purely 2D check using layer
|
|
// if (Physics2D.OverlapPoint(probe)) { ... }
|
|
}
|
|
}
|
|
|
|
Debug.Log($"? Placed {RayCount} 2D spawn markers.");
|
|
}
|
|
}
|