예제 #1
0
    public Vector3 getVector(NeighbourPosition position)
    {
        switch (position)
        {
        case NeighbourPosition.Top:
            return(new Vector3(x, y + 1, z));

        case NeighbourPosition.Bottom:
            return(new Vector3(x, y - 1, z));

        case NeighbourPosition.Left:
            return(new Vector3(x - 1, y, z));

        case NeighbourPosition.Right:
            return(new Vector3(x + 1, y, z));

        case NeighbourPosition.Front:
            return(new Vector3(x, y, z + 1));

        case NeighbourPosition.Back:
            return(new Vector3(x, y, z - 1));

        default:
            return(new Vector3(x, y, z));
        }
    }
예제 #2
0
	HexInfo GetNeighbourByPosition(NeighbourPosition position, HexInfo ActualHex)
	{
		HexInfo retVal = null;

		switch (position)
		{
		case NeighbourPosition.Left:
			retVal = GetLeftNeighbour (ActualHex);
			break;
		case NeighbourPosition.UpLeft:
			retVal = GetUpLeftNeighbour (ActualHex);
			break;
		case NeighbourPosition.UpRight:
			retVal = GetUpRightNeighbour(ActualHex);
			break;
		case NeighbourPosition.Right:
			retVal = GetRightNeighbour (ActualHex);
			break;
		case NeighbourPosition.DownRight:
			retVal = GetDownRightNeighbour(ActualHex);
			break;
		case NeighbourPosition.DownLeft:
			retVal = GetDownLeftNeighbour (ActualHex);
			break;
		default:
			break;
		}

		return retVal;
	}
예제 #3
0
        /// <summary>
        /// Gets a edge bounds, i.e. a side of a grid 1 cell size wide.
        /// </summary>
        /// <param name="grid">The grid.</param>
        /// <param name="pos">The position.</param>
        /// <returns>The bounds representing a side of the grid.</returns>
        /// <exception cref="System.ArgumentException">Only direct neighbours, i.e. Left, Right, Top or Bottom are supported.</exception>
        public static Bounds GetEdge(this IGrid grid, NeighbourPosition pos)
        {
            Bounds edgeBounds = new Bounds();

            var min = grid.bounds.min;
            var max = grid.bounds.max;

            min.y = grid.origin.y;
            max.y = Mathf.Min(0.1f, max.y);

            //First we establish an origin based bounds on the appropriate side of the grid
            switch (pos)
            {
            case NeighbourPosition.Bottom:
            {
                max.z = min.z + grid.cellSize;
                edgeBounds.SetMinMax(min, max);

                return(edgeBounds);
            }

            case NeighbourPosition.Top:
            {
                min.z = max.z - grid.cellSize;
                edgeBounds.SetMinMax(min, max);

                return(edgeBounds);
            }

            case NeighbourPosition.Left:
            {
                max.x = min.x + grid.cellSize;
                edgeBounds.SetMinMax(min, max);

                return(edgeBounds);
            }

            case NeighbourPosition.Right:
            {
                min.x = max.x - grid.cellSize;
                edgeBounds.SetMinMax(min, max);

                return(edgeBounds);
            }

            default:
            {
                throw new ArgumentException("Only direct neighbours, i.e. Left, Right, Top or Bottom are supported.");
            }
            }
        }
