22
votes

Using Unity 4.3 in 2d mode I have a GameObject which is a sprite (in the SpriteRenderer I've setted the sprite), and I'm trying to position it in the top-left of the screen.

I would like to have this sprite to be positioned in the top left (for example) in every resolution (I have iOS as build target so in my case I'm talking about iPhone all resolutions, retina, non-retina, iPad etc).

What I'm missing is how exactly the coordinate system works, I'm used to work with pixels in a coordinate system where 0,0 start from bottom-left or top-left.

Here in Unity 4.3 seems like the 0,0 is in the center (this is not a big problem obviously) but what it makes me confused is that if I print the width of my object (which is 128px) I get an 1.06 as value, and also the screen is subdivided in "points" I suppose, so the left is -3 and the right is +3

so questions are: Why my sprite width is 1.06 ? How I'm supposed to position things perfectly within this system ?

Imagine I want to position a square of 128px*128px exactly at top left, how can I do it?

1
Are you looking at providing 2D graphics in your scene? If so you need to set up the camera in orthographic projection. Once you've got that done you can specify the view matrix and the frustum will be calculated for you when Unity multiplies your matrices. Try this forum post: forum.unity3d.com/threads/… or this one: answers.unity3d.com/questions/28533/… - though they aren't tutorials, you should be able to pick up the code for ortho setup from themCharleh
You are most specifically interested in camera.transformCharleh
When you say 'If I print the width of my object', what method are you using to calculate this width?ardrian
I'm using this: myObject.GetComponent<SpriteRenderer>().bounds.size.xAdarkuccio

1 Answers

38
votes

The first thing you may want to note is that when you import an image into unity as Texture Type = Sprite, there is a attribute "Pixels To Units", which you will see on the sprite asset.

enter image description here

So your 128px, if left at default settings, would be 1.28 "Units" wide. This value doesn't correspond with your measuresment of 1.06 however, so I'm not sure where that comes from. It could be because the scale of your sprite object isn't uniform, or it could be because your "Pixels To Units" setting has been modified. Double check in the inspector that your input texture is actually 128x128, and also check that the Pixel to Units value is what you expect it to be.

Next, note that the "Size" of an orthographic camera corresponds to half its height.

So in the below image, the ortho camera will see the area in the white box. Size 5, means 10 units high. The picture of a flower I have in the scene is a 128 pixel wide by 96 pixel high image, imported at default settings (1 unit = 100 pixels).

enter image description here

Now I'm not sure what your exact use case is (i.e. perhaps this is something better solved using a GUITexture). However assuming you want to use a Sprite, and every frame you want it to be in the top left corner, and you want that sprite to always be displayed at native res, then the following code would do it. Add it to a script attached to the Sprite game object.

// Update is called once per frame
void Update () {
    float camHalfHeight = Camera.main.orthographicSize;
    float camHalfWidth = Camera.main.aspect * camHalfHeight; 

    Bounds bounds = GetComponent<SpriteRenderer>().bounds;

    // Set a new vector to the top left of the scene 
    Vector3 topLeftPosition = new Vector3(-camHalfWidth, camHalfHeight, 0) + Camera.main.transform.position; 

    // Offset it by the size of the object 
    topLeftPosition += new Vector3(bounds.size.x / 2,-bounds.size.y / 2, 0);

    transform.position = topLeftPosition;        
}