- Home /
Grid obstacle detection
Hi all,
I am having a problem with obstacle detection on my grid. My grid size differs depending on the current level of the game. Currently my grid is instantiated piece by piece and placed inside a List. Attached to the grid pieces is this class:
public class gridtile : MonoBehaviour
{
// This class will be used so we can modify the isOccupied flag
// if the grid section is occupied, the cube cant move onto it
public bool isOccupied = false;
public bool haslightsOn = false;
public gridtile north;
public gridtile south;
public gridtile east;
public gridtile west;
}
Once the obstacles have spawned on a part of the grid the isOccupied flag changes from false to true. I am trying to figure out how to initialize the north, south etc pieces dependant on the current tile my player is on. I think this sort of looks like a linked list. My player object moves from grid piece to grid piece. The player class also has a data member called gridtile currentTile. I am not sure also how to "read ahead" in the list so that for example this code may work:
if (currentTile.north.isOccupied)
{
canMoveNorth = false;
}
Is this a rectangular grid? What order you instantiate the pieces?
I want to jump on the array-train too, but if you're doing huge irregular shapes this could be an interesting problem :)
I'm thinking something like Hashtables, but it seems horribly inefficient... Another approach could be attaching coordinates to the class then searching for them, but again, slooow.
But tbh all signs point to a 2D array. Is there a reason you're using a list over a 2D array?
Answer by Tarlius · Feb 26, 2013 at 05:20 PM
This should get you going. Note that you'll have to add null checks when checking if you can move, since the ones around the outside will not have adjacent tiles (you could wrap them though if you want?)
Block[] blocks = new Blocks[4,4];
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
blocks[i,j] = new Block();
}
}
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
if(i + 1 < 4) blocks[i,j].North = blocks[i +1,j];
if(i - 1 >= 0) blocks[i,j].South = blocks[i - 1,j];
if(j + 1 < 4) blocks[i,j].East = blocks[i,j + 1];
if(j - 1 >= 0) blocks[i,j].West = blocks[i,j - 1];
}
}
I'm a little disappointed we aren't making massive irregularly shaped continents with portals though :(
lol thanks for the code, I'll give it a whirl. Also a portal idea sounds amazing!! I may have to "integrate" that into my game :P
I assume this code is:
1). creation of the grid 2). Checking the next possible movement (north, south etc) is possible?
No, create the grid that assign all the references inside the class for North, South, East, West. So you can do: if (currentTile.north.isOccupied) { can$$anonymous$$oveNorth = false; }
Although as I mentioned, you'll need to check whether .north is null before you try .isOccupied
A couple of problems:
1). $$anonymous$$y gridtile class is derived from monobehaviour, so I cant create new from that. 2). I've supplied my code for your perusal, and maybe you can see where I can make the changes?
public class gridtile : $$anonymous$$onoBehaviour
{
// This class will be used so we can modify the isOccupied flag
// if the grid section is occupied, the cube cant move onto it
public bool isOccupied;
public bool haslightsOn;
public gridtile north;
public gridtile south;
public gridtile east;
public gridtile west;
void Start()
{
isOccupied = false;
haslightsOn = false;
}
}
And I have a separate class the builds the grid like so:
public class gridBuilder : $$anonymous$$onoBehaviour { public static List gridList; public static ArrayList lgtPos; public static short lightsOnCount; public Transform grid;
public static bool gridIsBuilt;
public static bool lightsAreOn;
// Use this for initialization
void Start()
{
gridList = new List();
lgtPos = new ArrayList();
gridIsBuilt = false;
lightsAreOn = false;
StartCoroutine(createSquareGridTimed());
}
IEnumerator createSquareGridTimed()
{
short all = 0;
// The values used in the loops will change depending on the level, so the grid is different
for (short i = 0; i < squareGridSize(level$$anonymous$$anager.level); i++)
{
for (short j = 0; j < squareGridSize(level$$anonymous$$anager.level); j++)
{
// Add each piece of the grid to the screen and animate it
GameObject g = Instantiate(grid.gameObject, new Vector3(i, 15, j), Quaternion.identity) as GameObject;
iTween.$$anonymous$$oveTo(g, new Vector3(i, 0, j), 0.8f);
// Add the gameobjects to the list, to be used by all other classes
gridList.Add(g);
all++;
yield return new WaitForSeconds(0.15f);
}
}
// Set the various variables needed for the other classes
gridList.TrimExcess();
yield return new WaitForSeconds(0.5f);
lightsOnCount = (short)gridList.Count;
gridIsBuilt = true;
StartCoroutine(toggleLightingTimed());
}
IEnumerator toggleLightingTimed()
{
// gridLighter must send the lights position to the data$$anonymous$$anager class
// it needs to be retrieved by the cubeCollider class
Debug.Log("toggleLighting() called");
Transform go;
for (short i=0; i < lightsOnCount; i++)
{
go = gridList[i].transform.FindChild("GridLight");
gridtile tile = gridList[i].gameObject.GetComponent<gridtile>();
if (null == go)
{
// Handle the error if the piece of the grid cant be found
Debug.Log("Light not found!");
yield break;
}
go.light.enabled = true;
go.light.audio.Play();
tile.haslightsOn = true;
lgtPos.Add(gridList[i].transform.position);
yield return new WaitForSeconds(0.05f);
}
lightsAreOn = true;
}
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
Grid Based Map Object-Array vs Arrays only 1 Answer
using char to extract integer numbers from a list - [UnityScript] 1 Answer
Is there a way to remove array entries in the editor? 4 Answers
An Array within array 2 Answers