How can I set the draw order for an individual button so it is on top of everything else in the drawing order?
Here is what I’m trying to do. I have a Canvas UI where a portion of the screen has a VerticalLayoutGroup of buttons. I want to dim the entire screen and then put the button in front of the dimmer so it will be highlighted to the user. So I created an Image that is black and use CanvasGroup to adjust the alpha and I checked Blocked Raycasts because I don’t want anything else clickable. This dimmer image is directly under Canvas and at the bottom of the list in the hierarchy so it’s in front of everything. Now I just want one of the buttons in the layout group to be in front of the dimmer so they can still click on the button. (See attached image)
I can’t change the hierarchy of the button and move it into an object lower in the hierarchy list than the dimmer object. The problem is if I move the button out of the layout group, then the group will rearrange itself and the layout won’t be the same. I don’t want to move all the buttons in the layout group in front because then they will all be highlighted instead of just the one I want to highlight.
I watched the sorting layer video and it sounds like this is what sorting layers are for, but I can’t figure out how to change the sorting layer for a single button and not the entire canvas.
So alpha is inherited down the chain. The best thing to do would be to duplicate the button and link it’s location to the same place as original button.
Wow, that seems a bit hacky to me to have two copies of the same button to work around the problem. What if it were a complicated widget like a HUD that was more expensive and has alpha or other consequences of having a second copy? It seems that the fundamental problem is that draw order is tightly coupled to the hierarchy and so is layout so transitively draw order is tightly coupled to layout. It would be nice if there was a way to override the draw order for each ui component like with sorting layers and also have the event system pay attention to sorting layers when dispatching events too so you can click on the button in addition to having it be on top.
Thanks,
David
I too have looked into this issue using the ugui, however there doesn’t seem to be a non hacky way of doing so. I would recommend that you do not dim your whole button container. I would tell you to just dim the other buttons that are in that container.
When we were working on our game, H2FLOW, we faced a similar issue (using NGUI). In the end we opted to “disable” the button’s ability to receive ray casts as well as reduced its alpha to 50%.
On “usable” buttons, where the user clicks on the button to initiate the action and then has to click on the playing field we added an extra sprite on top of it and that was a radial filled sprite that we tweened the value. We also “disabled” all other buttons that should not be active at the time.
The button that is active (has inventory or hasn’t been “used”) stand out versus their counterparts which have a value of 0.
You can kind of see it in this screenshot below, the bricks with a value of 0 are “disabled” and just having used a “usable” ability it is now disabled and counting down.
@Haptix, A nice idea, but I think the use case is slightly different. I will be doing that sort of disabled state too. For some of my skills, the user needs to click on a certain area of the screen after clicking on the skill button and I also want to highlight that area and dim the rest to really push the point that it’s waiting for them to do something.
Nice graphics by the way. Do you do them yourself? Or do you have a dedicated artist? Or did you contract out the art?
In case anyone comes across this post, my solution for now was to not use VerticalLayoutGroup at all and manually layout the items. Then reparent it to a RectTransform that sits in front of the dimmer element so it will highlight just the one button. If VerticalLayoutGroup had a way to disable it’s layout abilities, I could turn that off temporarily (enabled = false doesn’t turn it off)
Coming in a later beta you should be able to add a canvas to the object and change the sorting order for that one object (and its children). It would break the batch (as a new canvas is a new batch) but it will do what you want while maintaining the ability to use the LayoutGroup.
I have also added a flag to the CanvasGroup for ‘Ignore parent Canvas Groups’. This would allow you to add this group to the button, then set it to ignore the parents. So you can fade out a whole bunch of element, then have one not fade out to remain highlighted.
Here’s what I did, since there is no GetParent method of the transform off of the gameobject, you will need to create a field and assign it to the parent gameobject. Get the child’s current localPosition, set it’s parent to what the value already is and that will move it forward and set the transform back to what you previously recorded.