Пример #1
0
        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());
        }
Пример #2
0
        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());
        }