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