예제 #1
0
        /// <summary>
        /// Calculates the location in grid (Column/Row) of the vector position (X/Z).
        /// </summary>
        /// <param name="vector">
        /// The reference vector that is to be converted into grid location.
        /// </param>
        /// <returns>
        /// Returns a <see cref="Vector2"/> type representing the Column and Row where the mouse of positioned over.
        /// </returns>
        public Point GetGridPosition(Vector3 vector)
        {
#if PERFORMANCE
            var performance = PerformanceTesting<PerformanceID>.Instance;
            performance.Start(PerformanceID.GetGridPosition);
#endif

            // get reference to the grid map component
            var map = (GridMap)this.target;

            // calculate column and row location from mouse hit location
            var position = new Vector3(vector.X / map.CellWidth, map.transform.position.y, vector.Z / map.CellHeight);

            // round the numbers to the nearest whole number using 5 decimal place precision
            position = new Vector3((int)Math.Round(position.X, 5, MidpointRounding.ToEven), 0, (int)Math.Round(position.Z, 5, MidpointRounding.ToEven));

            // do a check to ensure that the row and column are with the bounds of the grid map         
            var col = (int)position.X;
            var row = (int)position.Z;
            row = row < 0 ? 0 : row;
            row = row > map.Rows - 1 ? map.Rows - 1 : row;
            col = col < 0 ? 0 : col;
            col = col > map.Columns - 1 ? map.Columns - 1 : col;

#if PERFORMANCE
            performance.Stop(PerformanceID.GetGridPosition);
#endif
            // return the column and row values
            return new Point(col, row);
        }
