- Home /
How can I find adjacent 2D tiles without using colliders?
Everything I find on this tells me to use OverlapCircle
, however I cannot as my colliders cover multiple tiles. I also cannot check for a collider as I need to access information on the specific tile at that location, and since the collider is not specific to that (or any) tile, this fails.
I've tried storing the information about the tile that I need outside the tile itself, however I've not managed to access the information based on Vector2 coordinates as the map position frequently changes making this difficult. I also want to avoid iterating through the list as this script is going to be run very frequently making performance important.
EDIT: Found a solution, posted below.
You may have to bite the bullet and add colliders to the tiles. Some Overlap casts check for bounding boxes (But still require colliders).
I think you were on the right track when considering using the position to index into your tile array. I'm not clear on exactly what changes map position frequently, but, if all your tiles are children of a single object, then a single Vector subtraction should yield the offset you need: (test position- parent position)= tile offset position. With this method, you will probably need to scale by the tile size to get the correct offset. Are all tiles fixed in size and shape?
@Glurth Didn't think of parenting them, so that will make things a little easier. Tiles are all identically shaped and sized - this wasn't a problem. I was mostly having problems allocating and maintaining space in the lists, and I kept getting Index Out-of-Range errors when trying to put the tiles in their own spaces. I'll try some more and post my code if I keep getting errors.
Answer by LukeZaz · Mar 22, 2015 at 04:39 PM
A bit inefficient, but I've come up with a solution.
In short, I've decided to store the Vector2 positions of my tiles in their names, and use GameObject.Find
to retrieve them. Despite my worries about said method being performance intensive, testing thus far shows no meaningful impact.
More details:
Setting the name in Awake, since the function that looks for tiles is usually called almost immediately after creation
void Awake ()
{
gameObject.Name = (Convert.ToInt32 (transform.position.x) + "," + (Convert.ToInt32 (transform.position.y));
}
Looking for neighboring tiles
// X and Y are variables for this tiles position
GameObject yup = GameObject.Find ((x) + "," + (y + 1));
GameObject xright = GameObject.Find ((x + 1) + "," + (y));
GameObject ydown = GameObject.Find ((x) + "," + (y - 1));
GameObject xleft = GameObject.Find ((x - 1) + "," + (y));
And finally, check if tiles were found
if (yup != null)
{
// there is a tile above, do stuff
}
Answer by ekeldevious · Mar 03, 2015 at 01:17 AM
why not do a data monobehaviour class for the tiles and a static controller, giving tiles an index property and use a 2 dimensional array in the controller to access them, this is very efficient and flexible tracking system. You will need to make an add and subtract tile function for the controller. this system requires a lot of work to make but is very efficient
public class tile : monobehaviour {
public vector2 index ={x,y}
}
public static class controller {
public tile[,]tiles = new tile[maxX,maxY]();
findTileRight(vector2 index) {
return tiles [index.x + 1 , index.y ];
}
}
I considered this. Unfortunately the tiles are created and destroyed depending on player position and I haven't come up with a way to put them in a list (and extend and shorten said list) properly so that their indexes remain correct.
I may have found a solution however - I'm planning to finish the system it is part of to make it work before I post it. Thanks for contributing!
Answer by toddisarockstar · Mar 03, 2015 at 02:43 AM
i seen your post and i also have a block movement project i am working on, so i thought id let you know what my final arrangement was. first of all, I have tested levels with over 5 thousand blocks with box coliders and doesent show any noticable different in preformance. i even tested the build on a machine with a slower dual core processer. attaching scripts to blocks is a huge NO! but simple colliders does NOT slow the camera/game. if your only problem is your colliders being the wrong size you can simply create a child object with its own collider and its own script to get you secondary info from a smaller secondary collider. this way you can detect different distance collitions from the same object.
there might be other opinions out there but my soulution to storing info about a block on a very large level was simple strings. raycasting and spherecasting wait for returns from the unity game engine, which everyone here knows will slow a game when called every frame.
storing unity GameObject referenses in a large array stores all kinds of info by default such as names, components and many numbers after location decimal points that are completely worthless to my block based game. and are not even possible to send rpc call for muiltiplayer cause its too much bandwidth.
with unitys standard way of storing info my game and level size was not even possible. now my "outside of the box" threory has got my game running super smooth...
packing things into strings on a need to know basis.
its super fast for a pc to read a large string. let me know if you need more info.
Colliders weren't my issue. $$anonymous$$y issue with them was that I had a script I'd made that automatically created and sized colliders according to what was needed, so that there was the $$anonymous$$imum possible in addition to fixing issues with getting stuck on tiles.
Anyway, as I said above in a comment, I may have found a solution but am holding off answering this to make sure it works.