Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How to do selection box ?

Discussion in 'Getting Started' started by narf03, Oct 7, 2016.

  1. narf03

    narf03

    Joined:
    Aug 11, 2014
    Posts:
    222
    like in starcraft 2, you want to select multiple units, you can drag and draw a box to select all units in the box. But starcraft in 2D, i want to do in 3D space, something like HomeWorld, i dont need codes, i just need ideas, you can rotates your camera anywhere while still allows to do the selection.
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,841
    I would draw the selection box in a Canvas associated with the camera. And then just highlight whatever units fall within the corresponding part of the screen.
     
  3. narf03

    narf03

    Joined:
    Aug 11, 2014
    Posts:
    222
    I think i can draw on the canvas, but how do i know if which units are in that box ? that box is on canvas and has no direct relation to the 3d space.
     
  4. Deleted User

    Deleted User

    Guest

    Last edited by a moderator: Oct 8, 2016
  5. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,841
    Yep, that's how you do it.
     
  6. narf03

    narf03

    Joined:
    Aug 11, 2014
    Posts:
    222
    that means if there are like 100 units on the 3d space, i need to perform the calculation for every single units to see if they are within the selection box ?
     
  7. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,841
    Yep. And you also need to quit worrying about it. :) 100 coordinate transformations and bounds checks is trivial compared to what routinely happens on every frame anyway (particularly when physics are involved). And you'll be doing this only during manual selection.

    There are certainly ways to optimize it if profiling later shows this to be a bottleneck. But I doubt it will ever show that.
     
  8. narf03

    narf03

    Joined:
    Aug 11, 2014
    Posts:
    222
    actually i will need to do that every frame, imagine when you are dragging the box, you need to highlight which units will be selected, not only upon mouse up. thats why i am worry if the calculation will be heavy.
     
  9. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,841
    Yes, that's why I said "during manual selection" (instead of "at the end of manual selection").

    Well please stop. :)
     
  10. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Don't worry. Just build it and see what happens. If it is to heavy, then come back and we can help optimize.
     
  11. narf03

    narf03

    Joined:
    Aug 11, 2014
    Posts:
    222
    Not doing anything yet, just planning and predicting problems or difficulties.
     
  12. Kalladystine

    Kalladystine

    Joined:
    Jan 12, 2015
    Posts:
    227
    That's a slippery slope that often leads to analysis paralysis (not saying that no analysis should be done, just don't overdo it).
    Since building proof of concept scenes in Unity is extremely easy, if you're worried about the performance, commit a couple of hours and build it up. In many cases you will end up with a code snippet that is actually functional enough for the prototype/first iterations.
    But the biggest boon of building a PoC like that, is that if it works, you can stop worrying about it - and that's very important. When designing complex systems crossing anything out of "need to keep in mind to figure out" is invaluable, as our minds tend to jump between unsolved things, creating distractions and leading to us jumping between things we work on (and, usually, multi-tasking developers tend to create sloppy, duct-tape solutions).
     
  13. blu3drag0n

    blu3drag0n

    Joined:
    Nov 9, 2018
    Posts:
    94
    This is an old post, but when I was looking for a solution to get a selection rectangle drawing in game mode, also in a build version, then there were not really satisfying answers. Most tried via some assets packages or either Line Renderer or Shaders, which I found to be overloaded for what I was trying to achieve.

    I finally managed to build it myself with very few code and want to share for everyone else googling in the future, enjoy:
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. /// <summary>
    4. /// Draws a selection rectangle on the left mouse button down & dragging
    5. ///
    6. /// You only need an InputReceiverManager that basically tracks
    7. /// - if the left mouse button is currently down and saves it in "LeftMouseButtonDown"
    8. /// - saves the initial click position when mouse button was clicked  and saves it in "InitialMousePositionOnLeftClick"
    9. /// - updates the current mouse position and saves it in "CurrentMousePosition"
    10. ///
    11. /// </summary>
    12. public class SelectionRectangleDrawer : MonoBehaviour
    13. {
    14.     //set color via inspector for the selection rectangles filler color
    15.     public Color SelectionRectangleFillerColor;
    16.     //set color via inspector for the selection rectangles border color
    17.     public Color SelectionRectangleBorderColor;
    18.     //set selection rectangles  border thickness
    19.     public int SelectionRectangleBorderThickness = 2;
    20.     private Texture2D _selectionRectangleFiller;
    21.     private Texture2D _selectionRectangleBorder;
    22.     private bool _drawSelectionRectangle;
    23.     private float _x1, _x2, _y1, _y2;
    24.     private Vector2 pos1, pos2;
    25.     void Start()
    26.     {
    27.         _selectionRectangleFiller = new Texture2D(1, 1);
    28.         _selectionRectangleFiller.SetPixel(0, 0, SelectionRectangleFillerColor);
    29.         _selectionRectangleFiller.Apply();
    30.         _selectionRectangleFiller.wrapMode = TextureWrapMode.Clamp;
    31.         _selectionRectangleFiller.filterMode = FilterMode.Point;
    32.         _selectionRectangleBorder = new Texture2D(1, 1);
    33.         _selectionRectangleBorder.SetPixel(0, 0, SelectionRectangleBorderColor);
    34.         _selectionRectangleBorder.Apply();
    35.         _selectionRectangleBorder.wrapMode = TextureWrapMode.Clamp;
    36.         _selectionRectangleBorder.filterMode = FilterMode.Point;
    37.     }
    38.     void Update()
    39.     {
    40.         if (InputReceiverManager.Instance.LeftMouseButtonDown && !Mathf.Approximately(Vector2.Distance(InputReceiverManager.Instance.CurrentMousePosition,
    41.                                                                                                        InputReceiverManager.Instance.InitialMousePositionOnLeftClick), 0f))
    42.             _drawSelectionRectangle = true;
    43.         else if (!InputReceiverManager.Instance.LeftMouseButtonDown && _drawSelectionRectangle)
    44.             _drawSelectionRectangle = false;
    45.     }
    46.     private void OnGUI()
    47.     {
    48.         if (_drawSelectionRectangle)
    49.             drawSelectionRectangle();
    50.     }
    51.     private void drawSelectionRectangle()
    52.     {
    53.         pos1 = InputReceiverManager.Instance.InitialMousePositionOnLeftClick;
    54.         pos2 = InputReceiverManager.Instance.CurrentMousePosition;
    55.         //check initial mouse position on X axis versus dragging mouse position
    56.         if (pos1.x < pos2.x)
    57.         {
    58.             _x1 = pos1.x;
    59.             _x2 = pos2.x;
    60.         }
    61.         else
    62.         {
    63.             _x1 = pos2.x;
    64.             _x2 = pos1.x;
    65.         }
    66.         //check initial mouse position on Y axis versus dragging mouse position
    67.         if (pos1.y < pos2.y)
    68.         {
    69.             _y1 = pos1.y;
    70.             _y2 = pos2.y;
    71.         }
    72.         else
    73.         {
    74.             _y1 = pos2.y;
    75.             _y2 = pos1.y;
    76.         }
    77.         //filler
    78.         GUI.DrawTexture(new Rect(_x1, Screen.height - _y1, _x2 - _x1, _y1 - _y2), _selectionRectangleFiller, ScaleMode.StretchToFill);
    79.         //top line
    80.         GUI.DrawTexture(new Rect(_x1, Screen.height - _y1, _x2 - _x1, -SelectionRectangleBorderThickness), _selectionRectangleBorder, ScaleMode.StretchToFill);
    81.         //bottom line
    82.         GUI.DrawTexture(new Rect(_x1, Screen.height - _y2, _x2 - _x1, SelectionRectangleBorderThickness), _selectionRectangleBorder, ScaleMode.StretchToFill);
    83.         //left line
    84.         GUI.DrawTexture(new Rect(_x1, Screen.height - _y1, SelectionRectangleBorderThickness, _y1 - _y2), _selectionRectangleBorder, ScaleMode.StretchToFill);
    85.         //right line
    86.         GUI.DrawTexture(new Rect(_x2, Screen.height - _y1, -SelectionRectangleBorderThickness, _y1 - _y2), _selectionRectangleBorder, ScaleMode.StretchToFill);
    87.     }
    88. }
    89.  
    90.  
    91.