- Home /
Measuring distance on Camera Screen-Space Canvas in -canvas units-
So: I have a canvas which is set to Screen Space - Camera. I have there (as its child) a Sprite (which is at a different angle than the canvas) and an Image. So the hierarchy looks like that:
-Canvas
--Sprite
---Image
I have a code that allows user to drag the image on the Sprites plane. The issue is, that I don't want the user to be allowed to drag the Image onto the Sprite. So I measure the distance between them (via Vector3.Distance), and don't update the Images transform if the distance is below some constant threshold. Everything works fine until I maximize "Game" window or change the resolution. Physical distance my threshold represents is different depending on the Canvas Scaling. So how I measure the distance between two objects on the Canvas in "Canvas units"? How to solve this problem in a neaty way?
I tried the constant pixel size and "scale with screen". I Also tried multiplying the distance by the Canvas.scaleFactor. None of this helps. Sure I can do this with Colliders and triggers but I don't want to produce unnecessary garbage. How does UnityEngine.UI class handle this? Sliders works fine on scalable canvas... Can You help me?
Answer by Prosto_Lyubo · Jan 11, 2016 at 01:03 PM
I found the solution, not as clean as I wanted but still better than dealing with unnecessary colliders. Since this question have so many followers I'll post it for You. I added two RectTransform objects 'RefA' and 'RefB' separated by 50 pixels (which corresponds to one Unity unit according to my sprites Import Settings). They both are children of my Canvas. Then I created property
private float DistanceUnit { get { return Vector3.Distance( RefA.position, RefB.position ); } }
It can also be made static and pushed to some Utility class if You want to use it in other classes. Last step is to divide any calculated distance by DistanceUnit value. Here is an example to above question:
var distance = Vector3.Distance( Image.transform.position, Sprite.transform.position ) / DistanceUnit;
First, thanks for post your solution. This is a good practice for helping even in non answered questions. Second, maybe Camera.WorldToScreenPoint could help in this kind of situations where you have to measure two points "as you see them" in the screen. This is helpful even for measuring distances between 3d objects in scene and GUI stuff. Not sure if this is the best solution for you issue, but may help ;)
Your answer
![](https://koobas.hobune.stream/wayback/20220612055636im_/https://answers.unity.com/themes/thub/images/avi.jpg)