如何使用 Unity 将基于二维数组的图块实例化为平台游戏?
How to instantiate tiles based on a 2D Array into a Platform Game using Unity?
我正在构建一个非常简单的平台游戏,使用 2D 数组来构建基于它的地图。
我想要两个简单的目标,但我目前找不到答案:
- 确保相机16:9并且我的场景将100%显示在其中
- 在数组中构建 2D 平台图块集
我的环境:
- Unity 5.5.0f3(2D 模式)
- 相机投影正射尺寸10.9
- 游戏显示在16:9
- 图块集尺寸为 128x128 像素
这是我当前的代码:
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);
}
}
}
关于它有 3 点需要注意:
- 我正在使用 ScreenToWorldPoint 获取 0,0,0 的位置
- 我的建筑顺序是从左下角到右上角,每次迭代都作为过去的位置+块width/height(x和y)
- 我正在使用 16:9 作为方案 32:18
使用它,这是我的结果:
如您所见,它超出了相机边界,即使相机和代码都是 16:9,它也超过了 1 列。另请注意,实例化点正好在我的游戏对象的中间,所以我开始将其实例化为游戏对象宽度和高度的一半,意思是:
Vector3 pos = camera.ScreenToWorldPoint(new Vector3 (64, 64, 0));
结果如下:
完全不是我的预期,通过反复试验我发现它应该在 16,16:
Vector3 pos = camera.ScreenToWorldPoint(new Vector3 (16, 16, 0));
现在它非常适合,但它在顶部超过了 1 行,在右侧超过了 1.5 列。这不应该因为他们都是 16:9
我显然做错了什么,但我看不出是什么,我过去也遇到过这个问题,但我不记得我发现了什么。
"Pos" 需要在开始时换班。可以使用 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
这比使用幻数 (16,16,0) 更好。无论您使用什么比例尺,第一个图块都将位于左下角。
128x128 像素仅告诉我您使用的是方形图块。所以它是 128x128 像素 ,但我可以用一个图块填满整个屏幕,或者我可以让它尽可能小(在世界坐标中思考)。解决方案是缩放图块或更改相机的 orthognalSize。
简单的解决方案是更改 orthographicSize 以适合图块。
camera.orthographicSize = 18 * prefab.GetComponent<Renderer>().bounds.size.y * 0.5f;
orthographicSize 等于世界坐标高度的一半,你需要 18 个方块的高度。
所以所有代码组合在一起:
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
我正在构建一个非常简单的平台游戏,使用 2D 数组来构建基于它的地图。
我想要两个简单的目标,但我目前找不到答案:
- 确保相机16:9并且我的场景将100%显示在其中
- 在数组中构建 2D 平台图块集
我的环境:
- Unity 5.5.0f3(2D 模式)
- 相机投影正射尺寸10.9
- 游戏显示在16:9
- 图块集尺寸为 128x128 像素
这是我当前的代码:
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);
}
}
}
关于它有 3 点需要注意:
- 我正在使用 ScreenToWorldPoint 获取 0,0,0 的位置
- 我的建筑顺序是从左下角到右上角,每次迭代都作为过去的位置+块width/height(x和y)
- 我正在使用 16:9 作为方案 32:18
使用它,这是我的结果:
如您所见,它超出了相机边界,即使相机和代码都是 16:9,它也超过了 1 列。另请注意,实例化点正好在我的游戏对象的中间,所以我开始将其实例化为游戏对象宽度和高度的一半,意思是:
Vector3 pos = camera.ScreenToWorldPoint(new Vector3 (64, 64, 0));
结果如下:
完全不是我的预期,通过反复试验我发现它应该在 16,16:
Vector3 pos = camera.ScreenToWorldPoint(new Vector3 (16, 16, 0));
我显然做错了什么,但我看不出是什么,我过去也遇到过这个问题,但我不记得我发现了什么。
"Pos" 需要在开始时换班。可以使用 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
这比使用幻数 (16,16,0) 更好。无论您使用什么比例尺,第一个图块都将位于左下角。
128x128 像素仅告诉我您使用的是方形图块。所以它是 128x128 像素 ,但我可以用一个图块填满整个屏幕,或者我可以让它尽可能小(在世界坐标中思考)。解决方案是缩放图块或更改相机的 orthognalSize。
简单的解决方案是更改 orthographicSize 以适合图块。
camera.orthographicSize = 18 * prefab.GetComponent<Renderer>().bounds.size.y * 0.5f;
orthographicSize 等于世界坐标高度的一半,你需要 18 个方块的高度。
所以所有代码组合在一起:
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