예제 #4
0
파일: Cell.cs 프로젝트: rmcmrz/unity-rl
        /// <summary>
        /// Initializes a new instance of the <see cref="Cell"/> class.
        /// </summary>
        /// <param name="parent">The cell matrix that owns this cell.</param>
        /// <param name="position">The position.</param>
        /// <param name="matrixPosX">The matrix position x.</param>
        /// <param name="matrixPosZ">The matrix position z.</param>
        /// <param name="blocked">if set to <c>true</c> the cell will appear permanently blocked.</param>
        public Cell(CellMatrix parent, Vector3 position, int matrixPosX, int matrixPosZ, bool blocked)
        {
            Ensure.ArgumentNotNull(parent, "parent");

            this.position   = position;
            this.matrixPosX = matrixPosX;
            this.matrixPosZ = matrixPosZ;

            _parent             = parent;
            _permanentlyBlocked = blocked;

            _neighbours = NeighbourPosition.None;

            if (matrixPosX < (parent.columns - 1))
            {
                _neighbours |= NeighbourPosition.Right;

                if (matrixPosZ < (parent.rows - 1))
                {
                    _neighbours |= (NeighbourPosition.Top | NeighbourPosition.TopRight);
                }

                if (matrixPosZ > 0)
                {
                    _neighbours |= (NeighbourPosition.Bottom | NeighbourPosition.BottomRight);
                }
            }

            if (matrixPosX > 0)
            {
                _neighbours |= NeighbourPosition.Left;

                if (matrixPosZ < (parent.rows - 1))
                {
                    _neighbours |= (NeighbourPosition.Top | NeighbourPosition.TopLeft);
                }

                if (matrixPosZ > 0)
                {
                    _neighbours |= (NeighbourPosition.Bottom | NeighbourPosition.BottomLeft);
                }
            }
        }
예제 #5
0
파일: Cell.cs 프로젝트: forwolk/UnityApex
        /// <summary>
        /// Initializes a new instance of the <see cref="Cell"/> class.
        /// </summary>
        /// <param name="parent">The cell matrix that owns this cell.</param>
        /// <param name="position">The position.</param>
        /// <param name="matrixPosX">The matrix position x.</param>
        /// <param name="matrixPosZ">The matrix position z.</param>
        /// <param name="blocked">if set to <c>true</c> the cell will appear permanently blocked.</param>
        public Cell(CellMatrix parent, Vector3 position, int matrixPosX, int matrixPosZ, bool blocked)
        {
            Ensure.ArgumentNotNull(parent, "parent");

            this.position = position;
            this.matrixPosX = matrixPosX;
            this.matrixPosZ = matrixPosZ;

            _parent = parent;
            _permanentlyBlocked = blocked;

            _neighbours = NeighbourPosition.None;

            if (matrixPosX < (parent.columns - 1))
            {
                _neighbours |= NeighbourPosition.Right;

                if (matrixPosZ < (parent.rows - 1))
                {
                    _neighbours |= (NeighbourPosition.Top | NeighbourPosition.TopRight);
                }

                if (matrixPosZ > 0)
                {
                    _neighbours |= (NeighbourPosition.Bottom | NeighbourPosition.BottomRight);
                }
            }

            if (matrixPosX > 0)
            {
                _neighbours |= NeighbourPosition.Left;

                if (matrixPosZ < (parent.rows - 1))
                {
                    _neighbours |= (NeighbourPosition.Top | NeighbourPosition.TopLeft);
                }

                if (matrixPosZ > 0)
                {
                    _neighbours |= (NeighbourPosition.Bottom | NeighbourPosition.BottomLeft);
                }
            }
        }
