Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

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

Discussion in '2D' started by EnjeruDarari, Sep 29, 2022.

  1. EnjeruDarari

    EnjeruDarari

    Joined:
    Jul 6, 2020
    Posts:
    6
    Hi.
    When I try to specify a side to check a neighbor in Tiling Rules, I get an 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:

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. using UnityEngine.Tilemaps;
    4.  
    5.  
    6. [CreateAssetMenu]
    7. public class SiblingTileRule : RuleTile<SiblingTileRule>
    8. {
    9.     [SerializeField] Sprite FogSprite;
    10.     [SerializeField] List<TileBase> Siblings = new List<TileBase>();
    11.     public bool IsVisible { get; set; } = false;
    12.  
    13.     public override bool StartUp(Vector3Int position, ITilemap tilemap, GameObject instantiatedGameObject)
    14.     {
    15.         IsVisible = false;
    16.         return base.StartUp(position, tilemap, instantiatedGameObject);
    17.     }
    18.  
    19.     public override bool RuleMatch(int neighbor, TileBase other)
    20.     {
    21.         if (Application.isPlaying)
    22.         {
    23.             switch (neighbor)
    24.             {
    25.                 case TilingRuleOutput.Neighbor.This:
    26.                 {
    27.                     return other == this || Siblings.Contains(other);
    28.                 }
    29.                 case TilingRuleOutput.Neighbor.NotThis:
    30.                 {
    31.                     return other != this && !Siblings.Contains(other);
    32.                 }
    33.             }
    34.         }
    35.  
    36.         return base.RuleMatch(neighbor, other);
    37.     }
    38.  
    39.     public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData)
    40.     {
    41.         base.GetTileData(position, tilemap, ref tileData);
    42.         if (!IsVisible && Application.isPlaying)
    43.         {
    44.             tileData.sprite = FogSprite;
    45.         }
    46.     }
    47. }
    48.  
     
  2. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    Hi, the expectation for T is the Neighbors for your RuleTile, which would be:

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. using UnityEngine.Tilemaps;
    4. [CreateAssetMenu]
    5. public class SiblingTileRule : RuleTile<SiblingTileRule.Neighbor>
    6. {
    7.     [SerializeField] Sprite FogSprite;
    8.     [SerializeField] List<TileBase> Siblings = new List<TileBase>();
    9.    
    10.     public class Neighbor
    11.     {
    12.         public const int This = 1;
    13.         public const int NotThis = 2;
    14.         public const int Siblings = 3;
    15.     }
    16.  
    17.     .......
    18. }
    If there are no changes for the Rules for matching neighbours, you could instead derive from RuleTile:

    public class SiblingTileRule : RuleTile


    Hope this helps!
     
    InfiniteDuelz and EnjeruDarari like this.