protected override void OnUpdate() { MultiHashMap.Clear(); // need to be cleared because it is persistent // adjust its size to match the current needs int entityNumber = _query.CalculateLength(); if (entityNumber > MultiHashMap.Capacity) { MultiHashMap.Capacity = entityNumber; } var setQuadrantDataHashMapJob = new SetQuadrantHashMapDataJob { NativeMultiHashMap = MultiHashMap.ToConcurrent() }; JobHandle jobHandle = JobForEachExtensions.Schedule(setQuadrantDataHashMapJob, _query); jobHandle.Complete(); // === DEBUG DRAW === // draw quadrants around the player's if (Debug.isDebugBuild && GameEngine.Instance.DrawCollisionQuadrants) { float posX = GameEngine.SpaceshipInstance.transform.position.x; float posY = GameEngine.SpaceshipInstance.transform.position.y; for (int i = -1; i <= 1; i++) { for (int y = -1; y <= 1; y++) { DebugDrawMethods.DebugDrawQuadrant(posX + i * QuadrantCellSize, posY + y * QuadrantCellSize, Color.yellow); } } Debug.Log(GetEntityCountInHashMap(MultiHashMap, GetPositionHashMapKey(Utils.GetMouseWorldPosition()))); } }
protected override void OnUpdate() { Entities .WithAllReadOnly <Translation, CollisionTypeData>() .WithNone <TimeToRespawnData>() .ForEach((Entity entity, ref Translation translation, ref CollisionTypeData collisionType) => { int hashMapKey = QuadrantSystem.GetPositionHashMapKey(translation.Value); // check in this quadrant if (CheckInQuadrant(ref entity, translation, collisionType, hashMapKey)) { return; } // this will be used for the diagonal checks bool left = false, right = false, top = false, bottom = false; // check in neighboring quadrant if necessary QuadrantSystem.RetrieveComponentsFromHashMapKey(hashMapKey, out int xComponent, out int yComponent); float leftBorder = xComponent * QuadrantSystem.QuadrantCellSize; if (Mathf.Abs(translation.Value.x - leftBorder) < GetEntityRadius(collisionType.CollisionObjectType)) { left = true; if (CheckInQuadrant(ref entity, translation, collisionType, xComponent - 1 + yComponent * QuadrantSystem.QuadrantMultiplier)) { return; } } float rightBorder = (xComponent + 1) * QuadrantSystem.QuadrantCellSize; if (Mathf.Abs(translation.Value.x - rightBorder) < GetEntityRadius(collisionType.CollisionObjectType)) { right = true; if (CheckInQuadrant(ref entity, translation, collisionType, xComponent + 1 + yComponent * QuadrantSystem.QuadrantMultiplier)) { return; } } float topBorder = (yComponent + 1) * QuadrantSystem.QuadrantCellSize; if (Mathf.Abs(translation.Value.y - topBorder) < GetEntityRadius(collisionType.CollisionObjectType)) { top = true; if (CheckInQuadrant(ref entity, translation, collisionType, xComponent + (yComponent + 1) * QuadrantSystem.QuadrantMultiplier)) { return; } } float bottomBorder = yComponent * QuadrantSystem.QuadrantCellSize; if (Mathf.Abs(translation.Value.y - bottomBorder) < GetEntityRadius(collisionType.CollisionObjectType)) { bottom = true; if (CheckInQuadrant(ref entity, translation, collisionType, xComponent + (yComponent - 1) * QuadrantSystem.QuadrantMultiplier)) { return; } } // check diagonal possibilities if (top && left) { if (CheckInQuadrant(ref entity, translation, collisionType, xComponent - 1 + (yComponent + 1) * QuadrantSystem.QuadrantMultiplier)) { return; } } if (top && right) { if (CheckInQuadrant(ref entity, translation, collisionType, xComponent + 1 + (yComponent + 1) * QuadrantSystem.QuadrantMultiplier)) { return; } } if (bottom && left) { if (CheckInQuadrant(ref entity, translation, collisionType, xComponent - 1 + (yComponent - 1) * QuadrantSystem.QuadrantMultiplier)) { return; } } if (bottom && right) { if (CheckInQuadrant(ref entity, translation, collisionType, xComponent + 1 + (yComponent - 1) * QuadrantSystem.QuadrantMultiplier)) { return; } } // === DEBUG DRAW === // draw sphere around entities around the player's // surprisingly there is no way to draw a circle but sphere will do // is DebugBuild can only be called from the main thread as well as Gizmo.DrawSpheare if (Debug.isDebugBuild && GameEngine.Instance.DrawEntityCollisionBorders) { DebugDrawMethods.DebugDrawCircle(translation.Value.x, translation.Value.y, GetEntityRadius(collisionType.CollisionObjectType), Color.red); } }); }