- Home /
Detecting OnMouseDown when two objects are overlapping
I'll start off by noting that I am using unity 2d, and all of my GameObjects have sprite renderers. Let's say I have a grid, where each tile is an GameObject with a script (that has a onTileObject field). Let's say I also have some sprites, or characters, that can obviously stand on the tiles.
When someone presses on the tile/character, I'd like for the character's UI to show up, by calling a method in character's script. What's the best way to do it?
Having a script on every tile seems excessive. Probably shouldn't do that without a good reason. Ins$$anonymous$$d you should store your grid-based world's data in a 2-dimensional array of tiles and access them by their indexers. Then you can look up information about any tile cheaply, such as,
find where mouse clicked
translate into tile-space coordinates
get the tile at that x,y position
search for any actors on that tile
call whatever method is required on the found actor
Could you go more into detail about how I can achieve
1: find where mouse clicked
and
4: search for any actors on that tile.
I wouldn't know how to do it without a tile GameObject that has a polygon collider and a script with an On$$anonymous$$ouseDown() method.
I'd wager in just about any tile-based game, the map is created in such a way as to place tiles in a 2D array at some point, such as Tile[,] masterSet;
This is extremely advantageous, allowing you, the developer, to access your game world in an intuitive way. If your current method of world generation doesn't do this, it probably should. Guess you could get by without it.
Anyway, knowing where the mouse clicked is as easy as sampling the mouse position on your 2D plane. There's plenty of info around to learn that. The trick is actually step 2, where you round off the mouse position to correspond directly to your Tile[,] array. Then your mouse tile, if it exists, is,
Tile mouseTile = masterSet[rounded$$anonymous$$ouse.x, rounded$$anonymous$$ouse.y];
In a true old-school tile-based game, any given entity always belonged to one tile at a time. This made it very easy to create a two-way relationship between entities and tiles. So a Tile might have an Entity[] array to hold its entities, and an Entity might store its current tile in a Tile variable. This kind of relationship is also super useful, when it's possible and prudent.
Entity actor = mouseTile.FirstActorOnSelf();
if (actor) actor.Perform$$anonymous$$ethod();
I stored the tiles in a 2d array.
I had clickable towns and units, and wanted to select the unit if a unit and town shared tile, so I first checked the tile for a unit, if no unit was found it checked for a town.
So, I'm gonna use this chance to ask one more question. AlwaysSunny's solution involves creating a Tile class, which I'm guessing does not extend a monobehaviour. How big is the performance difference between classes that extend monobehaviours and classes that don't? Also, how big is the performance difference between attaching a script to a gameObject and not doing that? Should I be trying to avoid attaching scripts to gameObjects when possible as a rule of thumb?
Also, thank you for the answers, they are really helpful to me.
Your answer
![](https://koobas.hobune.stream/wayback/20220613182230im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Saving Grids in Grid System 1 Answer
Move Overlapbox/GameObject depending on Parent 2 Answers
Calling method once 2 Answers
Ground Plane when starting new project 2 Answers
Am I using too many Singletons? 2 Answers