Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unity 4.3 - understanding positions and screen resolution, how to properly set position of object?

Tags:

c#

unity3d

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?

like image 329
Adarkuccio Avatar asked Mar 23 '14 17:03

Adarkuccio


People also ask

How do I change the position of an object in Unity?

You can change the object position in the code by manipulating the transform property of the object. transform. position = new Vector3(1.0f, 1.0f, 1.0f); Simple as that!

How do I change my sprite position in Unity?

To change a Sprite from a script in Unity, create a reference variable to hold the new Sprite. Then set the Sprite property of the Sprite Renderer Component on the Game Object you wish to change to match the new, replacement Sprite.


1 Answers

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;        
}
like image 119
ardrian Avatar answered Oct 04 '22 21:10

ardrian