- Home /
How to convert Screen Units to World Units
I am trying to figure out how to do a unit conversion between screen and world.
For example. A player drags their finger 20 screen units, how many units in world space would that be?
I'm not looking for Camera.main.ScreenToWorldPoint. but how to find the unit conversion.
EDIT:
I wanted to add why I need the units... The Input.touches provides a delta position, but it's in screen space. I need to use this but to move something in world space. The Camera is moving, so the Camera.main.ScreenToWorldPoint is not going to work.
Answer by Coderdood · Jun 25, 2013 at 04:54 PM
Your probably going to have to use ScreenToWorldPoint. If you need a range you could use:
StartPoint = ScreenToWorldPoint(FingerStart);
EndPoint = ScreenToWorldPoint(FingerEnd);
Range = EndPoint - StartPoint;
Or something like that. Is there a particular reason ScreenToWorldPoint isn't what your looking for?
You could in theory do the math and figure it out - but unless you have a specific reason to not use ScreenToWorldPoint it would be a waste of effort. The world point will depend on a number of factors including camera angle, position and projection that unless you have a fixed camera would change over time.
Basically:
At frame 0: 20 Screen Units may equal 100 World Space units
At frame 1: 20 Screen Units may equal 50 World Space units
At frame 2: 20 Screen Units may equal 1000196 Worlds Space units
So tldr: Just use ScreenToWorldPoint.
That's exactly what I was looking for, I need to do a start and end to get the right measurement. Thanks
This is how I solved my problem:
Vector3 p1 = Camera.main.ScreenToWorldPoint(Vector3.zero);
Vector3 p2 = Camera.main.ScreenToWorldPoint(Vector3.right);
float unit = Vector3.Distance(p1, p2);
Vector3 pt = new Vector3(Camera.main.transform.position.x - touchDelta.x * unit, Camera.main.transform.position.y - touchDelta.y * unit, Camera.main.transform.position.z);
using UnityEngine;
namespace Assets.Scripts.Other {
public static class CameraExtension {
public static float UnitsPerPixel(this Camera cam) {
var p1 = cam.ScreenToWorldPoint(Vector3.zero);
var p2 = cam.ScreenToWorldPoint(Vector3.right);
return Vector3.Distance(p1, p2);
}
public static float PixelsPerUnit(this Camera cam) {
return 1/UnitsPerPixel(cam);
}
}
}
Nice Idea, I made them extension methods
When you use Camera.main, you are actually doing a tag search for the first camera with the tag "$$anonymous$$ainCamera". If you are doing this every frame, you might want to first cache a reference to the camera in the Start function.
Camera mainCamera;
void Start()
{
mainCamera = Camera.main;
}
void Update()
{
if (Input.touchCount > 0){
Vector2 touchPos = Input.GetTouch(0).position;
Vector3 worldPos = mainCamera.ScreenToWorldPoint(new Vector3(touchPos.x, touchPos.y, 0));
}
}
Also wanted to mention that a moving camera doesn't mean the world points are wrong. The world points are relative to the camera's position.
Answer by slek120 · Mar 16, 2014 at 12:44 PM
This can give you a conversion, although it's not the same as camera.ScreenToWorldPoint.
Vector2 test = Random.insideUnitCircle * Screen.height;
float height;
if (camera.orthographic)
// Size is half of the height of the screen
height = camera.orthographicSize;
else
// Since units depends on how far the camera is to the plane that you are displaying on, trig becomes necessary
// As you can imagine, this will be really annoying if your camera or your plane is rotating
// I assume here that the plane is at origin and normal points to camera
height = Mathf.Tan (camera.fieldOfView * 0.5f) * Vector3.Magnitude (camera.transform.position);
// Both ortho and perspective cameras calculate width using height
float width = height * camera.aspect;
// First convert to a box with coordinates (-0.5,-0.5) to (0.5,0.5)
// Then scale to world units
Vector3 testPos = new Vector3 (width * (test.x / Screen.width - 0.5f), height * (test.y / Screen.width - 0.5f), 0);
And that is why I use camera.ScreenToWorldPoint
Also, a world unit is supposed to be a meter, which is 100px when you import textures. Since iPhone5 resolution is 640x1136, an orthographic camera of size 5.68 (=1136/2/100) will give you the exact size for a texture of size 640x1136
Answer by TheDarkVoid · Jun 25, 2013 at 04:54 PM
This would be fairly simple to accomplish. First you need to look at Camera.ScreenPointToRay(). On the start of the drag you will use Camera.ScreenPointToRay() and save the hit point, and do the same at the end on the drag. You can then use Vector3.Distance() to find the distance between the two points.
Answer by NymoBasepro · Jul 29, 2017 at 09:57 PM
@youtilities Thanks men, this is the first usefull thing I read about it!