Determine if mouse is within a set distance of UI element

Started by
5 comments, last by Shaarigan 4 years, 9 months ago

RectTransform rect = RCPanel.GetComponent<RectTransform> ();

	float width = rect.sizeDelta.x;
	float height = rect.sizeDelta.y;

	float distanceLeft = Input.mousePosition.x - (RCPanel.transform.position.x - width/2);
	float distanceRight = Input.mousePosition.x - (RCPanel.transform.position.x + width/2);
	float distanceTop = Input.mousePosition.y - (RCPanel.transform.position.y + height/2);
	float distanceBottom = Input.mousePosition.y - (RCPanel.transform.position.y - height/2);
	//Debug.Log (Input.mousePosition.x + ", " + Input.mousePosition.y);
	Debug.Log (distanceLeft + ", " + distanceRight + ", " + distanceTop + ", " + distanceBottom);
	if (distanceLeft < -10) {
		RCPanel.SetActive (false);
	}
	if (distanceRight > 10) {
		RCPanel.SetActive (false);
	}
	if (distanceTop > 10) {
		RCPanel.SetActive (false);
	}
	if (distanceBottom < -10) {
		RCPanel.SetActive (false);
	}

I am currently using the following script to determine whether the mouse is within 10 units of the mini menu (RCPanel stands for right click panel, i.e. the panel that i want to open when i rightclick). Mathematically it makes sense but there appears to be a flaw in my logic somewhere in the calculation of the 4 distance variables that I believe has something to do with the canvas scaling or conversion between mousePosition in real space and canvas space.

How can I account for the differences so that regardless of screensize or canvas size, the calcuation works correctly. Image provided below of how the mouse doesnt sit where it says it should be sitting. (distance left states a value of 10, but the mouse was positioned just barely to the right of the left border, which should produce a number between 0 and 1 units roughly) (had to redraw the cursor position in to show where it was since it wasnt captured)

Capture.JPG

Advertisement

You need to take the camera into account because you are trying to map pure 2D corrdinates into 3D world space. This can't work unless you also respect the aspect ration, screen size and distance.

Converting the mouse point like so


 Vector3 v3 = Input.mousePosition;
 v3.z = 0.1f; //distance of your UI
 v3 = Camera.main.ScreenToWorldPoint(v3); //UI camera

to get the transposed 3D coordinates. If you are using 2D then you have the same kind of matrix anywhere that translates your UI to screen.

If you want to track an element by collider, you can just replace that for a Raycast

If you were saying to keep my script identical except to replace all instances of the mouse position with that value of v3. Then after just attempting it I can say it does not work. The values shoot off to the negative hundreds in the y component and further than -1200 in the x component meaning that as soon as the menu is opened it is immediately closed.

If this was not what you were intending could you elaborate please.

 

First, are you suing 2D or 3D Unity and how is your UI rendered; is it 3D or 2D space?

What you are trying to do is to compare Screen Space Coordinates (pixels) with World Space Coordinates (Unity units)

I am using 3D unity. Ill post an image of the scene so you can see exactly what i am working with.
my UI is all rendered using the canvas as a screen overlay which i would imagine means 2d space.
 

Capture.JPG

No it's not 2D space but it may have it's own camera, you need to check that. The code I posted should work or you go the other way round and instead transform your UI's screen position


Vector3 screenPoint3D = Camera.main.WorldToScreenPoint(worldSpacePosition);
Vector2 screenPoint = new Vector2(screenPoint3D.x, screenPoint3D.y);

We used this code to project a world point into screen corrdinates for displaying an overlay (a distance from the player to the target)

This topic is closed to new replies.

Advertisement