top of page
Writer's pictureCallum Pearce

RTS Unit Selection Improved

This post is an improvement and more detailed look into my unit selection. This is being created in a reponse to A.T to further explain how I did my unit selection and interation for Enemy Confederation (future projects that have any kind of unit selection was built of this one).


Below I will show different types of unit selection, and the code that matched it to create it. These selections include single unit, shift clicking, double clicking and drag box selection. All code below is only run once the player has released the left click button to ensure no rays are continuously being called.


Single Unit Selection

Single unit selection is the act of clicking on a unit and selecting just that unit. It works by raycasting from the camera to the mouse position into the world to see what object is under the mouse using a 'selectable' layer. This layer is attached to every game object that is to be selectable. If the object is selectable, a function is then called to select that object. The SelectObjects function checks for a lot of game specific conditions like teams, and if the object itself is a building or unit to highlight it correctly. But at its core it simply assigns the selected unit to the first element of a list. If no selectable object was found any selected unit will be deselected by clearing the list.


Shift Clicking Selection

Shift clicking selection is the act of adding units to the currently selected unit(s). It works by checking if the shift key is being held when a unit is selected. If it is, rather than deselecting, it will add the unit to the list.


Double Clicking Selection

Double clicking selection is the act of selecting all of the same type of unit on the screen. It works by nesting the single unit selection into an if statement that check if this is the first click within a small time frame. If it is, the single unit selection code is run and a first click variable is set to false. If the user clicks again within half a second it is counted as a double click and runs the else statement. Here it deselects all units and does another ray cast to screen. This time the object is stored, and compared to against a list that stores all other objects on screen. If the object has the same tag it adds that object to the selected objects list. Finally first clicks is reassigned to true stating the double click is over.

Drag Box Selection

Drag box selection is the act of creating a box with the mouse by clicking and dragging, then selecting all units within that box. Firstly to determine when the player is dragging, if they hold down the mouse button the click position is stored. If they then move the mouse far enough away, a dragging boolean is then set to true. A new check is then made to see if the player was dragging when they release the mouse. As the player can drag in any direction a bottom left and a top right corner had to be calculated.

With the orientation found, a temporary check can then be made to see if any objects are within these bounds in CheckAnyObjectsInsideBox(). This function goes into each unit in the objects on screen list, and checks whether it's screen position is within the bounds of the box created. As soon as one unit is a proper check is then made by checking two specific points (the base of the unit and the top). If at least one of these points are within the box, the unit is selected.


Additional Information

To improve performance all units make their own check to see whether they are on the screen or not. If they are, they are added to a master objectsOnScreen list that has been mentioned so far. This is done by calculating the units world to screen point at its base and top. If this is within the players screen space it is added to the list and set to on screen. If it isn't in screen space but still seen to be on screen it is removed from the list.

Final

All of these techniques put together allow a 'selectedObjects' list be put together. Whether there is one or more units in the list it allows commands to be issued. A very simple example of a command is when the player right clicks on terrain, it will loop through the selected objects list and issue a move command that will move the unit to the selected location. Complexity builds quickly when you have multiple units selected as you need to give positions for all units so that they do not go to the same location. This then moves into pathfinding, formations and much more.



117 views1 comment

Recent Posts

See All

1 comentário


foobar59403930393
07 de out. de 2020

Hi Callum! Thanks for getting back to me. Great post!


For single-unit selection, I presume you used IPointerClickHandler to attach the click-handling logic to each GameObject? Would you recommend this approach over having some monobehaviour manager class attached to an empty GameObject that checks if Input.GetButtonUp("Mouse 0") is true then sends a ray-cast? I realise that this is polling but it's not an expensive operation, and I'm avoiding code in each GameObject that would take up lots of RAM when I have hundreds of units in-game.


Also, I recently learned that we can ignore UI clicks by using the following:

using UnityEngine.EventSystems;

...

if(EventSystem.current.IsPointerOverGameObject() /*mouse over UI*/)

return;


Thanks,

A.T.

Curtir
bottom of page