- Home /
Using 4.6 UI RectTransform as a RTS selection box
So I know there is documentation on RectTransform which I have looked at, and there are plenty of resources regarding selection boxes using the older OnGUI function. I am wanting to use the new 4.6 UI, in particular an image that visually shows my drag selection box. I am however having trouble with it, I think I'm close.
When a UI element goes into minus it doesn't show up what I have in my script is that when the co ordinates go into minus values the corner offsets flip and the delta x and y of the RectTransform turn to their positive equivalent. I have some public variables to monitor these values. I am having trouble that the .sizeDelta is turning positive but the values of height and width on the actual image is not.
My anchors are set to 0 (bottom left corner) .
CODE; using UnityEngine; using System.Collections; using UnityEngine.UI;
public class DragScript : MonoBehaviour {
public RectTransform selectionBox;
Vector2 mouseDragStart;
Vector2 mouseDragEnd;
public Vector2 offsetMax;
public Vector2 offsetMin;
public Vector2 size;
void Update ()
{
size = selectionBox.sizeDelta;
offsetMax = selectionBox.offsetMax;
offsetMin = selectionBox.offsetMin;
if(Input.GetMouseButtonDown(0))
{
mouseDragStart = Input.mousePosition;
selectionBox.position = mouseDragStart;
}
else if(Input.GetMouseButton(0))
{
if(offsetMax.x < offsetMin.x)
{
offsetMin.x = offsetMax.x;
offsetMax.x = mouseDragStart.x;
}
if(offsetMax.y < offsetMin.y)
{
offsetMin.y = offsetMax.y;
offsetMax.y = mouseDragStart.y;
}
if(size.x < 0)
{
//print ("x is negative");
size.x = size.x * -1;
}
if(size.y < 0)
{
//print ("y is negative");
size.y = size.y * -1;
}
}
if(Input.GetMouseButton(0))
{
selectionBox.offsetMax = Input.mousePosition;
}
}
}
Cheers,
Steve.
Tried that code and it seems to be acting odd, do you just want to drag something around the the UI?
Apologies, i've changed the question slightly to hopefully make it more clear
Answer by stevecus · Jan 27, 2015 at 10:22 AM
I found this on the Unity forums and does what I want,
Credits go to Korindian
sing UnityEngine;
using System.Collections;
public class GUISelectionBox : MonoBehaviour
{
// Draggable inspector reference to the Image GameObject's RectTransform.
public RectTransform selectionBox;
// This variable will store the location of wherever we first click before dragging.
private Vector2 initialClickPosition = Vector2.zero;
void Update()
{
// Click somewhere in the Game View.
if (Input.GetMouseButtonDown(0))
{
// Get the initial click position of the mouse. No need to convert to GUI space
// since we are using the lower left as anchor and pivot.
initialClickPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
// The anchor is set to the same place.
selectionBox.anchoredPosition = initialClickPosition;
}
// While we are dragging.
if (Input.GetMouseButton(0))
{
// Store the current mouse position in screen space.
Vector2 currentMousePosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
// How far have we moved the mouse?
Vector2 difference = currentMousePosition - initialClickPosition;
// Copy the initial click position to a new variable. Using the original variable will cause
// the anchor to move around to wherever the current mouse position is,
// which isn't desirable.
Vector2 startPoint = initialClickPosition;
// The following code accounts for dragging in various directions.
if (difference.x < 0)
{
startPoint.x = currentMousePosition.x;
difference.x = -difference.x;
}
if (difference.y < 0)
{
startPoint.y = currentMousePosition.y;
difference.y = -difference.y;
}
// Set the anchor, width and height every frame.
selectionBox.anchoredPosition = startPoint;
selectionBox.sizeDelta = difference;
}
// After we release the mouse button.
if (Input.GetMouseButtonUp(0))
{
// Reset
initialClickPosition = Vector2.zero;
selectionBox.anchoredPosition = Vector2.zero;
selectionBox.sizeDelta = Vector2.zero;
}
}
}
The canvas scaler must be set to constant pixel size for this to work. Just a tip!
Answer by Mmmpies · Jan 26, 2015 at 07:58 PM
Well I'm just going to post this as an answer as it says Drag in the title:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
public class DragUI : MonoBehaviour, IPointerDownHandler, IPointerUpHandler {
private bool mouseDown = false;
private Vector3 startMousePos;
private Vector3 startPos;
public void OnPointerDown(PointerEventData ped)
{
mouseDown = true;
startPos = transform.position;
startMousePos = Input.mousePosition;
}
public void OnPointerUp(PointerEventData ped)
{
mouseDown = false;
}
void Update ()
{
if (mouseDown) {
Vector3 currentPos = Input.mousePosition;
Vector3 diff = currentPos - startMousePos;
Vector3 pos = startPos + diff;
transform.position = pos;
}
}
}
That should get you dragging, not sure if you were hoping to also re-size it as you're referencing the offsets but this'll allow you to drag a panel. Just plonk it on the panel you want to drag.
Hi $$anonymous$$mmpies thanks for your input, this isn't quite what I would like. I would like to create a selection box that I drag to select units in a rts. (like command and conquer group selection)
Currently my code drags fine in the positive values of Unity screen space (which up and right are positive) but I lose the visual appearance of the UI image due to the value changing to $$anonymous$$us when dragging left or down past your origin of clicking. It might act weird if your anchors are not set to all 0.
Ah - apologigies for misunderstanding then you probaly want to look at this:
Which leads to this:
Answer by Txguug · Oct 03, 2016 at 08:13 PM
Just wrote this script using open gl lines and a static rect, so without any of the gui stuff. Hope it helps somebody
using UnityEngine;
using System.Collections;
using System;
public class MouseRectUnitSelect : MonoBehaviour{
public static bool Selecting = false;
Vector2 startPos;
Vector2 endPos;
public static Rect SelectionBox;
void Update()
{
if(Input.GetMouseButtonDown(0))
{
Selecting = true;
startPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
if (Input.GetMouseButtonUp(0))
{
Selecting = false;
}
if (Selecting)
{
endPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
float width = startPos.x - endPos.x;
float height = startPos.y - endPos.y;
/*
* C--D
* | |
* A--B
*
*/
if (width < 0 && height < 0) SelectionBox = new Rect(startPos, new Vector2 (-width, -height)); // A --> D
if (width < 0 && height > 0) SelectionBox = new Rect(new Vector2(startPos.x, endPos.y), new Vector2(-width, height)); // C --> B
if (width > 0 && height < 0) SelectionBox = new Rect(new Vector2(endPos.x, startPos.y), new Vector2 (width, -height)); // B --> C
if (width > 0 && height > 0) SelectionBox = new Rect(new Vector2(endPos.x, endPos.y), new Vector2(width, height)); // D --> A
}
}
static Material lineMaterial;
public void OnRenderObject()
{
if (!lineMaterial)
{
Shader shader = Shader.Find("Hidden/Internal-Colored");
lineMaterial = new Material(shader);
lineMaterial.hideFlags = HideFlags.HideAndDontSave;
lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
lineMaterial.SetInt("_ZWrite", 1);
}
lineMaterial.SetPass(0);
if(Selecting)
{
GL.PushMatrix();
GL.MultMatrix(transform.localToWorldMatrix);
GL.Begin(GL.LINES);
GL.Color(new Color(0,1,0));
GL.Vertex3(startPos.x, startPos.y, 0);
GL.Vertex3(startPos.x, endPos.y, 0);
GL.Vertex3(startPos.x, endPos.y, 0);
GL.Vertex3(endPos.x, endPos.y, 0);
GL.Vertex3(endPos.x, endPos.y, 0);
GL.Vertex3(endPos.x, startPos.y, 0);
GL.Vertex3(endPos.x, startPos.y, 0);
GL.Vertex3(startPos.x, startPos.y, 0);
GL.End();
GL.PopMatrix();
}
}
}
then this is on a unit to select it:
void Update()
{
if (MouseRectUnitSelect.Selecting && MouseRectUnitSelect.SelectionBox.Contains(transform.position))
{
// this unit is within the box
}
}
Your answer
Follow this Question
Related Questions
RTS Style Selection system (How to control one unit and not the others) 2 Answers
Create selection box by double tapping then dragging? (android mobile)(cnc style)(image embedded) 1 Answer
Math/Programming Question 4 Answers
Cant select objects using my box-selection script 1 Answer
Unity RayCast Selection 1 Answer