Guilherme Garcia da Rosa
Guilherme Garcia da Rosa

Reputation: 1030

How to instantiate tiles based on a 2D Array into a Platform Game using Unity?

I'm building a very simple platform game using 2D array to build the map based on it.

There are two simple goals I want and I'm currently not finding the answer:

  1. Ensure that the camera is 16:9 and my scene will be 100% displayed in it
  2. Build a 2D platform tileset as in an array

My environment:

Here is my current code:

public Camera camera;
public GameObject prefab;

void Start () {
    Vector3 pos = camera.ScreenToWorldPoint(new Vector3 (0, 0, 0));
    Vector3 nextPosition = pos;
    for (int i = 0; i < 32; i++)
    {
        for(int j=0; j < 18; j++)
        {
            GameObject a = Instantiate(prefab, new Vector3(nextPosition.x, nextPosition.y, 0), Quaternion.identity);
            nextPosition = new Vector3(pos.x+(prefab.GetComponent<Renderer>().bounds.size.x)*i, pos.y+(prefab.GetComponent<Renderer>().bounds.size.y)*j,0);
        }
    }
}

There are 3 things to notice about it:

Using it, this is my result: enter image description here

As you can see it stays out of the camera boundary and even tho both camera and code are 16:9, it exceeds 1 column. Also note that the instantiate point is exactly in the middle of my GameObject, so I start instantiating it as half of the gameObject's width and height, meaning:

Vector3 pos = camera.ScreenToWorldPoint(new Vector3 (64, 64, 0));

And the reuslt is the following: enter image description here

Not what I expected at all, by trial and error I figured out it is suposed to be at 16,16:

Vector3 pos = camera.ScreenToWorldPoint(new Vector3 (16, 16, 0));

enter image description here Now its a perfect fit, but it exceeds 1 line at the top and 1,5 columns at the right. Which shouldn't because they are both 16:9

I'm clearly doing something wrong but I can't see what, I've been through this problem in the past but I don't remember what I figured out.

Upvotes: 2

Views: 988

Answers (1)

Badran
Badran

Reputation: 341

"Pos" needs a shift at the start. It can be achieved using Bounds.extents

    Vector3 pos = camera.ScreenToWorldPoint(new Vector3 (0, 0, 0));

    pos = new Vector3( pos.x + prefab.GetComponent<Renderer>().bounds.extents.x,
                      pos.y + prefab.GetComponent<Renderer>().bounds.extents.y,
                      0);


    //....the rest is the same as your code

This will be better than using the magic numbers (16,16,0). The first tile will be positioned at the left-bottom corner no matter what scale you use.

128x128 px only tells me that you're using a square tile. So it's 128x128 px but I can fill the whole screen with one tile or I can make it as tiny as I can (thinking in world coordinate). The solution is either to scale the tiles or change the orthognalSize of the camera.

The easy solution is to change the orthographicSize to fit the tiles.

camera.orthographicSize = 18 * prefab.GetComponent<Renderer>().bounds.size.y * 0.5f;

orthographicSize equals half the height in world coordinate and you need 18 tiles in height.

So all code combined :

        Bounds bound = prefab.GetComponent<Renderer>().bounds;

        camera.orthographicSize = 18 * bound.size.y * 0.5f;

        Vector3 pos = camera.ScreenToWorldPoint(Vector3.zero);
        pos = new Vector3( pos.x + bound.extents.x, pos.y + bound.extents.y, 0);

        //....The rest is the same as your code

Upvotes: 3

Related Questions