I’ve been working on an asset to help with 2D world generation. It worked perfectly, however, I was required to use namespaces to make my code easier to understand.
After converting everything to use a namespace, it works but is very slow.
Before using a namespace, I was able to generate a world in under a second, but now it takes one to five seconds to generate.
Here’s what my code looks like:
namespace EasyWorldGen2D
{
public class WorldGenFunctions
{
public static void SetUp(Transform objectTransform)
{
Tilemap tilemap = new Tilemap();
tilemap = objectTransform.GetComponent<Tilemap>();
if (objectTransform.GetComponentInChildren<Tilemap>() == null)
{
CreateNewGrid(tilemap, objectTransform);
}
else
{
tilemap = objectTransform.GetComponentInChildren<Grid>().GetComponentInChildren<Tilemap>();
}
}
public static void CreateNewGrid(Tilemap objTilemap, Transform objTransform)
{
var grid = new GameObject("Grid").AddComponent<Grid>();
objTilemap = new GameObject("Tilemap").AddComponent<Tilemap>();
objTilemap.gameObject.AddComponent<TilemapRenderer>();
grid.cellLayout = GridLayout.CellLayout.Rectangle;
objTilemap.GetComponent<TilemapRenderer>().sortOrder = TilemapRenderer.SortOrder.BottomLeft;
objTilemap.transform.SetParent(grid.transform);
grid.transform.SetParent(objTransform);
}
public static void Generate(Coord[,] coord, Tiles tilesToUse, TileAndGenerationSettings settings, Tilemap tilemap ,Enum noiseType, int seed, float scaleFactor, int noiseModifier, bool isIsland)
{
Debug.Log("Generating");
for (int x = 0; x < coord.GetLength(0); x++)
{
for (int y = 0; y < coord.GetLength(1); y++)
{
coord[x, y] = new Coord();
Coord newCoordinate = coord[x, y];
float noiseValue_1 = new float();
float noiseValue_2 = new float();
if(noiseType.ToString() == "Simplex")
{
noiseValue_1 = noise.snoise(new float2((x / scaleFactor) + (seed * noiseModifier), (y / scaleFactor) + (seed * noiseModifier)));
noiseValue_2 = noise.snoise(new float2((x / scaleFactor) + (seed * 2 * noiseModifier), (y / scaleFactor) + (seed * 2 * noiseModifier)));
}
else if(noiseType.ToString() == "Perlin")
{
noiseValue_1 = noise.cnoise(new float2((x / scaleFactor) + (seed * noiseModifier), (y / scaleFactor) + (seed * noiseModifier)));
noiseValue_2 = noise.cnoise(new float2((x / scaleFactor) + (seed * 2 * noiseModifier), (y / scaleFactor) + (seed * 2 * noiseModifier)));
}
else if(noiseType.ToString() == "Both")
{
noiseValue_1 = noise.cnoise(new float2((x / scaleFactor) + (seed * noiseModifier), (y / scaleFactor) + (seed * noiseModifier)));
noiseValue_2 = noise.snoise(new float2((x / scaleFactor) + (seed * noiseModifier), (y / scaleFactor) + (seed * noiseModifier)));
}
//average both
float noiseValue = (noiseValue_1 + noiseValue_2) / 2f;
Vector3Int tileLocation = new Vector3Int(x, y);
if (isIsland)
{
noiseValue = MakeIsland(settings, noiseValue, new Vector2(x, y));
}
SetTiles(newCoordinate, tilesToUse, settings, tilemap, tileLocation, noiseValue);
}
}
}
private static void SetTiles(Coord coordinate, Tiles m_tiles, TileAndGenerationSettings settings, Tilemap objectTilemap, Vector3Int tileLocation, float noiseValue)
{
coordinate.isHighestValue = noiseValue < settings.highestValue_size && noiseValue > settings.secondHighestValue_size;
coordinate.isSecondHighestValue = noiseValue < settings.secondHighestValue_size && noiseValue > settings.secondLowestValue_size;
coordinate.isSecondLowestValue = noiseValue < settings.secondLowestValue_size && noiseValue > settings.lowestValue_size;
coordinate.isLowestValue = noiseValue < settings.lowestValue_size;
if (coordinate.isHighestValue)
{
Debug.Log(m_tiles.highestValue);
objectTilemap.SetTile(tileLocation, m_tiles.highestValue);
}
else if (coordinate.isSecondHighestValue)
{
Debug.Log(m_tiles.secondHighestValue);
objectTilemap.SetTile(tileLocation, m_tiles.secondHighestValue);
}
else if (coordinate.isSecondLowestValue)
{
Debug.Log(m_tiles.secondLowestValue);
objectTilemap.SetTile(tileLocation, m_tiles.secondLowestValue);
}
else if (coordinate.isLowestValue)
{
Debug.Log(m_tiles.lowestValue);
objectTilemap.SetTile(tileLocation, m_tiles.lowestValue);
}
}
private static float MakeIsland(TileAndGenerationSettings settings, float noiseValue, Vector2 tilePosition)
{
//Find Center
float center_width = settings.width / 2;
float center_height = settings.height / 2;
Vector2 center = new Vector2(center_width, center_height);
float distance = Vector2.Distance(tilePosition, center);
float avgSize_withdamping = (settings.width + settings.height) / (float)settings.islandFalloutSize;
if (distance > 0)
{
noiseValue = ((noiseValue * avgSize_withdamping) - distance) / avgSize_withdamping;
}
return noiseValue;
}
public static int GenerateSeed(TileAndGenerationSettings settings)
{
int seed;
if (settings.isUsingRandomSeed)
{
//print("Generating Random Seed");
seed = UnityEngine.Random.Range(1000, 9999);
settings.seed = seed;
}
else
{
//print("not random");
seed = settings.seed;
}
return seed;
}
public static void Clear(Transform objTransform)
{
try
{
Debug.Log("Clearing");
objTransform.GetComponentInChildren<Grid>().GetComponentInChildren<Tilemap>();
}
catch
{
Debug.Log("Could't clear");
}
return;
}
}
public class Coord
{
public bool isHighestValue;
public bool isSecondHighestValue;
public bool isSecondLowestValue;
public bool isLowestValue;
}
public class Tiles
{
public RuleTile highestValue;
public RuleTile secondHighestValue;
public RuleTile secondLowestValue;
public RuleTile lowestValue;
}
public class TileAndGenerationSettings
{
public int width;
public int height;
public float islandFalloutSize;
public bool isUsingRandomSeed;
public int seed;
public float highestValue_size;
public float lowestValue_size;
public float secondHighestValue_size;
public float secondLowestValue_size;
}
}
The above code is called in a separate script:
[ExecuteAlways]
public class WorldGen : MonoBehaviour
{
Coord[,] coord;
public int width = 100, height = 100;
public float scaleFactor = 25;
public int noiseModifier = 1;
public enum NoiseType { Simplex, Perlin, Both}
public NoiseType noiseType;
public int _seed;
public bool randomSeed;
[SerializeField] RuleTile highestValue;
[SerializeField] RuleTile secondHighestValue;
[SerializeField] RuleTile secondLowestValue;
[SerializeField] RuleTile lowestValue;
public float highestValue_size = 1, secondHighestValue_size = 0.3f, secondLowestValue_size = 0.2f, lowestValue_size = -0.2f;
public bool isIsland;
public float islandFalloutSize;
private void Update()
{
coord = new Coord[width, height];
}
public void UseAllGenerateMethods()
{
WorldGenFunctions.SetUp(transform);
WorldGenFunctions.Clear(transform);
Tiles tilesToUse = Tiles_Settings();
TileAndGenerationSettings settings = TileSettings_Settings();
int seed = WorldGenFunctions.GenerateSeed(settings);
_seed = seed;
WorldGenFunctions.Generate(coord, tilesToUse, settings, transform.GetComponentInChildren<Tilemap>(), noiseType, seed, scaleFactor, noiseModifier, isIsland);
}
private Tiles Tiles_Settings()
{
Tiles tiles = new Tiles();
tiles.lowestValue = lowestValue;
tiles.highestValue = highestValue;
tiles.secondHighestValue = secondHighestValue;
tiles.secondLowestValue = secondLowestValue;
return tiles;
}
private TileAndGenerationSettings TileSettings_Settings()
{
TileAndGenerationSettings tileSettings = new TileAndGenerationSettings();
tileSettings.width = width;
tileSettings.height = height;
tileSettings.islandFalloutSize = islandFalloutSize;
tileSettings.isUsingRandomSeed = randomSeed;
tileSettings.seed = _seed;
tileSettings.highestValue_size = highestValue_size;
tileSettings.lowestValue_size = lowestValue_size;
tileSettings.secondHighestValue_size = secondHighestValue_size;
tileSettings.secondLowestValue_size = secondLowestValue_size;
return tileSettings;
}
}
Is there anything in my code that could be causing an issue?