如何使大型 2d tilemap 更容易在 Unity 中加载
How to make large 2d tilemap easier to load in Unity
我正在 Unity 游戏引擎中创建一个小游戏,游戏的地图是从 2d tilemap 生成的。虽然 tilemap 包含如此多的图块,但对于像 phone 这样的设备来说很难渲染所有图块,因此帧速率会下降。地图是完全静态的,因为游戏中唯一移动的东西是主角精灵和跟随它的相机。地图本身没有移动物体,它非常简单,必须有一种方法可以只渲染它需要的部分,或者只渲染一次地图。我在研究该主题时发现,也许一个好的方法是使用 Unity 网格 class 将 tilemap 转换为网格。我无法弄清楚如何使用 2d tilemap 执行此操作,而且我看不出它对渲染时间有何好处,但如果有人能指出正确的方向来渲染大型 2d tilemap,那就太棒了。谢谢
瓷砖系统:
为了使瓦片地图工作,我将每个单独的瓦片作为预制件放在我的预制件文件夹中,并针对 2d 盒碰撞器和缩放尺寸更改了属性。我将瓷砖的每个单独预制件归因于 RGB 标度上的特定颜色,然后导入一个 png 文件,该文件具有我想要的预制件的相应颜色,如下所示:
然后我编写了一个脚本,将每个预制件放置在其关联颜色所在的位置。一块瓷砖看起来像这样:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Map : MonoBehaviour {
private int levelWidth;
private int levelHeight;
public Transform block13;
private Color[] tileColors;
public Color block13Color;
public Texture2D levelTexture;
public PlayerMobility playerMobility;
// Use this for initialization
void Start () {
levelWidth = levelTexture.width;
levelHeight = levelTexture.height;
loadLevel ();
}
// Update is called once per frame
void Update () {
}
void loadLevel(){
tileColors = new Color[levelWidth * levelHeight];
tileColors = levelTexture.GetPixels ();
for (int y = 0; y < levelHeight; y++) {
for (int x = 0; x < levelWidth; x++) {
// if (tileColors [x + y * levelWidth] == block13Color) {
// Instantiate(block13, new Vector3(x, y), Quaternion.identity);
// }
//
}
}
}
}
当与所有代码一起使用时,这会产生一个看起来像这样的地图(我取出了其他预制件的所有代码以保存 space)
您可以实例化相机范围内的图块并销毁不在相机范围内的图块。有几种方法可以做到这一点。但首先要确保消耗资源的实际上是大量的图块,而不是其他东西。
一种方法是为每个图块创建一个空的父游戏对象(右键单击 "Hierarchy" > 创建空
然后将脚本附加到这位家长。该脚本引用了相机 (如果您需要帮助,请告诉我) 并计算它与相机之间的距离,如果距离小于某个值,则实例化图块,否则销毁实例(如果它存在)。
它必须在 Update 函数中执行此操作以检查每帧的距离,或者您可以使用 "Coroutines" 来减少检查(更有效)。
另一种方法是将脚本附加到相机,该脚本具有包含所有图块实例的数组,并以相同的方式检查它们与相机的距离。如果您只有一个大型瓷砖地图,则可以执行此操作,因为如果您有多个大型瓷砖地图,将很难重新使用此脚本。
您还可以计算图块和角色精灵之间的距离,而不是相机。选择哪个更方便。
完成上述操作后,您仍然会出现丢帧现象,您可以放大相机以在其范围内包含更少的图块,但您必须重新计算距离。
我正在 Unity 游戏引擎中创建一个小游戏,游戏的地图是从 2d tilemap 生成的。虽然 tilemap 包含如此多的图块,但对于像 phone 这样的设备来说很难渲染所有图块,因此帧速率会下降。地图是完全静态的,因为游戏中唯一移动的东西是主角精灵和跟随它的相机。地图本身没有移动物体,它非常简单,必须有一种方法可以只渲染它需要的部分,或者只渲染一次地图。我在研究该主题时发现,也许一个好的方法是使用 Unity 网格 class 将 tilemap 转换为网格。我无法弄清楚如何使用 2d tilemap 执行此操作,而且我看不出它对渲染时间有何好处,但如果有人能指出正确的方向来渲染大型 2d tilemap,那就太棒了。谢谢
瓷砖系统: 为了使瓦片地图工作,我将每个单独的瓦片作为预制件放在我的预制件文件夹中,并针对 2d 盒碰撞器和缩放尺寸更改了属性。我将瓷砖的每个单独预制件归因于 RGB 标度上的特定颜色,然后导入一个 png 文件,该文件具有我想要的预制件的相应颜色,如下所示:
然后我编写了一个脚本,将每个预制件放置在其关联颜色所在的位置。一块瓷砖看起来像这样:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Map : MonoBehaviour {
private int levelWidth;
private int levelHeight;
public Transform block13;
private Color[] tileColors;
public Color block13Color;
public Texture2D levelTexture;
public PlayerMobility playerMobility;
// Use this for initialization
void Start () {
levelWidth = levelTexture.width;
levelHeight = levelTexture.height;
loadLevel ();
}
// Update is called once per frame
void Update () {
}
void loadLevel(){
tileColors = new Color[levelWidth * levelHeight];
tileColors = levelTexture.GetPixels ();
for (int y = 0; y < levelHeight; y++) {
for (int x = 0; x < levelWidth; x++) {
// if (tileColors [x + y * levelWidth] == block13Color) {
// Instantiate(block13, new Vector3(x, y), Quaternion.identity);
// }
//
}
}
}
}
当与所有代码一起使用时,这会产生一个看起来像这样的地图(我取出了其他预制件的所有代码以保存 space)
您可以实例化相机范围内的图块并销毁不在相机范围内的图块。有几种方法可以做到这一点。但首先要确保消耗资源的实际上是大量的图块,而不是其他东西。
一种方法是为每个图块创建一个空的父游戏对象(右键单击 "Hierarchy" > 创建空
然后将脚本附加到这位家长。该脚本引用了相机 (如果您需要帮助,请告诉我) 并计算它与相机之间的距离,如果距离小于某个值,则实例化图块,否则销毁实例(如果它存在)。
它必须在 Update 函数中执行此操作以检查每帧的距离,或者您可以使用 "Coroutines" 来减少检查(更有效)。
另一种方法是将脚本附加到相机,该脚本具有包含所有图块实例的数组,并以相同的方式检查它们与相机的距离。如果您只有一个大型瓷砖地图,则可以执行此操作,因为如果您有多个大型瓷砖地图,将很难重新使用此脚本。
您还可以计算图块和角色精灵之间的距离,而不是相机。选择哪个更方便。
完成上述操作后,您仍然会出现丢帧现象,您可以放大相机以在其范围内包含更少的图块,但您必须重新计算距离。