public static Entity[] ComputeStaticHitboxHitEntities(AbilityCastData castData, Vector3 hitBoxOrigin, ICollection <Entity> toIgnore = null) { AbilityHitboxData hParams = castData.AbilityCast.Hitbox; List <Entity> hitEntities = new List <Entity>(); List <float> hitEntitiesDst = new List <float>(); #region Detect all entities hit Collider[] entitiesHit = null; if (hParams.Type == HitboxType.Sphere) { entitiesHit = Physics.OverlapSphere(hitBoxOrigin, hParams.Radius, PinouApp.Resources.Data.Layers.Entities); } else if (hParams.Type == HitboxType.Box) { entitiesHit = Physics.OverlapBox(hitBoxOrigin, hParams.Size * 0.5f, Quaternion.Euler(hParams.Orientation), PinouApp.Resources.Data.Layers.Entities); } #endregion #region Sort entities //Sort allowed entities and store them foreach (Collider coll in entitiesHit) { Entity collMaster = coll.GetComponentInParent <Entity>(); if (hitEntities.Contains(collMaster) == false && (toIgnore == null || toIgnore.Contains(collMaster) == false) && CanPerformedAbilityHitEntity(castData, collMaster) == true) { float dst = Vector3.SqrMagnitude(collMaster.Position - hitBoxOrigin); if (hitEntities.Count == 0) { hitEntities.Add(collMaster); hitEntitiesDst.Add(dst); } else { //Order the hit entity directly by distance for (int i = hitEntities.Count - 1; i >= 0; i--) { if (dst > (hitEntitiesDst[i])) { hitEntities.Insert(i + 1, collMaster); hitEntitiesDst.Insert(i + 1, dst); break; } else if (i == 0) { hitEntities.Insert(0, collMaster); hitEntitiesDst.Insert(0, dst); break; } } } } } //Keep only nearest entities and right count if (hitEntities.Count > hParams.MaxTargetHit) { hitEntities.RemoveRange(hParams.MaxTargetHit, hitEntities.Count - hParams.MaxTargetHit); } #endregion return(hitEntities.ToArray()); }
public static (Entity[], AdditionalHitInfos[]) ComputeMovingHitboxHitEntities(AbilityCastData castData, Vector3 hitBoxOrigin, float speed = -1f, ICollection <Entity> toIgnore = null) { AbilityHitboxData hParams = castData.AbilityCast.Hitbox; List <Entity> hitEntities = new List <Entity>(); List <float> hitEntitiesDst = new List <float>(); List <AdditionalHitInfos> hitEntitiesInfos = new List <AdditionalHitInfos>(); Dictionary <Collider, AdditionalHitInfos> colliderHitInfos = new Dictionary <Collider, AdditionalHitInfos>(); if (speed <= 0f) { speed = hParams.MoveSpeed; } #region Detect all entities hit Collider[] entitiesHit = null; AdditionalHitInfos baseHitInfos = new AdditionalHitInfos(hitBoxOrigin, castData.CastDirection, speed * Time.fixedDeltaTime, default); #region Static Hitboxes #endregion #region Moving Hitboxes if (hParams.Type == HitboxType.Sphere) { RaycastHit[] hits = Physics.SphereCastAll( baseHitInfos.RayOrigin, hParams.Radius, baseHitInfos.RayDirection, baseHitInfos.Distance, PinouApp.Resources.Data.Layers.Entities); entitiesHit = new Collider[hits.Length]; for (int i = 0; i < hits.Length; i++) { entitiesHit[i] = hits[i].collider; colliderHitInfos.Add(hits[i].collider, baseHitInfos.CopyWithHit(hits[i])); } } else if (hParams.Type == HitboxType.Box) { RaycastHit[] hits = Physics.BoxCastAll( baseHitInfos.RayOrigin, hParams.Size * 0.5f, baseHitInfos.RayDirection, Quaternion.Euler(hParams.Orientation), baseHitInfos.Distance, PinouApp.Resources.Data.Layers.Entities); entitiesHit = new Collider[hits.Length]; for (int i = 0; i < hits.Length; i++) { entitiesHit[i] = hits[i].collider; colliderHitInfos.Add(hits[i].collider, baseHitInfos.CopyWithHit(hits[i])); } } #endregion #endregion #region Sort entities //Sort allowed entities and store them foreach (Collider coll in entitiesHit) { Entity collMaster = coll.GetComponentInParent <Entity>(); if (hitEntities.Contains(collMaster) == false && (toIgnore == null || toIgnore.Contains(collMaster) == false) && CanPerformedAbilityHitEntity(castData, collMaster) == true) { float dst = Vector3.SqrMagnitude(collMaster.Position - hitBoxOrigin); if (hitEntities.Count == 0) { hitEntities.Add(collMaster); hitEntitiesDst.Add(dst); hitEntitiesInfos.Add(colliderHitInfos[coll]); } else { //Order the hit entity directly by distance for (int i = hitEntities.Count - 1; i >= 0; i--) { if (dst > (hitEntitiesDst[i])) { hitEntities.Insert(i + 1, collMaster); hitEntitiesDst.Insert(i + 1, dst); hitEntitiesInfos.Add(colliderHitInfos[coll]); break; } else if (i == 0) { hitEntities.Insert(0, collMaster); hitEntitiesDst.Insert(0, dst); hitEntitiesInfos.Add(colliderHitInfos[coll]); break; } } } } } //Keep only nearest entities and right count if (hitEntities.Count > hParams.MaxTargetHit) { hitEntities.RemoveRange(hParams.MaxTargetHit, hitEntities.Count - hParams.MaxTargetHit); } #endregion return(hitEntities.ToArray(), hitEntitiesInfos.ToArray()); }