예제 #6
0
 public PositionEstimationView(NeighbourPosition positionEstimation)
 {
     this.positionEstimation = positionEstimation;
 }
        private void UpdateCellHeightData(StandardCell reference, StandardCell neighbour, NeighbourPosition neighbourPos, float maxHeightDiff, float ledgeThreshold, bool testForPermanentBlock)
        {
            var heightSampler = GetHeightSampler();

            var dir = reference.GetDirectionTo(neighbour);
            var offsets = GetPerpendicularOffsets(dir.x, dir.z);
            var granularity = _matrix.granularity;
            var steps = _matrix.cellSize / granularity;

            var maxClimb = 0f;
            var maxDrop = 0f;

            for (int o = 0; o < 3; o++)
            {
                var samplePos = reference.position + offsets[o];
                var fromHeight = heightSampler.SampleHeight(samplePos, _matrix);

                var climbAccumulator = 0.0f;
                var dropAccumulator = 0.0f;

                for (int i = 0; i < steps; i++)
                {
                    samplePos.x += (dir.x * granularity);
                    samplePos.z += (dir.z * granularity);

                    var toHeight = heightSampler.SampleHeight(samplePos, _matrix);

                    var heightDiff = toHeight - fromHeight;
                    var absDiff = Mathf.Abs(heightDiff);

                    bool ledgeEncountered = absDiff < ledgeThreshold;

                    if (absDiff <= maxHeightDiff || ledgeEncountered)
                    {
                        if (climbAccumulator > maxClimb)
                        {
                            maxClimb = climbAccumulator;
                        }
                        else if (dropAccumulator > maxDrop)
                        {
                            maxDrop = dropAccumulator;
                        }

                        climbAccumulator = 0f;
                        dropAccumulator = 0f;
                    }
                    else if (heightDiff > 0f)
                    {
                        climbAccumulator += heightDiff;
                        if (dropAccumulator > maxDrop)
                        {
                            maxDrop = dropAccumulator;
                        }

                        dropAccumulator = 0f;
                    }
                    else if (heightDiff < 0f)
                    {
                        dropAccumulator += absDiff;
                        if (climbAccumulator > maxClimb)
                        {
                            maxClimb = climbAccumulator;
                        }

                        climbAccumulator = 0f;
                    }

                    fromHeight = toHeight;
                } /* end steps */

                maxClimb = Mathf.Max(climbAccumulator, maxClimb);
                maxDrop = Mathf.Max(dropAccumulator, maxDrop);
            }

            var refPos = reference.GetRelativePositionTo(neighbour);
            if (maxClimb > _maxClimbHeight || maxDrop > _maxDropHeight)
            {
                neighbour.heightBlockedFrom |= refPos;
            }

            if (maxClimb > _maxDropHeight || maxDrop > _maxClimbHeight)
            {
                reference.heightBlockedFrom |= neighbourPos;
            }

            reference.heightIntializedFrom |= neighbourPos;
            neighbour.heightIntializedFrom |= refPos;
        } /* end method */
예제 #8
0
        /// <summary>
        /// Gets a edge bounds, i.e. a side of a grid 1 cell size wide.
        /// </summary>
        /// <param name="grid">The grid.</param>
        /// <param name="pos">The position.</param>
        /// <returns>The bounds representing a side of the grid.</returns>
        /// <exception cref="System.ArgumentException">Only direct neighbours, i.e. Left, Right, Top or Bottom are supported.</exception>
        public static Bounds GetEdge(this IGrid grid, NeighbourPosition pos)
        {
            Bounds edgeBounds = new Bounds();

            var min = grid.bounds.min;
            var max = grid.bounds.max;
            min.y = grid.origin.y;
            max.y = Mathf.Min(0.1f, max.y);

            //First we establish an origin based bounds on the appropriate side of the grid
            switch (pos)
            {
                case NeighbourPosition.Bottom:
                {
                    max.z = min.z + grid.cellSize;
                    edgeBounds.SetMinMax(min, max);

                    return edgeBounds;
                }

                case NeighbourPosition.Top:
                {
                    min.z = max.z - grid.cellSize;
                    edgeBounds.SetMinMax(min, max);

                    return edgeBounds;
                }

                case NeighbourPosition.Left:
                {
                    max.x = min.x + grid.cellSize;
                    edgeBounds.SetMinMax(min, max);

                    return edgeBounds;
                }

                case NeighbourPosition.Right:
                {
                    min.x = max.x - grid.cellSize;
                    edgeBounds.SetMinMax(min, max);

                    return edgeBounds;
                }

                default:
                {
                    throw new ArgumentException("Only direct neighbours, i.e. Left, Right, Top or Bottom are supported.");
                }
            }
        }