예제 #2
0
        /// <summary>
        /// Calculates the position of the mouse over the grid map in local space coordinates.
        /// </summary>
        /// <returns>Returns true if the mouse is over the grid map.</returns>
        private bool UpdateHitPosition()
        {
            // get reference to the grid map component
            var map = (GridMap)this.target;

            // build a plane object that 
            // rotate up the same as map rotation
            var directionVector = Vector3.MoveTowards(Vector3.Up, map.transform.up, 1);
            directionVector.Normalize();
            directionVector *= this.ActiveLayer * map.Depth;

            var p = new Plane(map.transform.up, map.transform.position + directionVector);

            // build a ray type from the current mouse position
            var ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);

            // stores the hit location
            var hit = new Vector3();

            // stores the distance to the hit location
            float dist;

            // cast a ray to determine what location it intersects with the plane
            if (p.Raycast(ray, out dist))
            {
                // the ray hits the plane so we calculate the hit location in world space
                hit = ray.origin + (ray.direction.normalized * dist);
            }

            // convert the hit location from world space to local space
            var value = map.transform.InverseTransformPoint(hit);

            var changed = value != this.mouseHitPosition;
            this.mouseHitPosition = value;

            // return true indicating a successful hit test
            return changed;
        }
        /// <summary>
        /// positions a prefab on the map.
        /// </summary>
        /// <param name="map">The reference to a <see cref="GridMap"/> type.</param>
        /// <param name="row">The row where the prefab will be placed.</param>
        /// <param name="prefab">The prefab to be placed. </param>
        /// <param name="layer">The layer where placement will occur.</param>
        /// <param name="column">The column where the prefab will be placed.</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>
        public static void PositionPrefabOnMap(this GridMap map, int layer, int column, int row, GameObject prefab, bool autoCenterPrefab, bool autoScalePrefab)
        {
            if (prefab == null)
            {
                throw new ArgumentNullException("prefab");
            }

#if PERFORMANCE
            var perf = PerformanceTesting<PerformanceID>.Instance;
            perf.Start(PerformanceID.PositionPrefabOnMapExtensionMethod);
#endif

            var transform = prefab.transform;
            var bounds = new Bounds();
            if (autoScalePrefab)
            {
                // map.ScalePrefab(prefab);

#if PERFORMANCE
                perf.Start(PerformanceID.PositionPrefabOnMap_ScalePrefab);
#endif
                // get bounds of the prefab
                var encapsulate = false;
                if (Utilities.Helpers.GetBoundWithChildren(transform, ref bounds, ref encapsulate))
                {
                    // apply scaling to the prefab
                    var scale = transform.localScale;

                    // set x/z scale
                    scale.x *= map.CellWidth / bounds.size.x;
                    scale.z *= map.CellHeight / bounds.size.z;
                    //  scale.y *= (map.Depth / bounds.size.y) * (scale.x / scale.z);

                    // check for infinity values and if found set to 0
                    scale.x = float.IsInfinity(scale.x) ? 0 : scale.x;
                    scale.y = float.IsInfinity(scale.y) ? 0 : scale.y;
                    scale.z = float.IsInfinity(scale.z) ? 0 : scale.z;

                    scale.x = float.IsNaN(scale.x) ? 1 : scale.x;
                    scale.y = float.IsNaN(scale.y) ? 1 : scale.y;
                    scale.z = float.IsNaN(scale.z) ? 1 : scale.z;

                    // set scale
                    transform.localScale = scale;

#if PERFORMANCE
                    perf.Stop(PerformanceID.PositionPrefabOnMap_ScalePrefab);
#endif
                }
            }

#if PERFORMANCE
            perf.Start(PerformanceID.PositionPrefabOnMap_SetParent);
#endif
            transform.parent = map.transform;
#if PERFORMANCE
            perf.Stop(PerformanceID.PositionPrefabOnMap_SetParent);
#endif

#if PERFORMANCE
            perf.Start(PerformanceID.PositionPrefabOnMap_Rotate);
#endif
            // get maps rotation
            UnityEngine.Vector3 axis;
            float angle;
            map.transform.rotation.ToAngleAxis(out angle, out axis);
            // apply maps rotation to the prefab so the prefab is rotated along with the map
            transform.Rotate(axis, angle, Space.World);
#if PERFORMANCE
            perf.Stop(PerformanceID.PositionPrefabOnMap_Rotate);
#endif

            var gridPositionInLocalSpace = Vector3.Zero;
            if (autoCenterPrefab)
            {
#if PERFORMANCE
                perf.Start(PerformanceID.PositionPrefabOnMap_AutoCenter);
#endif
                // ensure prefab is perfectly centered in the middle of the grid cell based on it's render bounds
                var encapsulate = false;

                // zero out the prefab's position
                transform.position = Vector3.Zero;

                // get rendering bounds for the prefab if not already done so
                Utilities.Helpers.GetBoundWithChildren(transform, ref bounds, ref encapsulate);

                gridPositionInLocalSpace = new Vector3(
                     (column * map.CellWidth) + (map.CellWidth / 2) - bounds.center.x,
                     (layer * map.Depth) - bounds.center.y,
                     (row * map.CellHeight) + (map.CellHeight / 2) - bounds.center.z);

#if PERFORMANCE
                perf.Stop(PerformanceID.PositionPrefabOnMap_AutoCenter);
#endif
            }
            else
            {
                // set the prefabs position in the center of the grid cell not taking into account it's render bounds
                gridPositionInLocalSpace = new Vector3(
                    (column * map.CellWidth) + (map.CellWidth / 2),
                    layer * map.Depth,
                    (row * map.CellHeight) + (map.CellHeight / 2));
            }

            // set the prefabs transform position
#if PERFORMANCE
            perf.Start(PerformanceID.PositionPrefabOnMap_SetPosition);
#endif
            transform.localPosition = gridPositionInLocalSpace;
#if PERFORMANCE
            perf.Stop(PerformanceID.PositionPrefabOnMap_SetPosition);
#endif

#if PERFORMANCE
            perf.Stop(PerformanceID.PositionPrefabOnMapExtensionMethod);
#endif
        }
예제 #4
0
        /// <summary>
        /// Recalculates the position of the marker based on the location of the mouse pointer.
        /// </summary>
        private void RecalculateHighlightPosition()
        {
#if PERFORMANCE
            var performance = PerformanceTesting<PerformanceID>.Instance;
            performance.Start(PerformanceID.RecalculateHighlightPosition);
#endif

            // get reference to the grid map component
            var map = (GridMap)this.target;

            // store the grid location (Column/Row) based on the current location of the mouse pointer
            var gridPosition = this.GetGridPosition(this.mouseHitPosition);

            // store the grid position in local space
            var position = new Vector3(gridPosition.X * map.CellWidth, 0, gridPosition.Y * map.CellHeight);

            // set the highlightPosition value
            this.highlightPosition = new Vector3(
                                         position.X + (map.CellWidth / 2),
                                         this.ActiveLayer * map.Depth,
                                         position.Z + (map.CellHeight / 2));

#if PERFORMANCE
            performance.Stop(PerformanceID.RecalculateHighlightPosition);
#endif
        }
