using System.Collections.Generic; using System.Linq; using UnityEngine; using NavMeshPlus.Extensions; using UnityEngine.Tilemaps; //*********************************************************************************** // Contributed by author jl-randazzo github.com/jl-randazzo //*********************************************************************************** namespace NavMeshPlus.Components { [AddComponentMenu("Navigation/Navigation Modifier Tilemap", 33)] [HelpURL("https://github.com/Unity-Technologies/NavMeshComponents#documentation-draft")] [RequireComponent(typeof(Tilemap))] [RequireComponent(typeof(NavMeshModifier))] [DisallowMultipleComponent] [ExecuteInEditMode] public class NavMeshModifierTilemap : MonoBehaviour { [System.Serializable] public struct TileModifier { public TileBase tile; public bool overrideArea; [NavMeshArea] public int area; } private class MatchingTileComparator : IEqualityComparer { public static readonly IEqualityComparer Instance = new MatchingTileComparator(); public bool Equals(TileModifier a, TileModifier b) => a.tile == b.tile; public int GetHashCode(TileModifier tileModifier) => tileModifier.GetHashCode(); } // List of agent types the modifier is applied for. // Special values: empty == None, m_AffectedAgents[0] =-1 == All. [SerializeField] List m_AffectedAgents = new List(new int[] { -1 }); // Default value is All [SerializeField] List m_TileModifiers = new List(); private Dictionary m_ModifierMap; public Dictionary GetModifierMap() => m_TileModifiers.Where(mod => mod.tile != null).Distinct(MatchingTileComparator.Instance).ToDictionary(mod => mod.tile); void OnEnable() { CacheModifiers(); } public void CacheModifiers() { m_ModifierMap = GetModifierMap(); } #if UNITY_EDITOR public bool HasDuplicateTileModifiers() { return m_TileModifiers.Count != m_TileModifiers.Distinct(MatchingTileComparator.Instance).Count(); } #endif // UNITY_EDITOR public virtual bool TryGetTileModifier(Vector3Int coords, Tilemap tilemap, out TileModifier modifier) { if (tilemap.GetTile(coords) is TileBase tileBase) { return m_ModifierMap.TryGetValue(tileBase, out modifier); } modifier = new TileModifier(); return false; } public bool AffectsAgentType(int agentTypeID) { if (m_AffectedAgents.Count == 0) return false; if (m_AffectedAgents[0] == -1) return true; return m_AffectedAgents.IndexOf(agentTypeID) != -1; } } }