I am making a game in unity using TileMap and I have a problem.
I made my own Rule Tile script, where I added my own rules – to check if the neighbor tile is from one of 4 arrays – room with top/bottom/left/right entrance, because I want rooms to connect with entrances, so there isn’t a lot of dead ends. (I also added a script, which changes the icons in unity explorer). I also added rule to check if the tile is NOT from an array.
Scripts work fine, but I got into a problem. Tiling rules use only the first and last rule, others are ignored (image). I tried changing the order (still rule on first place is used), but nothing happened.
Rule tile script:
using UnityEngine;
using UnityEngine.Tilemaps;
using System.Linq;
using System;
[CreateAssetMenu(menuName = "VinTools/Custom Tiles/Advanced Rule Tile")]
public class AdvancedRuleTile : RuleTile<AdvancedRuleTile.Neighbor>
{
[Header("Advanced Tile")]
[Tooltip("If enabled, the tile will connect to these tiles too when the mode is set to "This"")]
public bool alwaysConnect;
[Tooltip("Tiles to connect to")]
public TileBase[] tilesToConnect;
public TileBase[] topEntrance;
public TileBase[] bottomEntrance;
public TileBase[] leftEntrance;
public TileBase[] rightEntrance;
[Space]
[Tooltip("Check itseft when the mode is set to "any"")]
public bool checkSelf = true;
public class Neighbor : RuleTile.TilingRule.Neighbor
{
public const int Any = 3;
public const int Nothing = 4;
public const int topEntrance = 5;
public const int bottomEntrance = 6;
public const int leftEntrance = 7;
public const int rightEntrance = 8;
public const int notTopEntrance = 9;
public const int notBottomEntrance = 10;
public const int notLeftEntrance = 11;
public const int notRightEntrance = 12;
}
public override bool RuleMatch(int neighbor, TileBase tile)
{
switch (neighbor)
{
case Neighbor.This: return Check_This(tile);
case Neighbor.NotThis: return Check_NotThis(tile);
case Neighbor.Any: return Check_Any(tile);
case Neighbor.Nothing: return Check_Nothing(tile);
case Neighbor.topEntrance: return Check_topEntrance(tile);
case Neighbor.bottomEntrance: return Check_bottomEntrance(tile);
case Neighbor.leftEntrance: return Check_leftEntrance(tile);
case Neighbor.rightEntrance: return Check_rightEntrance(tile);
case Neighbor.notTopEntrance: return Check_notTopEntrance(tile);
case Neighbor.notBottomEntrance: return Check_notBottomEntrance(tile);
case Neighbor.notLeftEntrance: return Check_notLeftEntrance(tile);
case Neighbor.notRightEntrance: return Check_notRightEntrance(tile);
}
return base.RuleMatch(neighbor, tile);
}
/// <summary>
/// Returns true if the tile is this, or if the tile is one of the tiles specified if always connect is enabled.
/// </summary>
/// <param name="tile">Neighboring tile to compare to</param>
/// <returns></returns>
bool Check_This(TileBase tile)
{
if (!alwaysConnect) return tile == this;
else return tilesToConnect.Contains(tile) || tile == this;
//.Contains requires "using System.Linq;"
}
/// <summary>
/// Returns true if the tile is not this.
/// </summary>
/// <param name="tile">Neighboring tile to compare to</param>
/// <returns></returns>
bool Check_NotThis(TileBase tile)
{
if (!alwaysConnect) return tile != this;
else return !tilesToConnect.Contains(tile) && tile != this;
//.Contains requires "using System.Linq;"
}
/// <summary>
/// Return true if the tile is not empty, or not this if the check self option is disabled.
/// </summary>
/// <param name="tile">Neighboring tile to compare to</param>
/// <returns></returns>
bool Check_Any(TileBase tile)
{
if (checkSelf) return tile != null;
else return tile != null && tile != this;
}
/// <summary>
/// Returns true if the tile is empty.
/// </summary>
/// <param name="tile">Neighboring tile to compare to</param>
/// <param name="tile"></param>
/// <returns></returns>
bool Check_Nothing(TileBase tile)
{
return tile == null;
}
/// <summary>
/// Returns true if the tile is one of the specified tiles.
/// </summary>
/// <param name="tile">Neighboring tile to compare to</param>
/// <returns></returns>
bool Check_topEntrance(TileBase tile)
{
if (checkSelf) return tile != null;
else return tile != null && tile != this && tile == topEntrance.Contains(tile);
//return topEntrance.Contains(tile);
//.Contains requires "using System.Linq;"
}
bool Check_bottomEntrance(TileBase tile)
{
if (checkSelf) return tile != null;
else return tile != null && tile != this && tile == bottomEntrance.Contains(tile);
//return bottomEntrance.Contains(tile);
//.Contains requires "using System.Linq;"
}
bool Check_leftEntrance(TileBase tile)
{
if (checkSelf) return tile != null;
else return tile != null && tile != this && tile == leftEntrance.Contains(tile);
//return leftEntrance.Contains(tile);
//.Contains requires "using System.Linq;"
}
bool Check_rightEntrance(TileBase tile)
{
if (checkSelf) return tile != null;
else return tile != null && tile != this && tile == rightEntrance.Contains(tile);
//return rightEntrance.Contains(tile);
//.Contains requires "using System.Linq;"
}
bool Check_notTopEntrance(TileBase tile)
{
if (checkSelf) return tile != null;
else return tile != null && tile != this && tile != topEntrance.Contains(tile);
}
bool Check_notBottomEntrance(TileBase tile)
{
if (checkSelf) return tile != null;
else return tile != null && tile != this && tile != bottomEntrance.Contains(tile);
}
bool Check_notLeftEntrance(TileBase tile)
{
if (checkSelf) return tile != null;
else return tile != null && tile != this && tile != leftEntrance.Contains(tile);
}
bool Check_notRightEntrance(TileBase tile)
{
if (checkSelf) return tile != null;
else return tile != null && tile != this && tile != rightEntrance.Contains(tile);
}
}
Here are screenshots of my tiling rules: 1, 2, 3
- black “R” means room with entrance on right, etc. for other letters
- red “R” means room with NO entrance or right, etc. for other letters
If you are wondering how the tiles look, it’s here: image
Does somebody know why is it happening or how to fix it?
Thanks