Reputation: 1420
What's the proper way of drawing rect outline based on mouse hover. Effect you get in strategy games when selecting units. Running Unity 2018.3.0f. Perhaps my code can be slightly changed. I was unable to find something done. As second option I could use LineRenderer and create a rect based on that line. Adding lines that would make the rect.
This is what I came up with but for some reason this has wrong Y coords.
using UnityEngine;
using System.Collections;
using System;
public class MouseDragSelect : MonoBehaviour
{
private Rect position = new Rect(193, 148, 249-193, 148-104);
public Color color = Color.green;
private Vector3[] mousePositions = new Vector3[2];
private bool draggingMouse = false;
private bool drawRect = false;
public float timer = 1.2f;
void OnGUI()
{
if (drawRect)
{
DrawRectangle(position, 1, color);
}
}
void DrawRectangle(Rect area, int frameWidth, Color color)
{
//Create a one pixel texture with the right color
var texture = new Texture2D(1, 1);
texture.SetPixel(0, 0, color);
texture.Apply();
Rect lineArea = area;
lineArea.height = frameWidth; //Top line
GUI.DrawTexture(lineArea, texture);
lineArea.y = area.yMax - frameWidth; //Bottom
GUI.DrawTexture(lineArea, texture);
lineArea = area;
lineArea.width = frameWidth; //Left
GUI.DrawTexture(lineArea, texture);
lineArea.x = area.xMax - frameWidth;//Right
GUI.DrawTexture(lineArea, texture);
}
void reset() {
drawRect = false;
mousePositions[0] = new Vector3();
mousePositions[1] = new Vector3();
timer = 1.2f;
draggingMouse = false;
}
private void Update()
{
if (drawRect)
{
if (timer > 0.1)
{
timer -= 1 * Time.deltaTime;
} else {
reset();
}
}
if(Input.GetMouseButtonDown(0)) {
if(!draggingMouse){
mousePositions[0] = Input.mousePosition;
print("x start:" + mousePositions[0].x);
print("y start:" + mousePositions[0].y);
}
draggingMouse = true;
}
if(Input.GetMouseButtonUp(0)) {
if(draggingMouse) {
mousePositions[1] = Input.mousePosition;
float width = Math.Abs(mousePositions[1].x - mousePositions[0].x);
float height = Math.Abs(mousePositions[1].y - mousePositions[0].y);
float x = mousePositions[0].x;
float y = mousePositions[0].y;
// print("width:" + width);
// print("height:" + height);
print("x end:" + mousePositions[1].x);
print("y end:" + mousePositions[1].y);
position = new Rect(x, y, width, height);
// print("Got last mouse position!");
drawRect = true;
}
}
}
}
Tried selecting area around the character.. Getting weird Y coords..
Following solutions does not work either :( as I am getting weird Y coords
float x = Math.Min(mousePositions[0].x, mousePositions[1].x);
float y = Math.Min(mousePositions[0].y, mousePositions[1].y);
float width = Math.Max(mousePositions[0].x, mousePositions[1].x) - x;
float height = Math.Max(mousePositions[0].y, mousePositions[1].y) - y;
Upvotes: 1
Views: 3143
Reputation: 1939
The key issue was Screen.height-mousePosition.y
as suggested by Technivorous, however this problem can be solved much more succinctly:
public class DrawSelect : MonoBehaviour
{
Texture2D selectTexture;
Vector3 boxOrigin;
Vector3 boxEnd;
bool drawing;
private void Start() {
selectTexture = new Texture2D(1, 1);
selectTexture.SetPixel(0, 0, UnityEngine.Color.white);
selectTexture.Apply();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Mouse0)) {
boxOrigin = Input.mousePosition;
drawing = true;
}
if (drawing) {
boxEnd = Input.mousePosition;
}
if(Input.GetKeyUp(KeyCode.Mouse0)) {
drawing = false;
}
}
void OnGUI() {
if (drawing) {
Rect area = new Rect(boxOrigin.x, Screen.height - boxOrigin.y, boxEnd.x - boxOrigin.x, boxOrigin.y - boxEnd.y);
Rect lineArea = area;
lineArea.height = 1; //Top line
GUI.DrawTexture(lineArea, selectTexture);
lineArea.y = area.yMax - 1; //Bottom
GUI.DrawTexture(lineArea, selectTexture);
lineArea = area;
lineArea.width = 1; //Left
GUI.DrawTexture(lineArea, selectTexture);
lineArea.x = area.xMax - 1;//Right
GUI.DrawTexture(lineArea, selectTexture);
}
}
}
Upvotes: 0
Reputation: 11
Just in case anyone was struggling with it as I was, here is the solution, which seems to be working correctly. The solution uses initial code by @Alex and adjustment by @Technivorous.
using UnityEngine;
using System.Collections;
using System;
public class MouseDragSelection : MonoBehaviour
{
private Rect position = new Rect(193, 148, 249 - 193, 148 - 104);
public Color color = Color.green;
private Vector3[] mousePositions = new Vector3[2];
private bool draggingMouse = false;
private bool drawRect = false;
public float timer = 1.2f;
void OnGUI()
{
if (drawRect)
{
DrawRectangle(position, 1, color);
}
}
void DrawRectangle(Rect area, int frameWidth, Color color)
{
//Create a one pixel texture with the right color
var texture = new Texture2D(1, 1);
texture.SetPixel(0, 0, color);
texture.Apply();
Rect lineArea = area;
lineArea.height = frameWidth; //Top line
GUI.DrawTexture(lineArea, texture);
lineArea.y = area.yMax - frameWidth; //Bottom
GUI.DrawTexture(lineArea, texture);
lineArea = area;
lineArea.width = frameWidth; //Left
GUI.DrawTexture(lineArea, texture);
lineArea.x = area.xMax - frameWidth;//Right
GUI.DrawTexture(lineArea, texture);
}
void reset()
{
drawRect = false;
mousePositions[0] = new Vector3();
mousePositions[1] = new Vector3();
timer = 1.2f;
draggingMouse = false;
}
private void Update()
{
if (drawRect)
{
if (timer > 0.1)
{
timer -= 1 * Time.deltaTime;
}
else
{
reset();
}
}
if (Input.GetMouseButtonDown(0))
{
if (!draggingMouse)
{
mousePositions[0] = Input.mousePosition;
print("x start:" + mousePositions[0].x);
print("y start:" + mousePositions[0].y);
}
draggingMouse = true;
}
if (Input.GetMouseButtonUp(0))
{
if (draggingMouse)
{
mousePositions[1] = Input.mousePosition;
float width = Math.Abs(mousePositions[1].x - mousePositions[0].x);
float height = Math.Abs(mousePositions[1].y - mousePositions[0].y);
float x = mousePositions[0].x;
float y = Screen.height - mousePositions[0].y;
// print("width:" + width);
// print("height:" + height);
print("x end:" + mousePositions[1].x);
print("y end:" + mousePositions[1].y);
if (mousePositions[0].x < mousePositions[1].x && mousePositions[0].y < mousePositions[1].y)
{
print("x1 < x2, y1 < y2");
position = new Rect(x, y, width, -height);
}
else if (mousePositions[0].x > mousePositions[1].x && mousePositions[0].y < mousePositions[1].y)
{
print("x1 > x2, y1 < y2");
position = new Rect(x, y, -width, -height);
}
else if (mousePositions[0].x < mousePositions[1].x && mousePositions[0].y > mousePositions[1].y)
{
print("x1 < x2, y1 > y2");
position = new Rect(x, y, width, height);
} else
{
print("x1 > x2, y1 > y2");
position = new Rect(x, y, -width, height);
}
// print("Got last mouse position!");
drawRect = true;
}
}
}
}
Upvotes: 1
Reputation: 1712
so for your y coord, screen space and world space are different frommouse to screen. change your y to Screen.height-mousePosition.y. this will fix it for you
Upvotes: 3