提问人:Nick785 提问时间:9/21/2023 最后编辑:Nick785 更新时间:9/21/2023 访问量:24
在 Unity 中渲染等距交错瓦片贴图时缺少瓦片
Missing tiles when rendering an isometric Staggered tilemap in Unity
问:
我正在尝试在Unity中的等距交错瓦片地图上显示图块,但缺少一些图块。我认为问题可能出在我放置瓷砖的位置或一些浮点精度问题上。
主要问题:
我从JSON文件中读取图块,并尝试将它们放在Unity Tilemap上。但是,有些瓷砖就是不显示。我已经仔细检查了我的数学,甚至尝试了一些小的调整,但我仍然缺少瓷砖。
这是我正在使用的代码:
MapLoader.cs - 负责从文件路径加载地图数据。
using System.IO;
using UnityEngine;
public static class MapLoader
{
public static MapDataStructure.MapData LoadMapFromPath(string path)
{
if (!IsValidPath(path)) return null;
return DeserializeMap(File.ReadAllText(path));
}
private static bool IsValidPath(string path)
{
if (File.Exists(path)) return true;
Debug.LogError($"Cannot find or access map file at: {path}");
return false;
}
private static MapDataStructure.MapData DeserializeMap(string jsonData)
{
return JsonUtility.FromJson<MapDataStructure.MapData>(jsonData);
}
}
TilePlacer.cs - 包含用于确定要放置的图块及其世界位置的逻辑。
using UnityEngine;
using UnityEngine.Tilemaps;
public class TilePlacer
{
private readonly Tilemap _tilemap;
private readonly Tile[] _tileAssets;
public TilePlacer(Tilemap tilemap, Tile[] tileAssets)
{
_tilemap = tilemap;
_tileAssets = tileAssets;
}
public void PlaceTileAtCoordinates(int[] tileData, int x, int y, MapDataStructure.MapData mapData)
{
int tileIndex = GetTileIndex(tileData, x, y, mapData);
if (IsValidTileIndex(tileIndex))
{
PlaceTile(tileIndex, x, y, mapData);
}
else
{
Debug.LogWarning($"Invalid tile index {tileIndex} at position {y},{x}");
}
}
private int GetTileIndex(int[] tileData, int x, int y, MapDataStructure.MapData mapData)
{
return tileData[y * mapData.width + x] - 1;
}
private bool IsValidTileIndex(int tileIndex)
{
return tileIndex >= 0 && tileIndex < _tileAssets.Length;
}
private void PlaceTile(int tileIndex, int x, int y, MapDataStructure.MapData mapData)
{
Vector3 tileWorldPosition = ComputeTileWorldPosition(x, y, mapData);
Vector3Int cellPosition = _tilemap.WorldToCell(tileWorldPosition);
_tilemap.SetTile(cellPosition, _tileAssets[tileIndex]);
}
private Vector3 ComputeTileWorldPosition(int x, int y, MapDataStructure.MapData mapData)
{
float worldX = x * mapData.tileWidth;
float worldY = y * mapData.tileHeight / 2;
// Adjust x for odd rows
if ((y & 1) == 1)
{
worldX += mapData.tileWidth / 2;
}
return new Vector3(worldX, worldY, 0);
}
}
TilemapRenderer.cs - 管理将图块渲染到瓦片图的过程。
using System.IO;
using UnityEngine;
using UnityEngine.Tilemaps;
public class TilemapRenderer : MonoBehaviour
{
[SerializeField]
private string mapFileName = "WorldMap.json";
[SerializeField]
private Tile[] tileAssets;
private Tilemap tilemap;
private TilePlacer tilePlacer;
private const int DEFAULT_LAYER_INDEX = 0;
private void Start()
{
tilemap = GetComponent<Tilemap>();
tilePlacer = new TilePlacer(tilemap, tileAssets);
LoadAndRenderMap();
}
private void LoadAndRenderMap()
{
string filePath = BuildFilePath();
MapDataStructure.MapData mapData = MapLoader.LoadMapFromPath(filePath);
if (mapData != null)
{
RenderTilesFromLayer(mapData, DEFAULT_LAYER_INDEX);
}
else
{
Debug.LogError("Failed to deserialize map data from the file.");
}
}
private string BuildFilePath()
{
return Path.Combine(Application.streamingAssetsPath, mapFileName);
}
private void RenderTilesFromLayer(MapDataStructure.MapData mapData, int layerIndex)
{
if (mapData.layers == null || layerIndex >= mapData.layers.Length)
{
Debug.LogError("Invalid map layer.");
return;
}
int[] tileData = mapData.layers[layerIndex].data;
for (int y = 0; y < mapData.height; y++)
{
for (int x = 0; x < mapData.width; x++)
{
tilePlacer.PlaceTileAtCoordinates(tileData, x, y, mapData);
}
}
}
}
代码的重要部分:
TilePlacer.cs 中的 ComputeTileWorldPosition 函数根据给定图块的坐标 x 和 y 计算其世界位置。 计算世界位置后,函数_tilemap。WorldToCell 用于将此世界位置转换为单元格位置。
截图:
我尝试过什么:
如果我在放置每个图块的位置添加一个小的偏移量(如 0.1),或者如果我将网格的位置更改为 -0.5,它似乎可以修复它。但感觉我只是在修补问题,而不是真正解决它。
下面是调整后的 ComputeTileWorldPosition 函数:
private Vector3 ComputeTileWorldPosition(int x, int y, MapDataStructure.MapData mapData)
{
float worldX = x * mapData.tileWidth;
float worldY = y * mapData.tileHeight / 2;
// Adjust x for odd rows
if ((y & 1) == 1)
{
worldX += mapData.tileWidth / 2;
}
worldX += 0.1f;
worldY += 0.1f;
return new Vector3(worldX, worldY, 0);
}
以前有没有人遇到过这个问题,或者看到我可能做错了什么?任何帮助都会很棒!谢谢!
答: 暂无答案
上一个:将终端中的字符串与 c 对齐#
下一个:控制台中的 C#“不是数字”
评论