问题
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:
- Ensure that the camera is 16:9 and my scene will be 100% displayed in it
- Build a 2D platform tileset as in an array
My environment:
- Unity 5.5.0f3 (in 2D Mode)
- Camera projection ortographic size 10.9
- Game displayed in 16:9
- Tileset dimensions are 128x128 px
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:
- I'm using ScreenToWorldPoint to get me the position for 0,0,0
- My building order goes from bottom left to top right, each iteration is put as the past position + block width/height (x and y)
- I'm using a 16:9 for scheme which is 32:18
Using it, this is my result:
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:
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));
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.
回答1:
"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
来源:https://stackoverflow.com/questions/41404299/how-to-instantiate-tiles-based-on-a-2d-array-into-a-platform-game-using-unity