- Home /
Tile-based Generation Not Working?
Ok, so I was testing some things for a project I am working on, and ran into a problem. I have created a script where, two seconds after the game starts, it will generate a map of basic little squares that I have stored as a prefab. Whenever I run the script, the game crashes. That's it, no errors, not even a single tile spawns. I have looked over it several times, but could not figure it out. Yes, it is a fairly primitive and simple way of handling this type of generation, but that is sort of the point. All help is appreciated.
Here is the script that actually does the generation:
public class Generator : MonoBehaviour {
public GameObject tile;
public bool done = false;
public int size = 10;
private GridCords origin = new GridCords(0, 0);
private GridCords current;
private GridCords last;
private List<GridCords> hist = new List<GridCords>();
private GridCords[] choices = new GridCords[4];
private GameObject newTile;
private bool first = true;
private int past = 0;
// Initialize stuff.
public void Start() {
current = origin;
last = origin;
choices[0] = new GridCords(last.GetX() + 1, last.GetY());
choices[1] = new GridCords(last.GetX() - 1, last.GetY());
choices[2] = new GridCords(last.GetX(), last.GetY() + 1);
choices[3] = new GridCords(last.GetX(), last.GetY() - 1);
}
public void Generate() {
if (size < 1) {
done = true;
return;
}
if (first) {
newTile = (GameObject)Instantiate(tile, origin.ToVect(), tile.transform.rotation);
hist.Add(origin);
last = origin;
} else {
// Wait a bit.
Wait(2.0f);
// Prepare for generation.
choices[0] = new GridCords(last.GetX() + 1, last.GetY());
choices[1] = new GridCords(last.GetX() - 1, last.GetY());
choices[2] = new GridCords(last.GetX(), last.GetY() + 1);
choices[3] = new GridCords(last.GetX(), last.GetY() - 1);
// Generate.
foreach (GridCords gc in choices) {
if (hist.Contains(gc)) {
past++;
}
}
if (past > 3) {
done = true;
return;
}
int i = 0;
while (hist.Contains(current)) {
current = choices[0];
i++;
}
newTile = (GameObject)Instantiate(tile, current.ToVect(), tile.transform.rotation);
// Post-generation.
hist.Add(current);
last = current;
size--;
past = 0;
}
}
private IEnumerator Wait(float secs) {
yield return new WaitForSeconds(secs);
}
}
Here is the GridCords class, which has the sole purpose of making my code a little more manageable:
public class GridCords : MonoBehaviour {
private int x, y;
public GridCords(int x, int y) {
this.x = x;
this.y = y;
}
// Creates world co-ordinates using the grid co-ordinates specified.
public Vector3 ToVect() {
return new Vector3(y * 10, 0, x * 10);
}
public int GetX() {
return x;
}
public int GetY() {
return y;
}
}
This should be all you need to figure it out. This is a completely separate project file, so the other things should have no effect on this.
Answer by maccabbe · Feb 25, 2015 at 08:37 PM
You never call Generate from either of these scripts so I can't tell exactly what is broken in your script but my guess it that you are calling Generate in a third script until size goes to 0. However since first is never set to false after creating a tile, size never goes down and the program is stuck in an infinite loop. Try using the following Generator :
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Generator : MonoBehaviour {
public GameObject tile;
public bool done=false;
public int size=10;
private GridCords origin=new GridCords(0, 0);
private GridCords current;
private GridCords last;
private List<GridCords> hist=new List<GridCords>();
private GridCords[] choices=new GridCords[4];
private GameObject newTile;
private bool first=true;
private int past=0;
// Initialize stuff.
public void Start() {
current=origin;
last=origin;
choices[0]=new GridCords(last.GetX()+1, last.GetY());
choices[1]=new GridCords(last.GetX()-1, last.GetY());
choices[2]=new GridCords(last.GetX(), last.GetY()+1);
choices[3]=new GridCords(last.GetX(), last.GetY()-1);
}
float time=0;
const float delay=0.5f;
public void Update() {
time=time+Time.deltaTime;
while(time>delay) {
Generate();
time=time-delay;
}
}
public void Generate() {
if(size<1) {
done=true;
return;
}
if(first) {
newTile=(GameObject)Instantiate(tile, origin.ToVect(), tile.transform.rotation);
hist.Add(origin);
last=origin;
size--;
first=false;
}
else {
// Prepare for generation.
choices[0]=new GridCords(last.GetX()+1, last.GetY());
choices[1]=new GridCords(last.GetX()-1, last.GetY());
choices[2]=new GridCords(last.GetX(), last.GetY()+1);
choices[3]=new GridCords(last.GetX(), last.GetY()-1);
// Generate.
foreach(GridCords gc in choices) {
if(hist.Contains(gc)) {
past++;
}
}
if(past>3) {
done=true;
return;
}
int i=0;
while(hist.Contains(current)) {
current=choices[0];
i++;
}
newTile=(GameObject)Instantiate(tile, current.ToVect(), tile.transform.rotation);
// Post-generation.
hist.Add(current);
last=current;
size--;
past=0;
}
}
}
Also GridCoords should not inherit from Monobehaviour. It does not override any methods from monobehaviour and is never attached to a gameObject.
using UnityEngine;
using System.Collections;
public class GridCords {
private int x, y;
public GridCords(int x, int y) {
this.x=x;
this.y=y;
}
// Creates world co-ordinates using the grid co-ordinates specified.
public Vector3 ToVect() {
return new Vector3(y*10, 0, x*10);
}
public int GetX() {
return x;
}
public int GetY() {
return y;
}
}
Oh, yeah. Thanks, I didn't actually set first to false... Thanks... again!