miepzerino
2025-04-03 4f1ed3919b0ee3f89dbcbacf49990888a7d9274a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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<CustomRuleTile.Neighbor>
{
 
    public List<TileBase> siblings = new List<TileBase>();
    private Dictionary<int, bool> ruleMatchCache = new Dictionary<int, bool>();
    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);
    }
}