예제 #5
0
        /// <summary>
        /// positions a prefab on the map.
        /// </summary>
        /// <param name="map">The reference to a <see cref="GridMap"/> type.</param>
        /// <param name="row">The row where the prefab will be placed.</param>
        /// <param name="prefab">The prefab to be placed. </param>
        /// <param name="layer">The layer where placement will occur.</param>
        /// <param name="column">The column where the prefab will be placed.</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>
        public static void PositionPrefabOnMap(this GridMap map, int layer, int column, int row, GameObject prefab, bool autoCenterPrefab, bool autoScalePrefab)
        {
            if (prefab == null)
            {
                throw new ArgumentNullException("prefab");
            }

#if PERFORMANCE
            var perf = PerformanceTesting <PerformanceID> .Instance;
            perf.Start(PerformanceID.PositionPrefabOnMapExtensionMethod);
#endif

            var transform = prefab.transform;
            var bounds    = new Bounds();
            if (autoScalePrefab)
            {
                // map.ScalePrefab(prefab);

#if PERFORMANCE
                perf.Start(PerformanceID.PositionPrefabOnMap_ScalePrefab);
#endif
                // get bounds of the prefab
                var encapsulate = false;
                if (Utilities.Helpers.GetBoundWithChildren(transform, ref bounds, ref encapsulate))
                {
                    // apply scaling to the prefab
                    var scale = transform.localScale;

                    // set x/z scale
                    scale.x *= map.CellWidth / bounds.size.x;
                    scale.z *= map.CellHeight / bounds.size.z;
                    //  scale.y *= (map.Depth / bounds.size.y) * (scale.x / scale.z);

                    // check for infinity values and if found set to 0
                    scale.x = float.IsInfinity(scale.x) ? 0 : scale.x;
                    scale.y = float.IsInfinity(scale.y) ? 0 : scale.y;
                    scale.z = float.IsInfinity(scale.z) ? 0 : scale.z;

                    scale.x = float.IsNaN(scale.x) ? 1 : scale.x;
                    scale.y = float.IsNaN(scale.y) ? 1 : scale.y;
                    scale.z = float.IsNaN(scale.z) ? 1 : scale.z;

                    // set scale
                    transform.localScale = scale;

#if PERFORMANCE
                    perf.Stop(PerformanceID.PositionPrefabOnMap_ScalePrefab);
#endif
                }
            }

#if PERFORMANCE
            perf.Start(PerformanceID.PositionPrefabOnMap_SetParent);
#endif
            transform.parent = map.transform;
#if PERFORMANCE
            perf.Stop(PerformanceID.PositionPrefabOnMap_SetParent);
#endif

#if PERFORMANCE
            perf.Start(PerformanceID.PositionPrefabOnMap_Rotate);
#endif
            // get maps rotation
            UnityEngine.Vector3 axis;
            float angle;
            map.transform.rotation.ToAngleAxis(out angle, out axis);
            // apply maps rotation to the prefab so the prefab is rotated along with the map
            transform.Rotate(axis, angle, Space.World);
#if PERFORMANCE
            perf.Stop(PerformanceID.PositionPrefabOnMap_Rotate);
#endif

            var gridPositionInLocalSpace = Vector3.Zero;
            if (autoCenterPrefab)
            {
#if PERFORMANCE
                perf.Start(PerformanceID.PositionPrefabOnMap_AutoCenter);
#endif
                // ensure prefab is perfectly centered in the middle of the grid cell based on it's render bounds
                var encapsulate = false;

                // zero out the prefab's position
                transform.position = Vector3.Zero;

                // get rendering bounds for the prefab if not already done so
                Utilities.Helpers.GetBoundWithChildren(transform, ref bounds, ref encapsulate);

                gridPositionInLocalSpace = new Vector3(
                    (column * map.CellWidth) + (map.CellWidth / 2) - bounds.center.x,
                    (layer * map.Depth) - bounds.center.y,
                    (row * map.CellHeight) + (map.CellHeight / 2) - bounds.center.z);

#if PERFORMANCE
                perf.Stop(PerformanceID.PositionPrefabOnMap_AutoCenter);
#endif
            }
            else
            {
                // set the prefabs position in the center of the grid cell not taking into account it's render bounds
                gridPositionInLocalSpace = new Vector3(
                    (column * map.CellWidth) + (map.CellWidth / 2),
                    layer * map.Depth,
                    (row * map.CellHeight) + (map.CellHeight / 2));
            }

            // set the prefabs transform position
#if PERFORMANCE
            perf.Start(PerformanceID.PositionPrefabOnMap_SetPosition);
#endif
            transform.localPosition = gridPositionInLocalSpace;
#if PERFORMANCE
            perf.Stop(PerformanceID.PositionPrefabOnMap_SetPosition);
#endif

#if PERFORMANCE
            perf.Stop(PerformanceID.PositionPrefabOnMapExtensionMethod);
#endif
        }