- Home /
Controlling GameObject selection across Parent/Child
Hello all, this is my first question here on UnityAnswers so please bare with me.
Currently I have a GameObject named Board
The Board is comprised of a 20x20 Grid of "Tile" Game objects. Each tile has a C# script that highlights when it is moused over.
I would also like the tiles to be select-able, in that they maintain their highlight if they are clicked by mouse (Additional functionality will be added to this later such as Menu pop ups and building animations).
My problem is a pretty basic one but searching the site I haven't found a solution, possibly because I am misunderstanding the issue and searching incorrectly.
I do not want more than one "tile" GameObject to be selected at a time.
I.E. If I have tile A selected, and I click tile B, tile B should assume the active selection highlight and tile A should deselect.
I am not sure how to do this via C# script as this script I believe needs to be running on the Board GameObject since it's the parent object rather than the tiles as children, although I could very easily be wrong. Thank you for any references to where you came up with your answers in advance, and if I missed an answer that could have been found easily via search I do apologize as I did attempt to search before asking.
Answer by robertbu · Jun 11, 2013 at 09:01 PM
Without your source, it is difficult to advice a specific solution. The basic idea is to have all the block deselect themselves before processing the new click. There are a number of possible mechanisms for doing this deselection:
Since you are using C#, you can use events and delegates. Here is a tutorial[1]:
http://www.youtube.com/watch?v=N2zdwKIsXJs
You can use BroadcastMessage(). Note the script that calls this method does not have to be on the parent. You can do something like:
transform.parent.gameObject.BroadcastMessage();
Assuming a common parent for the tiles, you could walk the transform list:
foreach (Transform child in transform) {
child.gameObject.GetComponent< SomeScript >().Deselect();
}
If you are using Raycasting() (instead of OnMouseDown()) to do the selecting and all the tiles are tagged:
var argo = GameObject.FindObjectsWithTag("tile");
for (int i = 0; i < argo.Length; i++) {
argo[i].GetComponent< SomeScript >().Deselect();
}
And I'm sure there are other ways.
Thank you for the proposed solution @robertbu, I haven't started attempting to use Raycasting as I understand what it does but have never actually implemented it yet and am not 100% sure on how so I may experiment with that later tonight. I will attempt your other suggestions as well and report back with my results.
A question though as to your comment about walking the transform list. If we know which tile has been selected by a click would it not be more efficient to somehow store this tiles ID as the active tile and some how simply de-activate it when a new tile is selected rather than traversing a list/array of all possible tiles?
Thanks again!
If you are going to be using Raycasting() from the outside rather than using On$$anonymous$$ouseDown(), storing and using a selected state should work fine. In general I try to push information down as far as possible, and hide it as much as possible. Anything that I can put into the buttons/tiles I would.
I accepted your answer as I feel for many facing these types of issues this is a reasonable solution. I haven't gotten around to implementing it myself yet but I will report back when I do. @robertbu.
Your answer
Follow this Question
Related Questions
"Center On Children" programmatically 1 Answer
How can I listen for a function being called from a parent class? 1 Answer
Make a simple tree 1 Answer
Make object A parent of object b 1 Answer