I’m making the first thing i’ve ever done that’s somewhat similar to an RTS, in that there are units which you can select by clicking them, and give them orders.
Internally, i have this work by doing a raycast from the camera through the screen point clicked until it hits something, and i check if that something is a selectable unit based on the tag attached to it.
I’ve also implemented the other common RTS behaviour, in that left-clicking on a place which doesn’t contain a selectable unit (ie, a random patch of ground) causes you to deselect all currently selected things. This is working fairly well
Right now i’m getting more into UI design, and i’m running into a problem. The raycasting doesn’t seem to detect UI objects, and passes right through them obliviously. This usually results in a click being detected against empty ground, and thus in deselecting. This is bad
I want clicks on UI objects to be a special case, to be discarded or ignored by the selection code. I could probably do this easily if the raycast were to hit them, i could check the layer they’re on. All my UI objects are on a canvas and the UI layer.
Wrong forum, so I will move it. And, one way to do this is to put a layer UNDER your UI that has a special tag on it (like UI_BLOCKING_LAYER). Then, when you cast your ray, if it also hits this layer, you can throw it out. Another way would be to use Viewport like behaviors. And, I think there is probably a way to take the ray and cast it into the UI, checking to see if it hit anything in the Canvas (though, in honesty, I haven’t solved that yet).
Since i literally just started getting into UI systems,. i have no idea what is and isn’t legacy. But i’m using UI objects placed onto a canvas object. is that the new system?
I don’t have personal experience with this issue, but there’s a pinned FAQ thread in the Unity UI forum that includes this answer, which seems relevant:
There is an alternative method, which I prefer. That is to turn over all of the ray casting to the Event System, and let it deal with blocking automatically. This video I did a while back may be helpful. It describes multiple ways to block clicks on a UI element, choose the one that works for you.
Well i got antistone’s method working, and it seems to do well. However i notice ha one of my UI elements is blocking clicks that i don’t want to. This particular element is just text, with no background/panel/buton underneath. I may have a look at the other options in that video.
he approach of putting a script inside whatever i want o click seems messy to me, i don’t do that. For selecting units in my game, i have a centralised input script detect clicks, and it passes the message to another centralised selectionManager script which does the raycasting and detects whether or not a unit was hit.
Can either of the latter two methods be implemented into this setup?
what exactly are the advantages between all threee methods?
and is there any way to make UI elements selectively not-block clicks
Something’s not quite right when I have to sit through my own tutorial to remember what I was talking about.
If you want to use a centralised selection manager the two later methods will not work. The EventSystem is its own centralised selection manager. You could pull apart the event system and incorporate it into your selection script, the component is open source. But I’m not sure that’s the best thing in your case. The first method is probably the best if you already have a central input manager
Method 1: Simple to implement, but if you are using a lot of OnMouseXXX it can be a pain to maintain bool checks everywhere. Not a big deal for a centralised input manager.
Method 2: Simple to implement. Can be done entirely in the inspector. Forces all input to go through the EventSystem.
Method 3: Essentially identical to method 2, but in script instead of in the inspector. Gives the finest control over the input system. Also forces input to use the EventSystem
This is the easy part. Add a canvas group and manipulate the blocks raycast property.
Switching between None/Nothing and All/Everything doesn’t seem to have any effect on clicks, or on the return value of EventSystem.current.IsPointerOverGameObject()
This solution just randomly broke. I was poking around in the canvas looking for a certain type of components, i think added a few things, maybe removed something.
Now eventsystem.current is null, and the check for if its over a gameobject returns a null reference error.