Index was out of range when adding a neighbor to Rule Tile

,

Hi.
When I try to specify a side to check a neighbor in Tiling Rules, I get an error:
error

ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
System.Collections.Generic.List`1[T].get_Item (System.Int32 index) (at <9aad1b3a47484d63ba2b3985692d80e9>:0)
UnityEditor.RuleTileEditor.RuleNeighborUpdate (UnityEngine.Rect rect, UnityEngine.RuleTile+TilingRule tilingRule, System.Collections.Generic.Dictionary`2[TKey,TValue] neighbors, UnityEngine.Vector3Int position) (at Library/PackageCache/com.unity.2d.tilemap.extras@2.2.3/Editor/Tiles/RuleTile/RuleTileEditor.cs:732)
UnityEditor.RuleTileEditor.RuleMatrixIconOnGUI (UnityEngine.RuleTile+TilingRule tilingRule, System.Collections.Generic.Dictionary`2[TKey,TValue] neighbors, UnityEngine.Vector3Int position, UnityEngine.Rect rect) (at Library/PackageCache/com.unity.2d.tilemap.extras@2.2.3/Editor/Tiles/RuleTile/RuleTileEditor.cs:831)
UnityEditor.RuleTileEditor.RuleMatrixOnGUI (UnityEngine.RuleTile tile, UnityEngine.Rect rect, UnityEngine.BoundsInt bounds, UnityEngine.RuleTile+TilingRule tilingRule) (at Library/PackageCache/com.unity.2d.tilemap.extras@2.2.3/Editor/Tiles/RuleTile/RuleTileEditor.cs:808)
UnityEditor.RuleTileEditor.OnDrawElement (UnityEngine.Rect rect, System.Int32 index, System.Boolean isactive, System.Boolean isfocused) (at Library/PackageCache/com.unity.2d.tilemap.extras@2.2.3/Editor/Tiles/RuleTile/RuleTileEditor.cs:363)
UnityEditorInternal.ReorderableList.DoListElements (UnityEngine.Rect listRect, UnityEngine.Rect visibleRect) (at <0d6ce211ebbc47e1a35a84c3672ff58f>:0)
UnityEditorInternal.ReorderableList.DoLayoutList () (at <0d6ce211ebbc47e1a35a84c3672ff58f>:0)
UnityEditor.RuleTileEditor.OnInspectorGUI () (at Library/PackageCache/com.unity.2d.tilemap.extras@2.2.3/Editor/Tiles/RuleTile/RuleTileEditor.cs:545)
UnityEditor.UIElements.InspectorElement+<>c__DisplayClass59_0.<CreateIMGUIInspectorFromEditor>b__0 () (at <122642d41668428d845063b1753c4e72>:0)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)

My definition for Rule Tile:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;


[CreateAssetMenu]
public class SiblingTileRule : RuleTile<SiblingTileRule>
{
    [SerializeField] Sprite FogSprite;
    [SerializeField] List<TileBase> Siblings = new List<TileBase>();
    public bool IsVisible { get; set; } = false;

    public override bool StartUp(Vector3Int position, ITilemap tilemap, GameObject instantiatedGameObject)
    {
        IsVisible = false;
        return base.StartUp(position, tilemap, instantiatedGameObject);
    }

    public override bool RuleMatch(int neighbor, TileBase other)
    {
        if (Application.isPlaying)
        {
            switch (neighbor)
            {
                case TilingRuleOutput.Neighbor.This:
                {
                    return other == this || Siblings.Contains(other);
                }
                case TilingRuleOutput.Neighbor.NotThis:
                {
                    return other != this && !Siblings.Contains(other);
                }
            }
        }

        return base.RuleMatch(neighbor, other);
    }

    public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData)
    {
        base.GetTileData(position, tilemap, ref tileData);
        if (!IsVisible && Application.isPlaying)
        {
            tileData.sprite = FogSprite;
        }
    }
}

Hi, the expectation for T is the Neighbors for your RuleTile, which would be:

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps;
[CreateAssetMenu]
public class SiblingTileRule : RuleTile<SiblingTileRule.Neighbor>
{
    [SerializeField] Sprite FogSprite;
    [SerializeField] List<TileBase> Siblings = new List<TileBase>();
   
    public class Neighbor
    {
        public const int This = 1;
        public const int NotThis = 2;
        public const int Siblings = 3;
    }

    .......
}

If there are no changes for the Rules for matching neighbours, you could instead derive from RuleTile:

public class SiblingTileRule : RuleTile

Hope this helps!

2 Likes