using System.Runtime.CompilerServices; using UnityEngine; public class MapMakerMain : MonoBehaviour { // Terrain width and height must be a power of two (e.g., 64, 128, 256) // for a valid heightmap resolution (power of two + 1). [SerializeField] private int mapWidth = 128; [SerializeField] private int mapHeight = 128; [SerializeField] private BFMTerrainType initialTerrainType = BFMTerrainType.Plain; [SerializeField][Range(0.1f, 5.0f)] private float hilliness = 1.0f; [SerializeField][Range(1f, 20f)] private float noiseScale = 10f; [SerializeField][Range(10f, 200f)] private float terrainMaxHeight = 20f; private BFMTerrainGenerator terrainGenerator; private NavMeshGenerator navMeshGenerator; private Terrain currentTerrain; void Start() { terrainGenerator = gameObject.AddComponent(); navMeshGenerator = gameObject.AddComponent(); // Initialize the map with specified dimensions InitializeComponents(); GenerateMap(mapWidth, mapHeight); } #if UNITY_EDITOR private bool m_DelayedUpdateScheduled = false; private void OnValidate() { if (m_DelayedUpdateScheduled) return; UnityEditor.EditorApplication.delayCall += () => { m_DelayedUpdateScheduled = false; // OnValidate can be called on prefabs, or when the component is not fully initialized. // We only want to run this on scene objects that are not being destroyed. if (this == null || !gameObject.scene.IsValid()) { return; } InitializeComponents(); GenerateMap(mapWidth, mapHeight); }; m_DelayedUpdateScheduled = true; } #endif private void InitializeComponents() { // Use GetComponent first to avoid adding multiple components if they already exist if (terrainGenerator == null) { terrainGenerator = GetComponent(); if (terrainGenerator == null) { terrainGenerator = gameObject.AddComponent(); } navMeshGenerator = GetComponent(); if (navMeshGenerator == null) { navMeshGenerator = gameObject.AddComponent(); } } } private void GenerateMap(int width, int height) { // Cleanup old terrain if it exists if (currentTerrain != null) { if (Application.isPlaying) { Destroy(currentTerrain.gameObject); } else { // Use DestroyImmediate when in the editor and not in play mode. DestroyImmediate(currentTerrain.gameObject); } } // Configure TerrainGenerator from MapMakerMain settings terrainGenerator.terrainType = initialTerrainType; terrainGenerator.hilliness = hilliness; terrainGenerator.noiseScale = noiseScale; terrainGenerator.terrainMaxHeight = terrainMaxHeight; // Generate terrain and NavMesh based on specified dimensions // Adjust the arguments below to match the correct overload of GenerateTerrain currentTerrain = terrainGenerator.GenerateTerrain(width, height); if (currentTerrain == null) { Debug.LogError("Terrain generation failed. Aborting map generation."); return; } navMeshGenerator.terrain = currentTerrain; navMeshGenerator.GenerateNavMesh(); } }