- Home /
Converting pixel dimensions to Unity's floating-point coordinates
So I'm creating a Procedural Mesh (a Plane) for a 2D app. The app is set to 640x480 pixels, and uses a camera set to Orthographic. The Vector3s used to create a Mesh are floating-point coordinates for Unity world-space. However, I want to set my Mesh dimensions in pixels, but haven't yet figured out a reliable conversion method. Unity scales are still a mystery to me. :)
For example - if I create a unit-1 sized Mesh (at Points (0,0,0),(1,0,0),(1,1,0),(0,1,0)), it looks like it fills about 40 pixels of the screen. Further experimentation seemed to put it at 36 pixels. So if I wanted a Plane/Mesh that filled the top-left quadrant of the screen, I'd use Points like (8,8, 6.6, 0).
That might work, but I'd prefer a more reliable algorithm than Programming by Coincidence... So is there any other way to backtrack from a set of pixel dimensions, to their floating-point coordinates?
Update: Andrew's answer worked well - and looking at his sample mesh project got me to change a few other things in my project. For instance, I was programmatically creating a GameObject to assign all the mesh Components to, whereas he just created an empty GameObject and drag/dropped the script to it. I still am not thinking in the Unity Way. :) Second, I used the numbers 320x240 hardcoded (just for testing), which, for unknown reasons, made the mesh way too large - when I switched to Screen.height/2 (as Andrew's code uses), it sized things correctly.
Answer by kilgore · Jun 23, 2010 at 03:14 PM
A package containing an example using ScreenToWorldPoint can be found here. It produces a triangle based on the coordinates of the Screen.
using UnityEngine;
using System.Collections; using System.Collections.Generic;
public class CreateMesh : MonoBehaviour {
public Material mat;
private MeshRenderer meshRender; private MeshFilter meshFilter; private int[] tris = new int[]{0,1,2}; private List<Vector2> uvs = new List<Vector2>(); private Vector3[] verts = new Vector3[]{}; private List<Vector3> normals = new List<Vector3>();
void Start() { meshRender = gameObject.AddComponent<MeshRenderer>(); meshFilter = gameObject.AddComponent<MeshFilter>(); verts = new Vector3[] { ToPixel(new Vector3(0, 0, 999)), ToPixel(new Vector3(Screen.width / 2, Screen.height / 2, 999)), ToPixel(new Vector3(Screen.width / 2, 0, 999)) };
//Normals
for (var e = 0; e < verts.Length; e++)
{
normals.Add(transform.up);
}
//Verts
for (int i = 0; i < verts.Length; i++)
{
uvs.Add(new Vector2(verts[i].x, verts[i].z));
}
Mesh mesh = new Mesh();
mesh.vertices = verts;
mesh.uv = uvs.ToArray();
mesh.normals = normals.ToArray();
mesh.triangles = tris;
meshFilter.mesh = mesh;
renderer.material = mat;
}
private Vector3 ToPixel(Vector3 cord) { cord = Camera.main.ScreenToWorldPoint(cord); return (cord); }
}
Thanks, it worked (eventually :) Further comments in my Question.