You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
4.2 KiB
124 lines
4.2 KiB
1 month ago
|
using System.Collections.Generic;
|
||
|
using System.Runtime.CompilerServices;
|
||
|
using CoreGame;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace CoreGame.Render
|
||
|
{
|
||
|
public static class ColliderSrv
|
||
|
{
|
||
|
private static readonly Dictionary<Collider2D, int> s_ColliderMap = new Dictionary<Collider2D, int>();
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
|
||
|
/// <summary>
|
||
|
/// 碰撞LayerMask
|
||
|
/// </summary>
|
||
|
/// <param name="faction">自己所在阵营</param>
|
||
|
/// <param name="collideWith">碰撞参数掩码,1-敌方,2-友方,4-建筑物</param>
|
||
|
/// <returns></returns>
|
||
|
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;
|
||
|
}
|
||
|
}
|
||
|
}
|