So, I’m pretty new to Unity. Been messing about for over 2 years off and on, but I haven’t completed anything. I’m making this RTS game as my first game. The players will be collecting the tiles on the map to craft stuff. And they will need to see the entire map at one time and the map will constantly be changing (tiles being removed and structures being built). Using offset hexagon tiles, so I decided not to use the tilemap because I wasn’t sure of a good way to make the tiles go off-grid with the tilemap. Idk if the tilemap would make it speedier or not. So the problem that I’m having is the map takes a long time to load and everything responds slowly once everything is loaded. The map that I uploaded is about half the size of the map I will need for a basic game.
So what I’m wondering is, is there a better way to instantiate all of these tiles? They will not have rigidbodies but, they will have colliders, and scripts on them. Also, I’m getting an ArugmentOutOfRangeException.
ArugmentOutOfRangeException: Index was out of range, Must be non-negative and less than the size of the collection.
I don’t understand why I’m getting this exception.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapGenerator : MonoBehaviour
{
[Header("Map Generator Attributes")]
[SerializeField] float mapDelayTime = 0.01f;
[SerializeField] int mapWidth = 256;
[SerializeField] int mapHeight = 256;
[SerializeField] int dirtPercentage = 45;
[SerializeField] int clayPercentage = 25;
[SerializeField] int sandPercentage = 15;
[SerializeField] int gravelPercentage = 15;
[SerializeField] int rockPercentage = 15;
[SerializeField] int waterPercentage = 15;
[Header("Perlin Noise Attributes")]
public int width = 240;
public int height = 135;
public float scale = 8f;
public float offsetX = 100f;
public float offsetY = 100f;
[SerializeField] float clayMin;
[SerializeField] float clayMax;
[SerializeField] float rockMin;
[SerializeField] float rockMax;
[SerializeField] float waterMin;
[SerializeField] float waterMax;
[Header("Tiles")]
[SerializeField] GameObject clay = null;
[SerializeField] GameObject dirt = null;
[SerializeField] GameObject gravel = null;
[SerializeField] GameObject sand = null;
[SerializeField] GameObject rock = null;
[SerializeField] GameObject water = null;
float tileXOffset = .5f;
float tileYOffset = 0.375f;
List<GameObject> tempTileList = new List<GameObject>();
void Awake()
{
//StartCoroutine(GenerateMap());
}
void Start()
{
offsetX = Random.Range(0f, 99999f);
offsetY = Random.Range(0f, 99999f);
GeneratePerlinTiles();
GenerateLooseTiles();
}
Color CalculateColor(int x, int y)
{
float xCoordinate = (float)x / width * scale + offsetX;
float yCoordinate = (float)y / height * scale + offsetY;
float sample = Mathf.PerlinNoise(xCoordinate, yCoordinate);
return new Color(sample, sample, sample);
}
private int GetNumber(int percentageOf, int wholeNumber)
{
int number = (wholeNumber / 100) * percentageOf;
return number;
}
private void GenerateList(GameObject tileToUse, int percentageOf, int wholeNumber)
{
int tempPercent = GetNumber(percentageOf, wholeNumber);
for (int x = 0; x < tempPercent; x++)
{
tempTileList.Add(tileToUse);
}
}
private void GenerateLooseTiles()
{
int numberOfTiles = mapWidth * mapHeight;
GenerateList(dirt, dirtPercentage, numberOfTiles);
GenerateList(sand, sandPercentage, numberOfTiles);
GenerateList(gravel, gravelPercentage, numberOfTiles);
for (int x = 0; x < mapWidth; x++)
{
for (int y = 0; y < mapHeight; y++)
{
GameObject tempTile = tempTileList[Random.Range(0, tempTileList.Count)];
if (y % 2 == 0)
{
if (tempTile.tag == "Dirt")
{
Instantiate(tempTile, new Vector3(x * tileXOffset + Random.Range(-0.3f, 0.3f), y * tileYOffset + Random.Range(-0.3f, 0.3f), 2), Quaternion.identity);
tempTileList.Remove(tempTile);
}
else if (tempTile.tag == "Sand" || tempTile.tag == "Gravel")
{
Instantiate(tempTile, new Vector3(x * tileXOffset + Random.Range(-0.3f, 0.3f), y * tileYOffset + Random.Range(-0.3f, 0.3f), 3), Quaternion.identity);
tempTileList.Remove(tempTile);
}
else
{
Instantiate(tempTile, new Vector3(x * tileXOffset + Random.Range(-0.3f, 0.3f), y * tileYOffset + Random.Range(-0.3f, 0.3f), 4), Quaternion.identity);
tempTileList.Remove(tempTile);
}
}
else
{
if (tempTile.tag == "Dirt")
{
Instantiate(tempTile, new Vector3(x * tileXOffset + (tileXOffset / 2) + Random.Range(-0.3f, 0.3f), y * tileYOffset + Random.Range(-0.3f, 0.3f), 2), Quaternion.identity);
tempTileList.Remove(tempTile);
}
else if (tempTile.tag == "Sand" || tempTile.tag == "Gravel")
{
Instantiate(tempTile, new Vector3(x * tileXOffset + (tileXOffset / 2) + Random.Range(-0.3f, 0.3f), y * tileYOffset + Random.Range(-0.3f, 0.3f), 3), Quaternion.identity);
tempTileList.Remove(tempTile);
}
else
{
Instantiate(tempTile, new Vector3(x * tileXOffset + (tileXOffset / 2) + Random.Range(-0.3f, 0.3f), y * tileYOffset + Random.Range(-0.3f, 0.3f), 4), Quaternion.identity);
tempTileList.Remove(tempTile);
}
}
}
}
}
private void GeneratePerlinTiles()
{
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
Color color = CalculateColor(x, y);
if (y % 2 == 0)
{
if (color.r >= clayMin && color.r < clayMax)
{
Instantiate(clay, new Vector3(x * tileXOffset + Random.Range(-0.3f, 0.3f), y * tileYOffset + Random.Range(-0.3f, 0.3f), 1), Quaternion.identity);
}
}
else
{
if (color.r >= clayMin && color.r < clayMax)
{
Instantiate(clay, new Vector3(x * tileXOffset + (tileXOffset / 2) + Random.Range(-0.3f, 0.3f), y * tileYOffset + Random.Range(-0.3f, 0.3f), 1), Quaternion.identity);
}
}
}
}
}
}