- Home /
RTS rectangle selection system
I'm trying to make a small RTS-like system where you can select your units and move them around. I was just wondering what the best/easiest method to make a classic rectangle massive selection system? (All it need to do is turn a boolean on the units called 'selected' to true)
-Thanks :)
Answer by Bunny83 · Jul 21, 2012 at 12:16 PM
It depends on the "style" you want. One way is, when your objects are located in a plane, to use a trigger and colliders on each unit. This could be a bit buggy but you would have a 3D volume in the scene, in other words a true 3d selection area.
The other (and probably better) way is to keep a list of all selectable units (in some kind of gamemanager) and just transform the positions of all units into screenspace. There you can simply use Rect.Contains to test if a unit is inside a rectangle.
edit
I didn't downvote your question, but i guess someone did because it has been asked several times before:
http://answers.unity3d.com/questions/31693/view.html
http://answers.unity3d.com/questions/33901/view.html
http://answers.unity3d.com/questions/168680/view.html
omg. I never thought of the second option :O ... Thanks man. I'm gonna try that out :)
(if it works, i'll accept your answer :) )
Answer by Sharpytwo · Jul 21, 2012 at 01:23 PM
well, this isnt really the whole answer, as i do not have it :P
but something that might help you though, is this:
function Update () { var unitPos : Vector3 = Camera.main.WorldToViewportPoint (transform.position); //Debug.Log ("Unit is located at: X:"+ unitPos[0] + "Y:"+ unitPos[1]);
}
attach this to the unit being selected.
it reports the unit position on camera. so if you are able draw a rectangle and calculate if this position is within that rectangle, you are pretty much there. hope this helped somewhat, still working on the same problem myself :-) edit: i see that several people answered just about the same thing before me, but that didnt show when i posted, sorry. :)
Answer by mustafa · Jul 21, 2012 at 01:23 PM
I did this before in C#, this is how I did it if it helps:
if(Input.GetMouseButtonDown(0)) { downMousePosition = Input.mousePosition; } else if(Input.GetMouseButtonUp(0)) {
RaycastHit hit1;
Physics.Raycast(Camera.main.ScreenPointToRay(downMousePosition), out hit1);
Vector3 v1 = hit1.point;
RaycastHit hit2;
Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit2);
Vector3 v2 = hit2.point;
Unit[] allUnits = GetAllUnits();
foreach(Unit unit in allUnits) {
Vector3 pos = unit.transform.position;
//is inside the box
if(Mathf.Max(v1.x, v2.x) >= pos.x && Mathf.Min(v1.x, v2.x) <= pos.x
&& Mathf.Max(v1.z, v2.z) >= pos.z && Mathf.Min(v1.z, v2.z) <= pos.z) {
//selecte the unit
Selecte(unit);
}
}
}
I recommend using a for ins$$anonymous$$d of a foreach for performance reasons...
Since "allUnits" is an array you won't see any preformance differences between for and foreach since it would be implemented as for loop.
Also the for loop is only executed once when you release the mouse button. So this isn't something where preformance plays any role