예제 #9
0
        /// <summary>
        /// Connects the specified grid to its neighbour grid(s) using Connector Portals. Will only connect to initialized and enabled grids.
        /// </summary>
        /// <param name="grid">The grid.</param>
        /// <param name="pos">The position to connect with neighbours. Valid options are Top, Bottom, Left and Right</param>
        /// <returns>A list of portal components that represent the connections. If none are found the list will be empty.</returns>
        /// <exception cref="System.ArgumentException">
        /// Can only connect a grid component that has been initialized.
        /// or
        /// Only direct neighbours, i.e. Left, Right, Top or Bottom are supported.
        /// </exception>
        public static IList<GridPortalComponent> Connect(this GridComponent grid, NeighbourPosition pos)
        {
            if (grid.grid == null)
            {
                throw new ArgumentException("Can only connect a grid component that has been initialized.");
            }

            NeighbourPosition neighboursPos;
            Vector3 translation;
            Bounds explorerBounds;

            //First we establish an origin based bounds on the appropriate side of the grid to check for neighbour grids
            switch (pos)
            {
                case NeighbourPosition.Bottom:
                {
                    neighboursPos = NeighbourPosition.Top;
                    translation = new Vector3(0f, 0f, grid.cellSize);
                    explorerBounds = GetEdge(grid.grid, NeighbourPosition.Bottom).Translate(-translation);
                    break;
                }

                case NeighbourPosition.Top:
                {
                    neighboursPos = NeighbourPosition.Bottom;
                    translation = new Vector3(0f, 0f, -grid.cellSize);
                    explorerBounds = GetEdge(grid.grid, NeighbourPosition.Top).Translate(-translation);
                    break;
                }

                case NeighbourPosition.Left:
                {
                    neighboursPos = NeighbourPosition.Right;
                    translation = new Vector3(grid.cellSize, 0f, 0f);
                    explorerBounds = GetEdge(grid.grid, NeighbourPosition.Left).Translate(-translation);
                    break;
                }

                case NeighbourPosition.Right:
                {
                    neighboursPos = NeighbourPosition.Left;
                    translation = new Vector3(-grid.cellSize, 0f, 0f);
                    explorerBounds = GetEdge(grid.grid, NeighbourPosition.Right).Translate(-translation);
                    break;
                }

                default:
                {
                    throw new ArgumentException("Only direct neighbours, i.e. Left, Right, Top or Bottom are supported.");
                }
            }

            //Resize so the bounds are contained in the grid
            explorerBounds = explorerBounds.DeltaSize(-0.05f, 0f, -0.05f);

            var existingConnectors = GridManager.instance.GetAssociatedPortals(grid).Where(p => p.type == PortalType.Connector).ToArray();

            var portals = new List<GridPortalComponent>();
            var neighbours = GridManager.instance.GetGrids(explorerBounds);
            foreach (var n in neighbours)
            {
                //Make sure a connection is not already in place
                bool connect = true;
                for (int i = 0; i < existingConnectors.Length; i++)
                {
                    if (existingConnectors[i].Connects(grid.grid, n))
                    {
                        connect = false;
                        break;
                    }
                }

                if (connect)
                {
                    //Get the edge on the neighbour grid and find the intersection between it and this grid
                    var p1 = GetEdge(n, neighboursPos).DeltaSize(-0.05f, 0f, -0.05f);
                    p1 = p1.Intersection(explorerBounds);
                    var p2 = p1.Translate(translation);

                    //TODO: revise this once the PortalActionNoneComponent is gone or made a default for connectors
                    var portal = GridPortalComponent.Create<PortalActionNoneComponent>(grid.gameObject, PortalType.Connector, p1, p2);
                    portals.Add(portal);
                }
            }

            return portals;
        }
예제 #10
0
 bool IGridCell.isWalkableFrom(NeighbourPosition pos, AttributeMask mask)
 {
     return _parentPortal.IsUsableBy(mask);
 }
