Hello I’m trying to create a fire emblem-esque movement system. It works more or less finally, but there’s a severe problem. I’m working on creating the tiles that show where you can move. Basically I have an array of the entire map that controls which spots are moveable and which aren’t. Coroutines fire off the tile creation functions, which take a tile and query spots next to it to see if those spots are available to plunk down a tile on. I think this system will be great because once it’s done each tile can have a ‘breadcrumb’ list that the unit can access to get to that tile, instead of needing some big old pathfinding thing.
So here’s the problem. Each grid block has a ‘tilePresent’ variable, which is changed whether a tile is on there or not. This stops tiles from being created on top of other tiles and eating up tons of memory. But it’s not working! I cllick the unit and tiles upon tiles upon tiles… I mean it technically is functional but I worry that once it gets to 10 move spaces that would create so many tiles that it would just rip the RAM to shreds.
Here’s my code, see any problems? Also if anybody wants to see the entire game I’m sure I could put it on Github or whatever.
I’m not the most experienced coder either, so if I did something in there that’s stupid please tell me.
(Excuse the messiness, I really need to do some clean-up work):
UnitController
using UnityEngine;
using System.Collections;
public class UnitStats : MonoBehaviour {
//All Unit Stats
public int attack = 1;
public int defense = 1;
public int luck = 1;
public int skill = 1;
public int speed = 1;
public int magic = 1;
public int resistance = 1;
public int move = 7;
public int posX = 1;
public int posZ = 1;
public Transform blueTile;
public GameObject gControl ;
//public bool isFinished;
IEnumerator OnMouseDown()
{
gControl = GameObject.FindGameObjectWithTag ("GameController");
GameControllerBase controlCode = (GameControllerBase)gControl.GetComponent (typeof(GameControllerBase));
//KILLS ALL PREVIOUS TILES
GameObject[] tilesDoomed = GameObject.FindGameObjectsWithTag("Tile");
for (int count = 0; count < tilesDoomed.Length; count++)
{
Destroy(tilesDoomed[count]);
Debug.Log("Tile Destroyed");
}
for (int count = 0; count <= (controlCode.LevelRows - 1); count++)
{
for(int newCount = 0; newCount <= (controlCode.LevelColumns - 1); newCount++)
{
controlCode.levelMap[count, newCount].tileHereChange(false);
}
}
TileCreation controlCreation = (TileCreation)gControl.GetComponent (typeof(TileCreation));
Debug.Log ("Unit Clicked");
yield return StartCoroutine (controlCreation.BeginCreation(posX, posZ, move));
}
/*
IEnumerator TileCreate(int tileNum)
{
gControl = GameObject.FindGameObjectWithTag ("GameController");
GameControllerBase controlCode = (GameControllerBase)gControl.GetComponent (typeof(GameControllerBase));
Quaternion blankQ = new Quaternion (0f, 0f, 0f, 0f);
Vector3 tilePos = new Vector3 (transform.position.x, transform.position.y, transform.position.z);
tilePos.y -= 0.5f;
Transform t = Instantiate (blueTile, tilePos, blankQ) as Transform;
GameObject firstTile = t.gameObject;
Debug.Log ("First Tile Created.");
TileBehavior behave = (TileBehavior)firstTile.GetComponent (typeof(TileBehavior));
behave.IsVisible = false;
MeshRenderer renderer = (MeshRenderer)behave.GetComponent (typeof(MeshRenderer));
renderer.enabled = false;
//behave.tileNum = (tileNum - 1);
behave.tilePos.x = (transform.position.x);
behave.tilePos.y = (transform.position.y);
behave.tilePos.z = (transform.position.z);
behave.mapX = posX;
behave.mapZ = posZ;
controlCode.levelMap [posX, posZ].tileHereChange (true);
/*
yield return StartCoroutine(tileCreationController (t));
//isFinished = true;
}
IEnumerator tileCreationController(Transform tile){
GameObject firstTile = tile.gameObject;
TileBehavior behave = (TileBehavior)firstTile.GetComponent (typeof(TileBehavior));
int tileNumControl = (behave.tileNum + 1);
yield return behave.makeMore ();
tileNumControl--;
for (int outCount = tileNumControl; outCount > 0; outCount--){
GameObject[] availableTiles = GameObject.FindGameObjectsWithTag("Tile") ;
TileBehavior[] tilesBehave = new TileBehavior[availableTiles.Length];
//ArrayList.
// tilesBehave = (TileBehavior)availableTiles[].GetComponents (typeof(TileBehavior));
//foreach (TilesBehavior availableTiles in tilesBehave)
for (int count = 0; count < availableTiles.Length; count++)
{
tilesBehave[count] = (TileBehavior)availableTiles[count].GetComponent (typeof(TileBehavior));
};
for (int count = 0; count < availableTiles.Length; count++)
{
yield return tilesBehave[count].makeMore();
}
}
}
yield break;*/
}
map construction
public class mapTiles
{
private bool clear;
private float height;
//private int defBonus;
private string terType;
private bool isPassable;
private bool tilePresent;
//ConstructorSafeAttribute Blank
public mapTiles()
{
clear = true;
height = 0;
//defBonus = 0;
terType = "Plains";
isPassable = true;
tilePresent = false;
}
public void newHeight(float newHeight)
{
height = newHeight;
}
public void changeClear(bool isClearIn)
{
clear = isClearIn;
isPassable = isClearIn;
}
public void changeType(string newType)
{
terType = newType;
}
public float heightPlease(){
return height;
}
public bool clearPlease(){
return clear;
}
public void changePassable(bool isPass)
{
isPassable = isPass;
}
public bool passPlease(){
return isPassable;
}
public void tileHereChange(bool tile){
tilePresent = tile;
}
public bool tilePlease()
{
return tilePresent;
}
}
}
TileCreation
public class TileCreation : MonoBehaviour {
public GameObject gControl;
public Transform blueTile;
public IEnumerator BeginCreation(int posX, int posZ, int tileNum){
gControl = GameObject.FindGameObjectWithTag ("GameController");
GameControllerBase controlCode = (GameControllerBase)gControl.GetComponent (typeof(GameControllerBase));
Quaternion blankQ = new Quaternion (0f, 0f, 0f, 0f);
Vector3 tilePos = new Vector3 (transform.position.x, transform.position.y, transform.position.z);
tilePos.y -= 0.5f;
Transform t = Instantiate (blueTile, tilePos, blankQ) as Transform;
GameObject firstTile = t.gameObject;
Debug.Log ("First Tile Created.");
TileBehavior behave = (TileBehavior)firstTile.GetComponent (typeof(TileBehavior));
behave.IsVisible = false;
MeshRenderer renderer = (MeshRenderer)behave.GetComponent (typeof(MeshRenderer));
renderer.enabled = false;
//behave.tileNum = (tileNum - 1);
behave.tilePos.x = (transform.position.x);
behave.tilePos.y = (transform.position.y);
behave.tilePos.z = (transform.position.z);
behave.mapX = posX;
behave.mapZ = posZ;
behave.tileNum = tileNum;
controlCode.levelMap [posX, posZ].tileHereChange (true);
yield return StartCoroutine(tileCreationController (t));
//isFinished = true;
}
IEnumerator tileCreationController(Transform tile){
GameObject firstTile = tile.gameObject;
TileBehavior behave = (TileBehavior)firstTile.GetComponent (typeof(TileBehavior));
int tileNumControl = (behave.tileNum + 1);
yield return behave.makeMore (behave.mapX, behave.mapZ);
tileNumControl--;
for (int outCount = tileNumControl; outCount > 0; outCount--){
GameObject[] availableTiles = GameObject.FindGameObjectsWithTag("Tile") ;
TileBehavior[] tilesBehave = new TileBehavior[availableTiles.Length];
for (int count = 0; count < availableTiles.Length; count++)
{
tilesBehave[count] = (TileBehavior)availableTiles[count].GetComponent (typeof(TileBehavior));
}
for (int count = 0; count < availableTiles.Length; count++)
{
yield return tilesBehave[count].makeMore(tilesBehave[count].mapX, tilesBehave[count].mapZ);
}
}
yield break;
}
}
public float whatIsHeight(int x, int z){
return levelMap[x, z].heightPlease();
}
}
TileBehavior
using UnityEngine;
using System.Collections;
public class TileBehavior : MonoBehaviour {
public bool IsVisible;
public int tileNum;
public Vector3 tilePos;
public int mapX;
public int mapZ;
public Transform blueTile;
public GameObject gControl ;
Quaternion blankQ = new Quaternion (0f, 0f, 0f, 0f);
void tileMakerInside(int mapX, int mapZ, int tileNum)
{
gControl = GameObject.FindGameObjectWithTag ("GameController");
GameControllerBase controlCode = (GameControllerBase)gControl.GetComponent (typeof(GameControllerBase));
float newPositionX = gControl.transform.position.x + mapX - 0.5f;
float newPositionZ = gControl.transform.position.z + mapZ - 0.5f;
float newPositionY = gControl.transform.position.y + controlCode.whatIsHeight(mapX, mapZ);
Vector3 tilePosNew = new Vector3(newPositionX, newPositionY, newPositionZ);
Transform t = Instantiate (blueTile, tilePosNew, blankQ) as Transform;
GameObject firstTile = t.gameObject;
TileBehavior behave = (TileBehavior)firstTile.GetComponent (typeof(TileBehavior));
if (!controlCode.levelMap [mapX, mapZ].passPlease ()) {
MeshRenderer renderer = (MeshRenderer)behave.GetComponent (typeof(MeshRenderer));
renderer.enabled = false;
behave.IsVisible = false;
} else {
MeshRenderer renderer = (MeshRenderer)behave.GetComponent (typeof(MeshRenderer));
renderer.enabled = true;
behave.IsVisible = true;
}
behave.tileNum = (tileNum - 1);
behave.mapX = mapX;
behave.mapZ = mapZ;
controlCode.levelMap [mapX, mapZ].tileHereChange (true);
Debug.Log ("Tile Created.");
}
public object makeMore(int mapX, int mapZ)
{
Debug.Log ("Making More...");
gControl = GameObject.FindGameObjectWithTag ("GameController");
GameControllerBase controlCode = (GameControllerBase)gControl.GetComponent (typeof(GameControllerBase));
if (tileNum > 0)
{
//Creates a tile up 1.
if (mapZ > 1)
{
if (!(controlCode.levelMap[mapX, (mapZ - 1)].tilePlease())){
tileMakerInside((mapX), (mapZ - 1), tileNum);
}
}
else
{
Debug.Log ("Up Tile Canceled.");
}
//Creates a tile Left 1.
if (mapX > 1)
{
if (!(controlCode.levelMap[mapX, (mapZ - 1)].tilePlease())){
tileMakerInside((mapX - 1), mapZ, tileNum);
}
}
else
{
Debug.Log ("Left Tile Canceled.");
}
//Creates a tile down 1.
if (mapZ < 10)
{
if (!(controlCode.levelMap[mapX, (mapZ + 1)].tilePlease())){
tileMakerInside((mapX), (mapZ + 1), tileNum);
}
}
else
{
Debug.Log ("Down Tile Canceled.");
}
//Creates a tile right 1.
if (mapX < 10)
{
if (!(controlCode.levelMap[(mapX + 1), mapZ].tilePlease()))
{
tileMakerInside((mapX + 1), mapZ, tileNum);
}
}
else
{
Debug.Log ("Right Tile Canceled.");
}
}
return null;
}
}
GameController
using UnityEngine;
using System.Collections.Generic;
using System;
public class GameControllerBase : MonoBehaviour
{
//Size of Level
public static int LevelRows = 10;
public static int LevelColumns = 10;
public LevelMapper.mapTiles[,] levelMap = new LevelMapper.mapTiles[LevelRows, LevelColumns];
// Use this for initialization
void Start ()
{
//GameObject controlPoint = GameObject.FindGameObjectWithTag ("Origin");
//This section creates the tile array.
for (int count = 0; count <= (LevelRows - 1); count++)
{
for(int newCount = 0; newCount <= (LevelColumns - 1); newCount++)
{
levelMap[count, newCount] = new LevelMapper.mapTiles();
}
}
Debug.Log ("Array Finished");
//This Section Assigns values to the array.
//THIS SECTION SHOULD BE CHANGED FOR EACH LEVEL
//--------------------------------------------------------
//First the Heights
levelMap [4, 4].newHeight(1);
levelMap [5, 4].newHeight(1);
levelMap [4, 5].newHeight(1);
//Next Obstacles Also changes if passable or not.
levelMap [5, 5].changeClear (false);
//next Types.
levelMap [5, 5].changeType ("Mountain");
//--------------------------------------------------------
Debug.Log ("Array Created successfully.");
//UnitStarter beginUnitPlacement = (UnitStarter)controlPoint.GetComponent (typeof(UnitStarter));
beginUnitPlacement();
}
private void beginUnitPlacement()
{
//GameObject controlPoint = GameObject.FindGameObjectWithTag ("GameController");
//Sorts the units into places.
GameObject[] units = GameObject.FindGameObjectsWithTag("Unit"); //returns GameObject[]
for (int count = 0; count < units.Length; count++)
{
Debug.Log("Unit Loaded");
UnitStats stats;
stats = units [count].GetComponent<UnitStats> ();
float newPositionX = transform.position.x + stats.posX;
float newPositionZ = transform.position.z + stats.posZ;
float newPositionY = transform.position.y;
float newHeight = whatIsHeight ((int)(stats.posX), (int)(stats.posZ));
Vector3 startPos = new Vector3 ((newPositionX - 0.5f), (newHeight + 0.5f), (newPositionZ - 0.5f));
units[count].transform.position = startPos;
levelMap[((int)(stats.posX - 1)), ((int)(stats.posZ - 1))].changePassable(false);
}
Debug.Log ("Units Placed");
}