using System.Collections.Generic; using System.Runtime.CompilerServices; using CoreGame; using UnityEngine; namespace CoreGame.Render { public static class ColliderSrv { private static readonly Dictionary s_ColliderMap = new Dictionary(); private static readonly int s_PlayerLayer = LayerMask.NameToLayer("Player"); private static readonly int s_EnemyLayer = LayerMask.NameToLayer("Enemy"); public static readonly int s_ObstacleLayer = LayerMask.NameToLayer("Obstacle"); private static int[] s_PlayerCollisionMasks; private static int[] s_EnemyCollisionMasks; public static void Init() { s_ColliderMap.Clear(); InitCollisionMasks(); } private static void InitCollisionMasks() { const int maxConditions = 1 << 3; //2^3 三种碰撞条件,敌方,友方,障碍物,可能会添加 s_PlayerCollisionMasks = new int[maxConditions]; s_EnemyCollisionMasks = new int[maxConditions]; for (var i = 0; i < maxConditions; i++) { s_PlayerCollisionMasks[i] = CalculateLayerMask(s_PlayerLayer, s_EnemyLayer, i); s_EnemyCollisionMasks[i] = CalculateLayerMask(s_EnemyLayer, s_PlayerLayer, i); } } private static int CalculateLayerMask(int sameLayer, int oppositeLayer, int collideWith) { var mask = 0; var sameLayerMask = 1 << sameLayer; var oppositeLayerMask = 1 << oppositeLayer; var obstacleLayerMask = 1 << s_ObstacleLayer; if ((collideWith & 1) != 0) // 敌方 mask |= oppositeLayerMask; if ((collideWith & 2) != 0) // 友方 mask |= sameLayerMask; if ((collideWith & 4) != 0) // 建筑物 mask |= obstacleLayerMask; return mask == 0 ? LayerMask.GetMask("Default") : mask; } /// /// 碰撞LayerMask /// /// 自己所在阵营 /// 碰撞参数掩码,1-敌方,2-友方,4-建筑物 /// public static LayerMask GetLayerMask(Faction faction, int collideWith) { return faction switch { Faction.Player => s_PlayerCollisionMasks[collideWith], Faction.Enemy => s_EnemyCollisionMasks[collideWith], _ => LayerMask.GetMask("Default") }; } public static int GetLayer(Faction faction) { if (faction == Faction.Player) return s_PlayerLayer; if (faction == Faction.Enemy) return s_EnemyLayer; return LayerMask.NameToLayer("Default"); } public static void AddCollider(Collider2D collider, int eid) { if (!s_ColliderMap.TryAdd(collider, eid)) { BattleLogger.LogInfo("ColliderSrv AddCollider failed"); } } public static void RemoveCollider(Collider2D collider) { if (!s_ColliderMap.Remove(collider)) { BattleLogger.LogInfo("ColliderSrv RemoveCollider failed"); } } public static void DisableCollider(Collider2D collider) { if (!s_ColliderMap.ContainsKey(collider)) { BattleLogger.LogInfo("ColliderSrv DisableCollider failed"); } collider.enabled = false; } public static void EnableCollider(Collider2D collider) { if (!s_ColliderMap.ContainsKey(collider)) { BattleLogger.LogInfo("ColliderSrv EnableCollider failed"); } collider.enabled = true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static CombatEntity GetEntityByCollider(Collider2D collider) { if (s_ColliderMap.TryGetValue(collider, out int eid)) { return (CombatEntity)Contexts.Combat.GetEntity(eid); } return null; } } }