예제 #11
0
        /// <summary>
        /// Connects the specified grid to its neighbour grid(s) using Connector Portals. Will only connect to initialized and enabled grids.
        /// </summary>
        /// <param name="grid">The grid.</param>
        /// <param name="pos">The position to connect with neighbours. Valid options are Top, Bottom, Left and Right</param>
        /// <returns>A list of portal components that represent the connections. If none are found the list will be empty.</returns>
        /// <exception cref="System.ArgumentException">
        /// Can only connect a grid component that has been initialized.
        /// or
        /// Only direct neighbours, i.e. Left, Right, Top or Bottom are supported.
        /// </exception>
        public static IList <GridPortalComponent> Connect(this GridComponent grid, NeighbourPosition pos)
        {
            if (grid.grid == null)
            {
                throw new ArgumentException("Can only connect a grid component that has been initialized.");
            }

            NeighbourPosition neighboursPos;
            Vector3           translation;
            Bounds            explorerBounds;

            //First we establish an origin based bounds on the appropriate side of the grid to check for neighbour grids
            switch (pos)
            {
            case NeighbourPosition.Bottom:
            {
                neighboursPos  = NeighbourPosition.Top;
                translation    = new Vector3(0f, 0f, grid.cellSize);
                explorerBounds = GetEdge(grid.grid, NeighbourPosition.Bottom).Translate(-translation);
                break;
            }

            case NeighbourPosition.Top:
            {
                neighboursPos  = NeighbourPosition.Bottom;
                translation    = new Vector3(0f, 0f, -grid.cellSize);
                explorerBounds = GetEdge(grid.grid, NeighbourPosition.Top).Translate(-translation);
                break;
            }

            case NeighbourPosition.Left:
            {
                neighboursPos  = NeighbourPosition.Right;
                translation    = new Vector3(grid.cellSize, 0f, 0f);
                explorerBounds = GetEdge(grid.grid, NeighbourPosition.Left).Translate(-translation);
                break;
            }

            case NeighbourPosition.Right:
            {
                neighboursPos  = NeighbourPosition.Left;
                translation    = new Vector3(-grid.cellSize, 0f, 0f);
                explorerBounds = GetEdge(grid.grid, NeighbourPosition.Right).Translate(-translation);
                break;
            }

            default:
            {
                throw new ArgumentException("Only direct neighbours, i.e. Left, Right, Top or Bottom are supported.");
            }
            }

            //Resize so the bounds are contained in the grid
            explorerBounds = explorerBounds.DeltaSize(-0.05f, 0f, -0.05f);

            var existingConnectors = GridManager.instance.GetAssociatedPortals(grid).Where(p => p.type == PortalType.Connector).ToArray();

            var portals    = new List <GridPortalComponent>();
            var neighbours = GridManager.instance.GetGrids(explorerBounds);

            foreach (var n in neighbours)
            {
                //Make sure a connection is not already in place
                bool connect = true;
                for (int i = 0; i < existingConnectors.Length; i++)
                {
                    if (existingConnectors[i].Connects(grid.grid, n))
                    {
                        connect = false;
                        break;
                    }
                }

                if (connect)
                {
                    //Get the edge on the neighbour grid and find the intersection between it and this grid
                    var p1 = GetEdge(n, neighboursPos).DeltaSize(-0.05f, 0f, -0.05f);
                    p1 = p1.Intersection(explorerBounds);
                    var p2 = p1.Translate(translation);

                    //TODO: revise this once the PortalActionNoneComponent is gone or made a default for connectors
                    var portal = GridPortalComponent.Create <PortalActionNoneComponent>(grid.gameObject, PortalType.Connector, p1, p2);
                    portals.Add(portal);
                }
            }

            return(portals);
        }
