using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.Tilemaps; using static UnityEngine.RuleTile.TilingRuleOutput; [CreateAssetMenu(fileName = "CustomRuleTile", menuName = "2D/Tiles/Custom Rule Tile")] public class CustomRuleTile : RuleTile { public List siblings = new List(); private Dictionary ruleMatchCache = new Dictionary(); public class Neighbor : RuleTile.TilingRule.Neighbor { public const int Sibling = 3; } public override bool RuleMatch(int neighbor, TileBase tile) { // Create a unique key for caching based on neighbor and tile int cacheKey = neighbor; if (tile != null) { cacheKey = cacheKey * 23 + tile.GetInstanceID(); // Use prime number to reduce collisions } // Check if we have a cached result if (ruleMatchCache.TryGetValue(cacheKey, out bool cachedResult)) { return cachedResult; } // If not cached, compute the result bool result; // Handle null tiles if (tile == null) { result = neighbor == RuleTile.TilingRule.Neighbor.NotThis; } // Always allow connections to siblings or self else if (tile == this || siblings.Contains(tile)) { result = neighbor == RuleTile.TilingRule.Neighbor.This; } // For Sibling type explicitly else if (neighbor == Neighbor.Sibling) { result = siblings.Contains(tile); } // For any other case, use base behavior else { result = base.RuleMatch(neighbor, tile); } // Cache the result ruleMatchCache[cacheKey] = result; return result; } // Add method to clear cache when needed (e.g., when rules change or on chunk unload) public void ClearRuleCache() { ruleMatchCache.Clear(); } // Override RefreshTile to clear cache for that specific tile position public override void RefreshTile(Vector3Int position, ITilemap tilemap) { ClearRuleCache(); // Clear cache before refresh to ensure proper updates base.RefreshTile(position, tilemap); } }