Skip to content

Commit

Permalink
RuleTile Fixes (Unity-Technologies#332)
Browse files Browse the repository at this point in the history
* -Store existing ids for all rules before validating ids

* -Check validity of originalRule in DrawRuleElement

* -C# changes for RuleTile and RuleTileEditor
  • Loading branch information
ChuanXin-Unity authored Feb 28, 2022
1 parent 25d619e commit e110805
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ public void DrawRulesHeader(Rect rect)
public void DrawRuleElement(Rect rect, int index, bool active, bool focused)
{
RuleTile.TilingRule originalRule = m_Rules[index].Key;
if (originalRule == null)
return;

RuleTile.TilingRuleOutput overrideRule = m_Rules[index].Value;
bool isMissing = index >= m_MissingOriginalRuleIndex;

Expand Down
30 changes: 19 additions & 11 deletions Editor/Tiles/RuleTile/RuleTileEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,20 @@ public virtual void OnDisable()

private void UpdateTilingRuleIds()
{
HashSet<int> usedIdSet = new HashSet<int>();
var existingIdSet = new HashSet<int>();
var usedIdSet = new HashSet<int>();
foreach (var rule in tile.m_TilingRules)
{
while (usedIdSet.Contains(rule.m_Id))
rule.m_Id++;
existingIdSet.Add(rule.m_Id);
}
foreach (var rule in tile.m_TilingRules)
{
if (usedIdSet.Contains(rule.m_Id))
{
while (existingIdSet.Contains(rule.m_Id))
rule.m_Id++;
existingIdSet.Add(rule.m_Id);
}
usedIdSet.Add(rule.m_Id);
}
}
Expand Down Expand Up @@ -934,14 +943,13 @@ private static List<Sprite> GetValidSingleSprites(Object[] objects)
List<Sprite> result = new List<Sprite>();
foreach (Object obj in objects)
{
if (obj is Sprite)
if (obj is Sprite sprite)
{
result.Add(obj as Sprite);
result.Add(sprite);
}
else if (obj is Texture2D)
else if (obj is Texture2D texture2D)
{
Texture2D texture = obj as Texture2D;
List<Sprite> sprites = GetSpritesFromTexture(texture);
List<Sprite> sprites = GetSpritesFromTexture(texture2D);
if (sprites.Count > 0)
{
result.AddRange(sprites);
Expand Down Expand Up @@ -1116,9 +1124,9 @@ public override Texture2D RenderStaticPreview(string assetPath, Object[] subAsse
return base.RenderStaticPreview(assetPath, subAssets, width, height);
}

private static Type GetType(string TypeName)
private static Type GetType(string typeName)
{
var type = Type.GetType(TypeName);
var type = Type.GetType(typeName);
if (type != null)
return type;

Expand All @@ -1129,7 +1137,7 @@ private static Type GetType(string TypeName)
var assembly = Assembly.Load(assemblyName);
if (assembly != null)
{
type = assembly.GetType(TypeName);
type = assembly.GetType(typeName);
if (type != null)
return type;
}
Expand Down
58 changes: 29 additions & 29 deletions Runtime/Tiles/RuleTile/RuleTile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,19 +201,21 @@ public class TilingRule : TilingRuleOutput
/// <returns>A copy of the TilingRule.</returns>
public TilingRule Clone()
{
TilingRule rule = new TilingRule();
rule.m_Neighbors = new List<int>(m_Neighbors);
rule.m_NeighborPositions = new List<Vector3Int>(m_NeighborPositions);
rule.m_RuleTransform = m_RuleTransform;
rule.m_Sprites = new Sprite[m_Sprites.Length];
TilingRule rule = new TilingRule
{
m_Neighbors = new List<int>(m_Neighbors),
m_NeighborPositions = new List<Vector3Int>(m_NeighborPositions),
m_RuleTransform = m_RuleTransform,
m_Sprites = new Sprite[m_Sprites.Length],
m_GameObject = m_GameObject,
m_MinAnimationSpeed = m_MinAnimationSpeed,
m_MaxAnimationSpeed = m_MaxAnimationSpeed,
m_PerlinScale = m_PerlinScale,
m_Output = m_Output,
m_ColliderType = m_ColliderType,
m_RandomTransform = m_RandomTransform,
};
Array.Copy(m_Sprites, rule.m_Sprites, m_Sprites.Length);
rule.m_GameObject = m_GameObject;
rule.m_MinAnimationSpeed = m_MinAnimationSpeed;
rule.m_MaxAnimationSpeed = m_MaxAnimationSpeed;
rule.m_PerlinScale = m_PerlinScale;
rule.m_Output = m_Output;
rule.m_ColliderType = m_ColliderType;
rule.m_RandomTransform = m_RandomTransform;
return rule;
}

Expand Down Expand Up @@ -351,9 +353,9 @@ public override bool StartUp(Vector3Int position, ITilemap tilemap, GameObject i
Vector3 gameObjectScale = new Vector3();

bool ruleMatched = false;
Matrix4x4 transform = iden;
foreach (TilingRule rule in m_TilingRules)
{
Matrix4x4 transform = iden;
if (RuleMatches(rule, position, tilemap, ref transform))
{
transform = orientMatrix * transform;
Expand Down Expand Up @@ -399,9 +401,9 @@ public override void GetTileData(Vector3Int position, ITilemap tilemap, ref Tile
tileData.flags = TileFlags.LockTransform;
tileData.transform = iden;

Matrix4x4 transform = iden;
foreach (TilingRule rule in m_TilingRules)
{
Matrix4x4 transform = iden;
if (RuleMatches(rule, position, tilemap, ref transform))
{
switch (rule.m_Output)
Expand Down Expand Up @@ -438,7 +440,7 @@ public static float GetPerlinValue(Vector3Int position, float scale, float offse
}

static Dictionary<Tilemap, KeyValuePair<HashSet<TileBase>, HashSet<Vector3Int>>> m_CacheTilemapsNeighborPositions = new Dictionary<Tilemap, KeyValuePair<HashSet<TileBase>, HashSet<Vector3Int>>>();
static TileBase[] m_AllocatedUsedTileArr = new TileBase[0];
static TileBase[] m_AllocatedUsedTileArr = Array.Empty<TileBase>();

static bool IsTilemapUsedTilesChange(Tilemap tilemap, out KeyValuePair<HashSet<TileBase>, HashSet<Vector3Int>> hashSet)
{
Expand Down Expand Up @@ -481,10 +483,10 @@ static KeyValuePair<HashSet<TileBase>, HashSet<Vector3Int>> CachingTilemapNeighb
usedTiles.Add(tile);
RuleTile ruleTile = null;

if (tile is RuleTile)
ruleTile = tile as RuleTile;
else if (tile is RuleOverrideTile)
ruleTile = (tile as RuleOverrideTile).m_Tile;
if (tile is RuleTile rt)
ruleTile = rt;
else if (tile is RuleOverrideTile ot)
ruleTile = ot.m_Tile;

if (ruleTile)
foreach (Vector3Int neighborPosition in ruleTile.neighborPositions)
Expand Down Expand Up @@ -536,12 +538,11 @@ static void ReleaseDestroyedTilemapCacheData()
/// <returns>Whether the call was successful.</returns>
public override bool GetTileAnimationData(Vector3Int position, ITilemap tilemap, ref TileAnimationData tileAnimationData)
{
var iden = Matrix4x4.identity;
Matrix4x4 transform = Matrix4x4.identity;
foreach (TilingRule rule in m_TilingRules)
{
if (rule.m_Output == TilingRuleOutput.OutputSprite.Animation)
{
Matrix4x4 transform = iden;
if (RuleMatches(rule, position, tilemap, ref transform))
{
tileAnimationData.animatedSprites = rule.m_Sprites;
Expand All @@ -566,8 +567,7 @@ public override void RefreshTile(Vector3Int position, ITilemap tilemap)

ReleaseDestroyedTilemapCacheData(); // Prevent memory leak

KeyValuePair<HashSet<TileBase>, HashSet<Vector3Int>> neighborPositionsSet;
if (IsTilemapUsedTilesChange(baseTilemap, out neighborPositionsSet))
if (IsTilemapUsedTilesChange(baseTilemap, out var neighborPositionsSet))
neighborPositionsSet = CachingTilemapNeighborPositions(baseTilemap);

var neighborPositionsRuleTile = neighborPositionsSet.Value;
Expand All @@ -577,10 +577,10 @@ public override void RefreshTile(Vector3Int position, ITilemap tilemap)
TileBase tile = tilemap.GetTile(offsetPosition);
RuleTile ruleTile = null;

if (tile is RuleTile)
ruleTile = tile as RuleTile;
else if (tile is RuleOverrideTile)
ruleTile = (tile as RuleOverrideTile).m_Tile;
if (tile is RuleTile rt)
ruleTile = rt;
else if (tile is RuleOverrideTile ot)
ruleTile = ot.m_Tile;

if (ruleTile != null)
if (ruleTile == this || ruleTile.neighborPositions.Contains(offset))
Expand Down Expand Up @@ -706,8 +706,8 @@ public FieldInfo[] GetCustomFields(bool isOverrideInstance)
/// <returns>True if there is a match, False if not.</returns>
public virtual bool RuleMatch(int neighbor, TileBase other)
{
if (other is RuleOverrideTile)
other = (other as RuleOverrideTile).m_InstanceTile;
if (other is RuleOverrideTile ot)
other = ot.m_InstanceTile;

switch (neighbor)
{
Expand Down

0 comments on commit e110805

Please sign in to comment.