예제 #12
0
        public CellCoordinates GetNeighbourCoordinates(Cell cell, Generation generation, NeighbourPosition position)
        {
            var maxRow    = generation.Rows - 1;
            var maxColumn = generation.Columns - 1;
            var row       = 0;
            var column    = 0;

            switch (position)
            {
            case NeighbourPosition.TopLeft:
                column = HandleOutOfBounds(cell.Coordinates.Column - 1, maxColumn);
                row    = HandleOutOfBounds(cell.Coordinates.Row - 1, maxRow);
                break;

            case NeighbourPosition.Top:
                column = cell.Coordinates.Column;
                row    = HandleOutOfBounds(cell.Coordinates.Row - 1, maxRow);
                break;

            case NeighbourPosition.TopRight:
                column = HandleOutOfBounds(cell.Coordinates.Column + 1, maxColumn);
                row    = HandleOutOfBounds(cell.Coordinates.Row - 1, maxRow);
                break;

            case NeighbourPosition.Right:
                column = HandleOutOfBounds(cell.Coordinates.Column + 1, maxColumn);
                row    = cell.Coordinates.Row;
                break;

            case NeighbourPosition.BottomRight:
                column = HandleOutOfBounds(cell.Coordinates.Column + 1, maxColumn);
                row    = HandleOutOfBounds(cell.Coordinates.Row + 1, maxRow);
                break;

            case NeighbourPosition.Bottom:
                column = cell.Coordinates.Column;
                row    = HandleOutOfBounds(cell.Coordinates.Row + 1, maxRow);
                break;

            case NeighbourPosition.BottomLeft:
                column = HandleOutOfBounds(cell.Coordinates.Column - 1, maxColumn);
                row    = HandleOutOfBounds(cell.Coordinates.Row + 1, maxRow);
                break;

            case NeighbourPosition.Left:
                row    = cell.Coordinates.Row;
                column = HandleOutOfBounds(cell.Coordinates.Column - 1, maxColumn);
                break;
            }

            return(new CellCoordinates(row, column));
        }
예제 #13
0
        private void UpdateCellHeightData(StandardCell reference, StandardCell neighbour, NeighbourPosition neighbourPos, float maxHeightDiff, float ledgeThreshold, bool testForPermanentBlock)
        {
            var heightSampler = GetHeightSampler();

            var dir         = reference.GetDirectionTo(neighbour);
            var offsets     = GetPerpendicularOffsets(dir.x, dir.z);
            var granularity = _matrix.granularity;
            var steps       = _matrix.cellSize / granularity;

            var maxClimb = 0f;
            var maxDrop  = 0f;

            for (int o = 0; o < 3; o++)
            {
                var samplePos  = reference.position + offsets[o];
                var fromHeight = heightSampler.SampleHeight(samplePos, _matrix);

                var climbAccumulator = 0.0f;
                var dropAccumulator  = 0.0f;

                for (int i = 0; i < steps; i++)
                {
                    samplePos.x += (dir.x * granularity);
                    samplePos.z += (dir.z * granularity);

                    var toHeight = heightSampler.SampleHeight(samplePos, _matrix);

                    var heightDiff = toHeight - fromHeight;
                    var absDiff    = Mathf.Abs(heightDiff);

                    bool ledgeEncountered = absDiff < ledgeThreshold;

                    if (absDiff <= maxHeightDiff || ledgeEncountered)
                    {
                        if (climbAccumulator > maxClimb)
                        {
                            maxClimb = climbAccumulator;
                        }
                        else if (dropAccumulator > maxDrop)
                        {
                            maxDrop = dropAccumulator;
                        }

                        climbAccumulator = 0f;
                        dropAccumulator  = 0f;
                    }
                    else if (heightDiff > 0f)
                    {
                        climbAccumulator += heightDiff;
                        if (dropAccumulator > maxDrop)
                        {
                            maxDrop = dropAccumulator;
                        }

                        dropAccumulator = 0f;
                    }
                    else if (heightDiff < 0f)
                    {
                        dropAccumulator += absDiff;
                        if (climbAccumulator > maxClimb)
                        {
                            maxClimb = climbAccumulator;
                        }

                        climbAccumulator = 0f;
                    }

                    fromHeight = toHeight;
                } /* end steps */

                maxClimb = Mathf.Max(climbAccumulator, maxClimb);
                maxDrop  = Mathf.Max(dropAccumulator, maxDrop);
            }

            var refPos = reference.GetRelativePositionTo(neighbour);

            if (maxClimb > _maxClimbHeight || maxDrop > _maxDropHeight)
            {
                neighbour.heightBlockedFrom |= refPos;
            }

            if (maxClimb > _maxDropHeight || maxDrop > _maxClimbHeight)
            {
                reference.heightBlockedFrom |= neighbourPos;
            }

            reference.heightIntializedFrom |= neighbourPos;
            neighbour.heightIntializedFrom |= refPos;
        } /* end method */