The RoadTile
example provides the ability to easily layout linear segments onto the Tilemap, such as roads or pipes, with a minimal set of sprites. The following is a script used to create the Tile.
using UnityEngine;
using System.Collections;
# if UNITY_EDITOR
using UnityEditor;
# endif
public class RoadTile : Tile
{
public Sprite[] m_Sprites;
public Sprite m_Preview;
// 刷新自身以及其他以正交和对角形式相邻的 RoadTile
public override void RefreshTile(Vector3Int location, ITilemap tilemap)
{
for (int yd = -1; yd <= 1; yd++)
for (int xd = -1; xd <= 1; xd++)
{
Vector3Int position = new Vector3Int(location.x + xd, location.y + yd, location.z);
if (HasRoadTile(tilemap, position))
tilemap.RefreshTile(position);
}
}
// 根据相邻的 RoadTile 确定使用哪个精灵,并将其旋转以适应其他瓦片。
//由于旋转取决于 RoadTile,因此为瓦片设置 TileFlags.OverrideTransform。
public override void GetTileData(Vector3Int location, ITilemap tilemap, ref TileData tileData)
{
int mask = HasRoadTile(tilemap, location + new Vector3Int(0, 1, 0)) ? 1 : 0;
mask += HasRoadTile(tilemap, location + new Vector3Int(1, 0, 0)) ? 2 : 0;
mask += HasRoadTile(tilemap, location + new Vector3Int(0, -1, 0)) ? 4 : 0;
mask += HasRoadTile(tilemap, location + new Vector3Int(-1, 0, 0)) ? 8 : 0;
int index = GetIndex((byte)mask);
if (index >= 0 && index < m_Sprites.Length)
{
tileData.sprite = m_Sprites[index];
tileData.color = Color.white;
var m = tileData.transform;
m.SetTRS(Vector3.zero, GetRotation((byte) mask), Vector3.one);
tileData.transform = m;
tileData.flags = TileFlags.LockTransform;
tileData.colliderType = ColliderType.None;
}
else
{
Debug.LogWarning("Not enough sprites in RoadTile instance");
}
}
// 这将确定该位置的瓦片是否是相同的 RoadTile。
private bool HasRoadTile(ITilemap tilemap, Vector3Int position)
{
return tilemap.GetTile(position) == this;
}
//下面根据相邻 RoadTile 的数量确定要使用的精灵
private int GetIndex(byte mask)
{
switch (mask)
{
case 0: return 0;
case 3:
case 6:
case 9:
case 12: return 1;
case 1:
case 2:
case 4:
case 5:
case 10:
case 8: return 2;
case 7:
case 11:
case 13:
case 14: return 3;
case 15: return 4;
}
return -1;
}
// 下面根据相邻 RoadTile 的位置确定要使用的旋转
private Quaternion GetRotation(byte mask)
{
switch (mask)
{
case 9:
case 10:
case 7:
case 2:
case 8:
return Quaternion.Euler(0f, 0f, -90f);
case 3:
case 14:
return Quaternion.Euler(0f, 0f, -180f);
case 6:
case 13:
return Quaternion.Euler(0f, 0f, -270f);
}
return Quaternion.Euler(0f, 0f, 0f);
}
# if UNITY_EDITOR
// 下面是添加菜单项以创建 RoadTile 资源的 helper 函数
[MenuItem("Assets/Create/RoadTile")]
public static void CreateRoadTile()
{
string path = EditorUtility.SaveFilePanelInProject("Save Road Tile", "New Road Tile", "Asset", "Save Road Tile", "Assets");
if (path == "")
return;
AssetDatabase.CreateAsset(ScriptableObject.CreateInstance<RoadTile>(), path);
}
# endif
}