Hello, I am making simple 2D game, something like endless runner(using C#). To make it I am using cube(tile) for random generated path(infinity). Tile have 3 attach(left,right,top) point, so they will spawn to correct place, those attach point is empty game object that is childed to Tile. Using 3 differend prefabs: TopTile, LeftTile, RightTile all of them have same attach points.
Tile Manager script
public class TileManager : MonoBehaviour {
public GameObject currentTile;
public GameObject[] tilePrefabs;
private static TileManager instance;
private Stack<GameObject> leftTiles = new Stack<GameObject>();
public Stack<GameObject> LeftTiles
{
get { return leftTiles; }
set { leftTiles = value; }
}
private Stack<GameObject> topTiles = new Stack<GameObject>();
public Stack<GameObject> TopTiles
{
get { return topTiles; }
set { topTiles = value; }
}
private Stack<GameObject> rightTiles = new Stack<GameObject>();
public Stack<GameObject> RightTiles
{
get { return rightTiles; }
set { rightTiles = value; }
}
public static TileManager Instance
{
get
{
if (instance == null)
{
instance = GameObject.FindObjectOfType<TileManager>();
}
return instance;
}
}
// Use this for initialization
void Start () {
CreateTiles(150);
GameEventManager.GameStart += GameStart;
GameEventManager.GameOver += GameOver;
for (int i = 0; i < 75; i++)
{
SpawnTile();
}
}
public void CreateTiles(int amount)
{
//creating new tiles for random generated path (using stacks)
for (int i = 0; i < amount; i++)
{
leftTiles.Push(Instantiate(tilePrefabs[0]));
topTiles.Push(Instantiate(tilePrefabs[1]));
rightTiles.Push(Instantiate(tilePrefabs[2]));
leftTiles.Peek().SetActive(false);
topTiles.Peek().SetActive(false);
rightTiles.Peek().SetActive(false);
leftTiles.Peek().name = "LeftTile";
topTiles.Peek().name = "TopTile";
rightTiles.Peek().name = "RightTile";
}
}
/// <summary>
/// need make condition that tile from current position can spawn only in 2 direction
/// example, if currect position is LeftTile, then next tile will be left or top
/// if right, then right or top
/// if top, only then next tile can be right, left or top
/// </summary>
public void SpawnTile()
{
//generate random number 0-2
int randomIndex = Random.Range(0, 3);
//condition for checking if there is tiles for path
if (leftTiles.Count == 0 || topTiles.Count == 0 || rightTiles.Count == 0)
{
CreateTiles(100);
}
//swamping tiles
if (randomIndex == 0)
{
GameObject temp = leftTiles.Pop();
temp.SetActive(true);
temp.transform.position = currentTile.transform.GetChild(0).transform.GetChild(randomIndex).position;
currentTile = temp;
}
else if (randomIndex == 1)
{
GameObject temp = topTiles.Pop();
temp.SetActive(true);
temp.transform.position = currentTile.transform.GetChild(0).transform.GetChild(randomIndex).position;
currentTile = temp;
}
else if(randomIndex == 2)
{
GameObject temp = rightTiles.Pop();
temp.SetActive(true);
temp.transform.position = currentTile.transform.GetChild(0).transform.GetChild(randomIndex).position;
currentTile = temp;
}
else
{
Debug.LogError("Don't have that tile");
}
}
}
Tile script
public class Tile : MonoBehaviour {
private float fallDelay = 1.5f;
void OnTriggerEnter(Collider collider)
{
//condition for tile falldown and spawning next amount of tiles(path) when player enter tile
if (collider.tag == "Player")
{
Debug.Log("Spawn next tile");
TileManager.Instance.SpawnTile();
StartCoroutine(FallDown());
}
}
IEnumerator FallDown()
{
//wait few seconds for doing operation in line below
yield return new WaitForSeconds(fallDelay);
GetComponent<Rigidbody>().isKinematic = false;
yield return new WaitForSeconds(fallDelay + 0.5f);
//"case of" condition for deciding which tiles push in correct stack, disable it and set rigidbody isKinematic to true
switch (gameObject.name)
{
case "LeftTile":
TileManager.Instance.LeftTiles.Push(gameObject);
gameObject.GetComponent<Rigidbody>().isKinematic = true;
gameObject.SetActive(false);
break;
case "TopTile":
TileManager.Instance.TopTiles.Push(gameObject);
gameObject.GetComponent<Rigidbody>().isKinematic = true;
gameObject.SetActive(false);
break;
case "RightTile":
TileManager.Instance.RightTiles.Push(gameObject);
gameObject.GetComponent<Rigidbody>().isKinematic = true;
gameObject.SetActive(false);
break;
default:
break;
}
}
}
With this code i get randomly spawned tiles, but not something I needed. What i get with this code.
What i wanted to get, but not sure how to implement it.
So far I noticed that i need some condition in function SpawnTIles, but can’t figure out how to make it. I want that if there is spawning tiles to left side(for example), then right tiles wont be spawning or something like that. Hope you will help me.
P.S. Sorry for not smart comments in code, I made them to not forget what that code lines do(for myself).