public static bool WorldRectInView(this Camera camera, Rect worldRect, float depth) { return worldRect.Intersects(camera.GetRect(depth)); }
/// <summary> /// Erases a rectangular area of the map. /// </summary> /// <param name="map">The reference to a <see cref="GridMap"/> type.</param> /// <param name="width">The width of the rectangle.</param> /// <param name="height">The height of the rectangle.</param> /// <param name="layer">The layer where drawing will occur.</param> /// <param name="left">The left position of the rectangle in grid co-ordinates.</param> /// <param name="top">The top position of the rectangle in grid co-ordinates.</param> /// <param name="callback">Provides a erase callback function that if returns true will allow the prefab to be erased. </param> /// <remarks>If <see cref="callback"/> is null the check is ignored and erasing is allowed.</remarks> public static void EraseFilledRectangle(this GridMap map, int layer, int left, int top, int width, int height, Func<int, int, int, GameObject, bool> callback) { var dimensions = new Rect(0, 0, map.Columns, map.Rows); var rect = new Rect(left, top, width, height); if (!dimensions.Intersects(rect)) { return; } var transform = map.transform; var i = 0; while (i < transform.childCount) { var child = transform.GetChild(i).gameObject; string name; int column; int row; int layerIndex; if (child.name.TryParsePrefabName(out name, out layerIndex, out column, out row)) { // check if name is within expected bounds if (layer != layerIndex || column < 0 || column > map.Columns - 1 || row < 0 || row > map.Rows - 1 || !rect.Contains(new UnityEngine.Vector2(column, row))) { i++; continue; } // check if there is a callback and if so call it for validation whether we can destroy the game object if (callback != null && !callback(column, row, layer, child.gameObject)) { continue; } #if UNITY_EDITOR Object.DestroyImmediate(child); #else Object.Destroy(child); #endif continue; } i++; } }
/// <summary> /// Draws a rectangular area of the map with a specified prefab. /// </summary> /// <param name="map">The reference to a <see cref="GridMap"/> type.</param> /// <param name="width">The width of the rectangle.</param> /// <param name="height">The height of the rectangle.</param> /// <param name="prefab">The prefab to be drawn. Specify null to erase.</param> /// <param name="layer">The layer where drawing will occur.</param> /// <param name="left">The left position of the rectangle in grid co-ordinates.</param> /// <param name="top">The top position of the rectangle in grid co-ordinates.</param> /// <param name="autoCenterPrefab">Determines whether or not to automatically center the prefab within the grid cell.</param> /// <param name="autoScalePrefab">If true the prefab will be automatically scaled to fit within the confines of the maps cell size.</param> /// <param name="callback">Provides a draw callback function that if returns true will allow the prefab to be drawn. </param> /// <remarks>If <see cref="callback"/> is null the check is ignored and drawing is allowed.</remarks> public static void DrawRectangle(this GridMap map, int layer, int left, int top, int width, int height, GameObject prefab, bool autoCenterPrefab, bool autoScalePrefab, Func<int, int, int, GameObject, bool> callback) { if (prefab == null) { throw new ArgumentNullException("prefab"); } var dimensions = new Rect(0, 0, map.Columns, map.Rows); var firstRun = true; if (!dimensions.Intersects(new Rect(left, top, width, height))) { return; } var material = prefab.renderer.sharedMaterial; var getClone = new Func<GameObject>(() => { var value = firstRun ? prefab : Helpers.PerformInstantiation(prefab); // clear material references before assigning new material value.renderer.material = null; value.renderer.sharedMaterial = material; return value; }); for (var rowIndex = 0; rowIndex < height; rowIndex++) { if (rowIndex + top < 0 || rowIndex + top > map.Rows - 1) { continue; } if (left < 0 || left > map.Columns - 1 && left + width - 1 < 0 || left + width - 1 > map.Columns - 1) { continue; } // left side var clonedObject = getClone(); firstRun = false; if (callback != null && !callback(left, rowIndex + top, layer, clonedObject)) { continue; } map.PositionPrefabOnMap(layer, left, rowIndex + top, clonedObject, autoCenterPrefab, autoScalePrefab); if (left != left + width - 1) { // right side clonedObject = getClone(); // clonedObject = firstRun ? prefab : Helpers.PerformInstantiation(prefab); if (callback != null && !callback(left + width - 1, rowIndex + top, layer, clonedObject)) { continue; } map.PositionPrefabOnMap(layer, left + width - 1, rowIndex + top, clonedObject, autoCenterPrefab, autoScalePrefab); } } if (left == left + width - 1) { return; } for (var columnIndex = 1; columnIndex < width - 1; columnIndex++) { if (columnIndex + left < 0 || columnIndex + left > map.Columns - 1) { continue; } if (top < 0 || top > map.Rows - 1 && top + height - 1 < 0 || top + height - 1 > map.Rows - 1) { continue; } // top side var clonedObject = getClone(); // var clonedObject = firstRun ? prefab : Helpers.PerformInstantiation(prefab); if (callback != null && !callback(columnIndex + left, top, layer, clonedObject)) { continue; } map.PositionPrefabOnMap(layer, columnIndex + left, top, clonedObject, autoCenterPrefab, autoScalePrefab); if (top != top + height - 1) { // bottom side clonedObject = getClone(); // clonedObject = firstRun ? prefab : Helpers.PerformInstantiation(prefab); if (callback != null && !callback(columnIndex + left, top + height - 1, layer, clonedObject)) { continue; } map.PositionPrefabOnMap(layer, columnIndex + left, top + height - 1, clonedObject, autoCenterPrefab, autoScalePrefab); } } }
/// <summary> /// Fills a rectangular area of the map with a specified prefab. /// </summary> /// <param name="map">The reference to a <see cref="GridMap"/> type.</param> /// <param name="width">The width of the rectangle.</param> /// <param name="height">The height of the rectangle.</param> /// <param name="prefab">The prefab to be drawn. Specify null to erase.</param> /// <param name="layer">The layer where drawing will occur.</param> /// <param name="left">The left position of the rectangle in grid co-ordinates.</param> /// <param name="top">The top position of the rectangle in grid co-ordinates.</param> /// <param name="autoCenterPrefab">Determines whether or not to automatically center the prefab within the grid cell.</param> /// <param name="autoScalePrefab">If true the prefab will be automatically scaled to fit within the confines of the maps cell size.</param> /// <param name="callback">Provides a draw callback function that if returns true will allow the prefab to be drawn. </param> /// <remarks>If <see cref="callback"/> is null the check is ignored and drawing is allowed.</remarks> public static void FillRectangle(this GridMap map, int layer, int left, int top, int width, int height, GameObject prefab, bool autoCenterPrefab, bool autoScalePrefab, Func<int, int, int, GameObject, bool> callback) { if (prefab == null) { throw new ArgumentNullException("prefab"); } var dimensions = new Rect(0, 0, map.Columns, map.Rows); var firstRun = true; if (!dimensions.Intersects(new Rect(left, top, width, height))) { return; } var material = prefab.renderer.sharedMaterial; var getClone = new Func<GameObject>(() => { var value = firstRun ? prefab : Helpers.PerformInstantiation(prefab); // clear material references before assigning new material value.renderer.material = null; value.renderer.sharedMaterial = material; return value; }); #if PERFORMANCE var perf = PerformanceTesting<PerformanceID>.Instance; perf.Start(PerformanceID.FillRectangleExtensionMethod); #endif for (var rowIndex = 0; rowIndex < height; rowIndex++) { if (rowIndex + top < 0 || rowIndex + top > map.Rows - 1) { continue; } for (var columnIndex = 0; columnIndex < width; columnIndex++) { if (columnIndex + left < 0 || columnIndex + left > map.Columns - 1) { continue; } #if PERFORMANCE perf.Start(PerformanceID.FillRectangleExtensionMethod_Instantiation); #endif var clonedObject = getClone(); #if PERFORMANCE perf.Stop(PerformanceID.FillRectangleExtensionMethod_Instantiation); #endif firstRun = false; #if PERFORMANCE perf.Start(PerformanceID.FillRectangleExtensionMethod_Callback); #endif if (callback != null && !callback(columnIndex + left, rowIndex + top, layer, clonedObject)) { #if PERFORMANCE perf.Stop(PerformanceID.FillRectangleExtensionMethod_Callback); #endif continue; } #if PERFORMANCE perf.Stop(PerformanceID.FillRectangleExtensionMethod_Callback); #endif map.PositionPrefabOnMap(layer, columnIndex + left, rowIndex + top, clonedObject, autoCenterPrefab, autoScalePrefab); } } #if PERFORMANCE perf.Stop(PerformanceID.FillRectangleExtensionMethod); #endif }
void Update() { CleanUp(); position = transform.position + offset; rect = new Rect(position.x - MaxRadius, position.y - MaxRadius, MaxRadius * 2, MaxRadius * 2); IsInView = Camera.main.WorldRectInView(rect); if (IsStatic) { if (HasChanged) { foreach (FogOfWar fogOfWar in FogsOfWar) { fogOfWar.UpdateFogOfWar = true; } } } else { foreach (FogOfWar fogOfWar in FogsOfWar) { Vector3 lastRelativePosition = RelativePositionsDict[fogOfWar]; Vector3 currentRelativePosition = fogOfWar.transform.position - position; RelativePositionsDict[fogOfWar] = currentRelativePosition; if (HasChanged || (lastRelativePosition != currentRelativePosition && rect.Intersects(fogOfWar.Area))) { fogOfWar.UpdateFogOfWar = true; } } } }