private static void FindAndAddPosibleTargetsToBuffer(FractionalHex position, Fix64 sightRange, ActTargetFilters filters, Team team, Dictionary <Hex, List <EntityOnVision> > unitsForeachHex, List <BuildingOnVision> buildingsOnSight, DynamicBuffer <BEPosibleTarget> buffer) { Hex roundedPosition = position.Round(); //buildings foreach (var building in buildingsOnSight) { var buildingHex = building.building.position; var reversedDirection = (position - (FractionalHex)buildingHex).NormalizedManhathan(); var fullHexTargetPos = FractionalHex.GetBorderPointOfTheHex(buildingHex, reversedDirection); var buildingPos = (FractionalHex)buildingHex; if (ValidPossibleTarget(position, sightRange, team.Number, filters, buildingPos, (Fix64)0.5, building.team)) { buffer.Add(new BEPosibleTarget() { Position = buildingPos, Radius = Fix64.Zero, Entity = building.entity, IsUnit = false, OccupiesFullHex = true, OccupyingHex = buildingHex, GatherTarget = false, ActTypeTarget = filters.actType }); } } //units var pointsOfHex = SpartialSortUtils.GetAllPointsAtRange(roundedPosition, (int)Fix64.Ceiling(sightRange), unitsForeachHex); foreach (var point in pointsOfHex) { int pointTeam = point.team; Entity pointEntity = point.entity; var pointRadius = point.collider.Radius; if (ValidPossibleTarget(position, sightRange, team.Number, filters, point.position, pointRadius, pointTeam)) { buffer.Add(new BEPosibleTarget() { Position = point.position, Radius = pointRadius, Entity = pointEntity, IsUnit = true, OccupiesFullHex = false, OccupyingHex = point.position.Round(), GatherTarget = false, ActTypeTarget = filters.actType }); } } }
protected override void OnUpdate() { var activeMap = MapManager.ActiveMap; if (activeMap == null) { Debug.LogError("Active map needed for the collision system"); return; } int colliderCount = m_ColliderEntityQuery.CalculateEntityCount(); var positions = new FractionalHex[colliderCount]; var collidersRadious = new Fix64[colliderCount]; var collidersLayers = new ColliderLayer[colliderCount]; var teams = new int[colliderCount]; var areActing = new bool[colliderCount]; //init the collections int collectionIndex = 0; Entities.ForEach((Entity entity, ref HexPosition hexPosition, ref Collider collider, ref Team team) => { var position = hexPosition.HexCoordinates; positions[collectionIndex] = position; collidersRadious[collectionIndex] = collider.Radius; collidersLayers[collectionIndex] = collider.Layer; teams[collectionIndex] = team.Number; if (EntityManager.HasComponent <IsActing>(entity)) { areActing[collectionIndex] = true; } else { areActing[collectionIndex] = false; } collectionIndex++; }); var pointsSorted = SpartialSortUtils.GetPointsSpartiallySorted(positions, 1); //collide Entities.ForEach((ref HexPosition hexPosition, ref Collider collider, ref Team team) => { if (!layerCollisionMatrix.TryGetValue(collider.Layer, out ColliderFlags colliderFlag)) { throw new System.Exception("Assign the collider layer type on the collision matrix!"); } else if (colliderFlag == ColliderFlags.NONE) { return; } FractionalHex position = hexPosition.HexCoordinates; //FractionalHex prevPos = hexPosition.PrevPosition; bool areHexOnCenter = activeMap.map.MovementMapValues.TryGetValue(position.Round(), out bool centerIsWalkable); bool centerOnWalkableHex = areHexOnCenter && centerIsWalkable; if (!centerOnWalkableHex) { FractionalHex closestOpenHex = (FractionalHex)MapUtilities.FindClosestOpenHex(position, activeMap.map, true); FractionalHex collisionResolutionDir = (closestOpenHex - position).NormalizedManhathan(); hexPosition.HexCoordinates = position + (collisionResolutionDir * collider.Radius); } else if (CollisionTestAgainstMap(collider.Radius, position, activeMap, out List <FractionalHex> collidingResponseVectors)) { var colisionIntensity = Fix64.Zero;; var colisionVectorSum = (FractionalHex)Hex.Zero; foreach (var vector in collidingResponseVectors) { if (vector.Lenght() > colisionIntensity) { colisionIntensity = vector.Lenght(); } colisionVectorSum += vector; } var direction = colisionVectorSum.NormalizedManhathan(); hexPosition.HexCoordinates = position + colisionVectorSum;//direction * colisionIntensity; } else //collide with other colliders { int thisIndex; var pointsToCheck = SpartialSortUtils.GetFilteredPoints(position, pointsSorted, out thisIndex); var collidableIndices = GetCollidableCollidersIndices(collider, pointsToCheck, collidersLayers); //SimpleCollisionCheckAndResponse(ref hexPosition, collider.Radious, positions, collidersRadious, teams, thisIndex, collidableIndices); //vamos a intentar una collision de dos pasos. DoubleStepCollision(ref hexPosition, collider.Radius, team, positions, collidersRadious, teams, areActing, thisIndex, collidableIndices); } }); }
protected override void OnUpdate() { List <EntityOnVision> unitsOnVisionTeam_0 = SightSystem.GetUnitsOnVisionOfTeam(0); List <EntityOnVision> unitsOnVisionTeam_1 = SightSystem.GetUnitsOnVisionOfTeam(1); List <EntityOnVision> unitsOnVisionTeam_2 = SightSystem.GetUnitsOnVisionOfTeam(2); List <EntityOnVision> unitsOnVisionTeam_3 = SightSystem.GetUnitsOnVisionOfTeam(3); List <EntityOnVision> unitsOnVisionTeam_4 = SightSystem.GetUnitsOnVisionOfTeam(4); List <EntityOnVision> unitsOnVisionTeam_5 = SightSystem.GetUnitsOnVisionOfTeam(5); List <EntityOnVision> unitsOnVisionTeam_6 = SightSystem.GetUnitsOnVisionOfTeam(6); List <EntityOnVision> unitsOnVisionTeam_7 = SightSystem.GetUnitsOnVisionOfTeam(7); var sortedByHex_UnitsOnVisionTeam_0 = SpartialSortUtils.GetHexToPointsDictionary(unitsOnVisionTeam_0); var sortedByHex_UnitsOnVisionTeam_1 = SpartialSortUtils.GetHexToPointsDictionary(unitsOnVisionTeam_1); var sortedByHex_UnitsOnVisionTeam_2 = SpartialSortUtils.GetHexToPointsDictionary(unitsOnVisionTeam_2); var sortedByHex_UnitsOnVisionTeam_3 = SpartialSortUtils.GetHexToPointsDictionary(unitsOnVisionTeam_3); var sortedByHex_UnitsOnVisionTeam_4 = SpartialSortUtils.GetHexToPointsDictionary(unitsOnVisionTeam_4); var sortedByHex_UnitsOnVisionTeam_5 = SpartialSortUtils.GetHexToPointsDictionary(unitsOnVisionTeam_5); var sortedByHex_UnitsOnVisionTeam_6 = SpartialSortUtils.GetHexToPointsDictionary(unitsOnVisionTeam_6); var sortedByHex_UnitsOnVisionTeam_7 = SpartialSortUtils.GetHexToPointsDictionary(unitsOnVisionTeam_7); var buildingsOnVisionTeam_0 = SightSystem.GetBuildingsOnVisionOfTeam(0); var buildingsOnVisionTeam_1 = SightSystem.GetBuildingsOnVisionOfTeam(1); var buildingsOnVisionTeam_2 = SightSystem.GetBuildingsOnVisionOfTeam(2); var buildingsOnVisionTeam_3 = SightSystem.GetBuildingsOnVisionOfTeam(3); var buildingsOnVisionTeam_4 = SightSystem.GetBuildingsOnVisionOfTeam(4); var buildingsOnVisionTeam_5 = SightSystem.GetBuildingsOnVisionOfTeam(5); var buildingsOnVisionTeam_6 = SightSystem.GetBuildingsOnVisionOfTeam(6); var buildingsOnVisionTeam_7 = SightSystem.GetBuildingsOnVisionOfTeam(7); //normal group entities. #region Group that targets entities on vision. Entities.WithAll <Group, BEPosibleTarget>().WithNone <GroupOnGather>().ForEach((Entity entity, ref HexPosition hexPosition, ref SightRange sightRange, ref GroupBehaviour behaviour, ref ActTargetFilters filters, ref Team team, ref MovementState movementState) => { var buffer = EntityManager.GetBuffer <BEPosibleTarget>(entity); buffer.Clear(); var sortedByHex_UnitsOnTeamVision = GetSortedUnitsOnTeamVision(team.Number, sortedByHex_UnitsOnVisionTeam_0, sortedByHex_UnitsOnVisionTeam_1, sortedByHex_UnitsOnVisionTeam_2, sortedByHex_UnitsOnVisionTeam_3, sortedByHex_UnitsOnVisionTeam_4, sortedByHex_UnitsOnVisionTeam_5, sortedByHex_UnitsOnVisionTeam_6, sortedByHex_UnitsOnVisionTeam_7); var buildingsOnTeamVision = GetBuildingOnTeamVision(team.Number, buildingsOnVisionTeam_0, buildingsOnVisionTeam_1, buildingsOnVisionTeam_2, buildingsOnVisionTeam_3, buildingsOnVisionTeam_4, buildingsOnVisionTeam_5, buildingsOnVisionTeam_6, buildingsOnVisionTeam_7); switch (behaviour.Value) { case Behaviour.PASSIVE: if (EntityManager.HasComponent <PriorityGroupTarget>(entity)) { PostUpdateCommands.RemoveComponent <PriorityGroupTarget>(entity); } if (!movementState.DestinationReached) { break; } FindAndAddPosibleTargetsToBuffer(hexPosition.HexCoordinates, sightRange.Value, filters, team, sortedByHex_UnitsOnTeamVision, buildingsOnTeamVision, buffer); break; case Behaviour.DEFAULT: if (EntityManager.HasComponent <PriorityGroupTarget>(entity)) { PostUpdateCommands.RemoveComponent <PriorityGroupTarget>(entity); } if (!movementState.DestinationReached) { break; } FindAndAddPosibleTargetsToBuffer(hexPosition.HexCoordinates, sightRange.Value, filters, team, sortedByHex_UnitsOnTeamVision, buildingsOnTeamVision, buffer); break; case Behaviour.AGRESIVE: //este modo agrega la entidad más cercana no bloqueada, como blanco prioritario. agrega a todas las entidades cercanas como posibles targets. PriorityGroupTarget priorityTarget; if (GetPriorityTargetAndAddPosibleTargets(out priorityTarget, hexPosition.HexCoordinates, sightRange.Value, team, filters, sortedByHex_UnitsOnTeamVision, buildingsOnTeamVision, buffer)) { // 1° if there isn´t a priorityTarget component we add one. if (!EntityManager.HasComponent <PriorityGroupTarget>(entity)) { PostUpdateCommands.AddComponent <PriorityGroupTarget>(entity, priorityTarget); } else { PostUpdateCommands.SetComponent <PriorityGroupTarget>(entity, priorityTarget); } } else { // 1° if there is a priorityTarget component we remove it. if (EntityManager.HasComponent <PriorityGroupTarget>(entity)) { PostUpdateCommands.RemoveComponent <PriorityGroupTarget>(entity); } } break; default: throw new System.NotImplementedException(); } }); #endregion #region Groups that are gathering Entities.WithAll <Group, BEPosibleTarget, BEResourceSource>().ForEach((Entity entity, ref GroupOnGather onGather, ref HexPosition hexPosition, ref SightRange sightRange, ref Team team, ref MovementState movementState) => { //UnityEngine.Debug.Log($"Group on gather. Entity: {entity.Index}. Gather resource: {onGather.GatheringResourceType}."); //Los targets son: todos los elementos del BEResourceSource + todos los elementos de los droppoints var posTargetBuffer = EntityManager.GetBuffer <BEPosibleTarget>(entity); posTargetBuffer.Clear(); if (!movementState.DestinationReached) { return; } var resSourceBuffer = EntityManager.GetBuffer <BEResourceSource>(entity); var allDropPointsOfTeam = DropPointSystem.GetAllDropPointsOfTeam(onGather.GatheringResourceType, team.Number); foreach (var resSource in resSourceBuffer) { if (resSource.currentGatherers >= resSource.maxGatherers) { continue; } var posTarget = new BEPosibleTarget() { Entity = resSource.entity, Position = (FractionalHex)resSource.position, Radius = Fix64.Zero, IsUnit = false, GatherTarget = true, IsResource = true, OccupiesFullHex = true, OccupyingHex = resSource.position, ActTypeTarget = ActType.GATHER, }; posTargetBuffer.Add(posTarget); } foreach (var dropPoint in allDropPointsOfTeam) { var posTarget = new BEPosibleTarget() { Entity = dropPoint.Value, Position = (FractionalHex)dropPoint.Key, Radius = Fix64.Zero, IsUnit = false, GatherTarget = true, IsResource = false, OccupiesFullHex = true, OccupyingHex = dropPoint.Key, ActTypeTarget = ActType.STORE }; posTargetBuffer.Add(posTarget); } }); #endregion }
/// <summary> /// Gets the target if true. /// debo ver una buena manera de conseguir el parent entity. /// </summary> private static bool GetPriorityTargetAndAddPosibleTargets(out PriorityGroupTarget target, FractionalHex position, Fix64 sightRange, Team team, ActTargetFilters filters, Dictionary <Hex, List <EntityOnVision> > unitsForeachHex, List <BuildingOnVision> buildingsOnSight, DynamicBuffer <BEPosibleTarget> buffer) { //no es lo más eficiente. Pero es más facil de mantener. FindAndAddPosibleTargetsToBuffer(position, sightRange, filters, team, unitsForeachHex, buildingsOnSight, buffer); Hex roundedPosition = position.Round(); var pointsOfHex = SpartialSortUtils.GetAllPointsAtRange(roundedPosition, (int)Fix64.Ceiling(sightRange), unitsForeachHex); target = new PriorityGroupTarget(); var bestTargetDistance = Fix64.MaxValue; bool arePrioriryTarget = false; bool areUnitPriorityTarget = false; //units firs because we search if there is a unit in sight and if so there cannot be a building as a priority target. foreach (var point in pointsOfHex) { int pointTeam = point.team; Entity pointEntity = point.entity; var pointLayer = point.collider.Layer; var pointRadius = point.collider.Radius; if (ValidPossibleTarget(position, sightRange, team.Number, filters, point.position, pointRadius, pointTeam)) { //buffer.Add(new BEPosibleTarget() //{ // Position = point.position, // Radius = pointRadius, // Entity = pointEntity, // IsUnit = true, // GatherTarget = false, // OccupiesFullHex = false, // ActTypeTarget = filters.actType //}); //hay que ver si hay algo que bloquea el paso if (MapUtilities.PathToPointIsClear(position, point.position)) { areUnitPriorityTarget = true; arePrioriryTarget = true; var distance = point.position.Distance(position); if (distance < bestTargetDistance) { bestTargetDistance = distance; target = new PriorityGroupTarget() { //TargetPosition = point.position, //TargetEntity = pointEntity, TargetHex = point.position.Round(), //IsUnit = true }; } } } } //buildings foreach (var building in buildingsOnSight) { var buildingPos = (FractionalHex)building.building.position; //if (ValidPossibleTarget(position, sightRange, team.Number, filters, buildingPos, (Fix64)0.5, building.team)) //{ // buffer.Add(new BEPosibleTarget() // { // Position = buildingPos, // Radius = Fix64.Zero, // Entity = building.entity, // IsUnit = false, // GatherTarget = false, // OccupiesFullHex = true, // ActTypeTarget = filters.actType // }); //} if (ValidPossibleTarget(position, sightRange, team.Number, filters, buildingPos, (Fix64)0.5, building.team)) { if (!areUnitPriorityTarget) { if (MapUtilities.PathToPointIsClear(position, buildingPos)) { arePrioriryTarget = true; var distance = buildingPos.Distance(position); if (distance < bestTargetDistance) { bestTargetDistance = distance; target = new PriorityGroupTarget() { //TargetPosition = buildingPos, //TargetEntity = building.entity, TargetHex = buildingPos.Round(), //IsUnit = false }; } } } } } return(arePrioriryTarget); }
protected override void OnUpdate() { int visionPointCount = m_VisionPointEntities.CalculateEntityCount(); VisionPointsForEachTeam = new Dictionary <int, List <VisionPoint> >(visionPointCount); int observableUnitCount = m_ObservableUnits.CalculateEntityCount(); UnitsOnVisionRangeOfTeams = new Dictionary <int, List <EntityOnVision> >(observableUnitCount); var positionsOfObservableUnits = new FractionalHex[observableUnitCount]; var teamsOfObservableUnits = new int[observableUnitCount]; var collidersOfObservableUnits = new Collider[observableUnitCount]; var entitiesOfObservableUnits = new Entity[observableUnitCount]; int observableBuildingCount = m_ObservableBuildings.CalculateEntityCount(); BuildingsOnVisionRangeOfTeams = new Dictionary <int, List <BuildingOnVision> >(observableBuildingCount); var observableBuildings = new Dictionary <Hex, BuildingOnVision>(observableBuildingCount); var obserbableSubstitutes = new Dictionary <Hex, Entity>(); var obserbableResources = new Dictionary <Hex, Entity>();//unico uso es para la visibilidad de monobehaviour. EntitiesOnVisionRangeOfTeamsHashset = new Dictionary <int, HashSet <Entity> >(observableUnitCount + observableBuildingCount); //INIT THE LISTS OF UNIT COMPONENTS int iteration = 0; Entities.WithNone <Group, HexTile, ExcludeFromSimulation>().ForEach((Entity entity, ref HexPosition position, ref Collider collider, ref Team team) => { positionsOfObservableUnits[iteration] = position.HexCoordinates; teamsOfObservableUnits[iteration] = team.Number; collidersOfObservableUnits[iteration] = collider; entitiesOfObservableUnits[iteration] = entity; iteration++; }); Entities.WithNone <Group, HexTile, ExcludeFromSimulation>().ForEach((Entity entity, ref Building building, ref Team team) => { Hex hex = building.position; if (observableBuildings.ContainsKey(hex)) { Debug.LogError($"In {hex} are more than 1 building."); } else { observableBuildings.Add(hex, new BuildingOnVision(entity, building, team)); } }); Entities.ForEach((Entity entity, ref Substitute substitute) => { if (obserbableSubstitutes.ContainsKey(substitute.position)) { Debug.LogError($"In {substitute.position} are more than 1 substitute. And the current sight system only supports 1 substitute per hex."); } else { obserbableSubstitutes.Add(substitute.position, entity); } }); Entities.ForEach((Entity entity, ref ResourceSource resource) => { if (obserbableResources.ContainsKey(resource.position)) { Debug.LogError($"In {resource.position} are more than 1 resource. And the current sight system only supports 1 resource per hex."); } else { obserbableResources.Add(resource.position, entity); } }); //WE GET THE OBSERVABLE UNITS SORTED BY THE HEX THAT THEY ARE STANDING ON var observablePointsSortedByHex = SpartialSortUtils.GetHexToPointsDictionary(positionsOfObservableUnits); //1- AGREGA LA ENTIDAD A LOS PUNTOS DE VISION DE SU EQUIPO Entities.WithNone <ExcludeFromSimulation>().ForEach((ref Building building, ref SightRange sightRange, ref Team team) => { var position = (FractionalHex)building.position; //ADD THE UNIT TO THE POINT OF VISION OF HIS TEAM. if (VisionPointsForEachTeam.TryGetValue(team.Number, out List <VisionPoint> listOfVisionPointsOfTeam)) { listOfVisionPointsOfTeam.Add(new VisionPoint(position, sightRange.Value)); VisionPointsForEachTeam[team.Number] = listOfVisionPointsOfTeam; } else { var newListOfVisionPointsOfTeam = new List <VisionPoint>() { new VisionPoint(position, sightRange.Value) }; VisionPointsForEachTeam.Add(team.Number, newListOfVisionPointsOfTeam); } }); Entities.WithNone <Group, ExcludeFromSimulation>().ForEach((ref HexPosition hexPosition, ref SightRange sightRange, ref Team team) => { var position = hexPosition.HexCoordinates; //ADD THE UNIT TO THE POINT OF VISION OF HIS TEAM. if (VisionPointsForEachTeam.TryGetValue(team.Number, out List <VisionPoint> listOfVisionPointsOfTeam)) { listOfVisionPointsOfTeam.Add(new VisionPoint(position, sightRange.Value)); VisionPointsForEachTeam[team.Number] = listOfVisionPointsOfTeam; } else { var newListOfVisionPointsOfTeam = new List <VisionPoint>() { new VisionPoint(position, sightRange.Value) }; VisionPointsForEachTeam.Add(team.Number, newListOfVisionPointsOfTeam); } }); // loopea por todas las ENTIDADES(unidades y estructuras) con sight range y luego en cada una revisa las ENTIDADES obserbables (dentro de los hexagonos de su vision) // y si es que estan en su rango de vision los agrega a unidades/buildings en vista y a la hashset de entidades. // hay que agragar que esto revisa por las estructuras a la vista. // -> llena la coleccion que es usada para la vision en la presentacion y las coleccione para la simulacion. Entities.WithNone <Group, HexTile, ExcludeFromSimulation>().WithAny <HexPosition, Building>().ForEach((Entity entity, ref SightRange sightRange, ref Team team) => { FractionalHex position; if (EntityManager.HasComponent <HexPosition>(entity)) { position = EntityManager.GetComponentData <HexPosition>(entity).HexCoordinates; } else { position = (FractionalHex)EntityManager.GetComponentData <Building>(entity).position; } //ACÁ SE REVISA 1 A 1 SI LA ENTIDAD ACTUAL VE ALGUNA DE LAS UNIDADES QUE ESTAN DENTRO DE LOS HEXAGONOS QUE VE. //BUILDINGS. int sightDistanceInHex = (int)Fix64.Ceiling(sightRange.Value); var allVisibleHexes = Hex.AllHexesInRange(position.Round(), sightDistanceInHex, true); foreach (var visHex in allVisibleHexes) { if (observableBuildings.ContainsKey(visHex)) { BuildingOnVision buildingComps = observableBuildings[visHex]; List <BuildingOnVision> buildingViewedByTeam; if (BuildingsOnVisionRangeOfTeams.TryGetValue(team.Number, out buildingViewedByTeam)) { if (!buildingViewedByTeam.Contains(buildingComps)) { buildingViewedByTeam.Add(buildingComps); BuildingsOnVisionRangeOfTeams[team.Number] = buildingViewedByTeam; } } else { var newBuildingViewedByTeam = new List <BuildingOnVision>() { buildingComps }; BuildingsOnVisionRangeOfTeams.Add(team.Number, newBuildingViewedByTeam); } //add to hash set. HashSet <Entity> entitiesOnSightOfTeamHashSet; if (EntitiesOnVisionRangeOfTeamsHashset.TryGetValue(team.Number, out entitiesOnSightOfTeamHashSet)) { if (!entitiesOnSightOfTeamHashSet.Contains(buildingComps.entity)) { entitiesOnSightOfTeamHashSet.Add(buildingComps.entity); EntitiesOnVisionRangeOfTeamsHashset[team.Number] = entitiesOnSightOfTeamHashSet; } } else { entitiesOnSightOfTeamHashSet = new HashSet <Entity>() { buildingComps.entity }; EntitiesOnVisionRangeOfTeamsHashset.Add(team.Number, entitiesOnSightOfTeamHashSet); } } //substitutes to hashset. if (obserbableSubstitutes.ContainsKey(visHex)) { var subsEntity = obserbableSubstitutes[visHex]; HashSet <Entity> entitiesOnSightOfTeamHashSet; if (EntitiesOnVisionRangeOfTeamsHashset.TryGetValue(team.Number, out entitiesOnSightOfTeamHashSet)) { if (!entitiesOnSightOfTeamHashSet.Contains(subsEntity)) { entitiesOnSightOfTeamHashSet.Add(subsEntity); EntitiesOnVisionRangeOfTeamsHashset[team.Number] = entitiesOnSightOfTeamHashSet; } } else { entitiesOnSightOfTeamHashSet = new HashSet <Entity>() { subsEntity }; EntitiesOnVisionRangeOfTeamsHashset.Add(team.Number, entitiesOnSightOfTeamHashSet); } } //resources to hashset if (obserbableResources.ContainsKey(visHex)) { var resEntity = obserbableResources[visHex]; HashSet <Entity> entitiesOnSightOfTeamHashSet; if (EntitiesOnVisionRangeOfTeamsHashset.TryGetValue(team.Number, out entitiesOnSightOfTeamHashSet)) { if (!entitiesOnSightOfTeamHashSet.Contains(resEntity)) { entitiesOnSightOfTeamHashSet.Add(resEntity); EntitiesOnVisionRangeOfTeamsHashset[team.Number] = entitiesOnSightOfTeamHashSet; } } else { entitiesOnSightOfTeamHashSet = new HashSet <Entity>() { resEntity }; EntitiesOnVisionRangeOfTeamsHashset.Add(team.Number, entitiesOnSightOfTeamHashSet); } } } //UNIDADES. var observablePointsOnRange = SpartialSortUtils.GetAllPointsAtRange(position.Round(), sightDistanceInHex, observablePointsSortedByHex); foreach (var point in observablePointsOnRange) { var positionOfPoint = point.position; int teamOfPoint = teamsOfObservableUnits[point.index]; Collider colliderOfPoint = collidersOfObservableUnits[point.index]; Fix64 radiusOfPoint = colliderOfPoint.Radius; Entity entityOfPoint = entitiesOfObservableUnits[point.index]; var distance = position.Distance(positionOfPoint); bool onSight = distance <= sightRange.Value + radiusOfPoint; if (onSight) { var pointToAdd = new EntityOnVision(entityOfPoint, colliderOfPoint, teamOfPoint, positionOfPoint); //add the entity on the list dictionary if it is not there already. List <EntityOnVision> entitiesOnSightOfTeam; if (UnitsOnVisionRangeOfTeams.TryGetValue(team.Number, out entitiesOnSightOfTeam)) { if (!entitiesOnSightOfTeam.Contains(pointToAdd)) { entitiesOnSightOfTeam.Add(pointToAdd); UnitsOnVisionRangeOfTeams[team.Number] = entitiesOnSightOfTeam; } } else { entitiesOnSightOfTeam = new List <EntityOnVision>() { pointToAdd }; UnitsOnVisionRangeOfTeams.Add(team.Number, entitiesOnSightOfTeam); } //Add the entity to the hash set dicionary if it is not there already. HashSet <Entity> entitiesOnSightOfTeamHashSet; if (EntitiesOnVisionRangeOfTeamsHashset.TryGetValue(team.Number, out entitiesOnSightOfTeamHashSet)) { if (!entitiesOnSightOfTeamHashSet.Contains(entityOfPoint)) { entitiesOnSightOfTeamHashSet.Add(entityOfPoint); EntitiesOnVisionRangeOfTeamsHashset[team.Number] = entitiesOnSightOfTeamHashSet; } } else { entitiesOnSightOfTeamHashSet = new HashSet <Entity>() { entityOfPoint }; EntitiesOnVisionRangeOfTeamsHashset.Add(team.Number, entitiesOnSightOfTeamHashSet); } } } }); }