예제 #1
0
    /// <summary>
    /// Recursively travel up the 'parent' chain and construct a list of integer coordinates that form a path.
    /// </summary>
    /// <param name="endCell">End of path</param>
    /// <param name="startCell">Start of path</param>
    /// <returns>A list of integer axial coordinate arrays that form a path</returns>
    private List <int[]> ReconstructPath(PathCell endCell, PathCell startCell)
    {
        //Create the return list
        List <int[]> returnList = new List <int[]>();

        //If the end cell is the same as the start cell, return an empty list (no path)
        if (endCell.Equals(startCell))
        {
            return(returnList);
        }
        //Create a temporary cell
        PathCell temp = endCell;

        do
        {
            //Add temp to the return list
            returnList.Add(new int[] { temp.q, temp.r, temp.h });
            //Set temp to it's parent
            temp = temp.parent;
            //repeat

            //Loop while temp has not been set to the start cell
        } while (!temp.Equals(startCell));
        //Finally, add the start cell to the list and return the path
        returnList.Add(new int[] { startCell.q, startCell.r, startCell.h });
        return(returnList);
    }
예제 #2
0
    /// <summary>
    /// Update the UI for player movement and item usage
    /// </summary>
    /// <returns>Returns true when movement has happened</returns>
    public bool MovePlayer()
    {
        //Check to see if the player is standing on a hex; if so show all valid moves on the minimap.
        //If the player is standing on a hex (not falling, jumping)
        if (levelController[q, r, h] != null)
        {
            //Get the neighbors of the current hex
            movable = aiController.ReachableInSteps(new int[] { q, r, h }, 2, actionPoints);
            //Give all valid neighbors the neighbor material
            uiController.ShowValidMoves(movable);
            //Give the current hex the current hex material
            uiController[q, r, h].gameObject.GetComponent <Renderer>().material = currenthexmaterial;
        }
        //Non VR Movement
        if (!vrActive)
        {
            //Get the cell the player is looking at
            Vector3    lineOfSight = playerCamera.transform.forward * 1000;
            RaycastHit hit;
            UICellObj  hitObj = null;
            if (Physics.Raycast(playerCamera.transform.position, lineOfSight, out hit))
            {
                //Get the UI hex cell the player is looking at
                hitObj = hit.transform.gameObject.GetComponent <UICellObj>() as UICellObj;
            }
            //if it isn't null
            if (hitObj != null)
            {
                //get the selected cell
                PathCell lookedCell = aiController[hitObj.q, hitObj.r, hitObj.h];
                PathCell startCell  = aiController[q, r, h];

                //loop through all cells we're close enough to reach
                for (int i = 0; i < movable.Count; i++)
                {
                    foreach (PathCell m in movable[i])
                    {
                        if (lookedCell.Equals(m) && !lookedCell.Equals(startCell))
                        {
                            //set the material
                            hitObj.gameObject.GetComponent <Renderer>().material = highlightMaterial;
                            //If the player clicked the mouse
                            if (Input.GetMouseButtonUp(0))
                            {
                                //Move the player
                                transform.parent.transform.position = levelController[hitObj.q, hitObj.r, hitObj.h].centerPos;
                                //If the target has a goal
                                if (levelController[hitObj.q, hitObj.r, hitObj.h].hasGoal)
                                {
                                    //Update the goal
                                    levelController.numOfGoals -= 1;
                                    levelController[hitObj.q, hitObj.r, hitObj.h].goal.GetComponent <Goal>().Accomplished();
                                }
                                //Reduce number of player action points remaining
                                actionPoints -= i + 1;
                                //Clear the UI controller
                                uiController.ClearCells();
                                uiController.setVisibility(false);
                                return(true);
                            }
                        }
                    }
                }
            }
            //VR Specific movement
        }
        else
        {
            if (vrMoveComplete)
            {
                vrMoveComplete = false;
                return(true);
            }
        }
        //Movement not finished
        return(false);
    }
예제 #3
0
    /// <summary>
    /// A basic implementation of A*
    /// </summary>
    /// <param name="startCoords">start hex coordinate array</param>
    /// <param name="endCoords">end hex coordinate array</param>
    /// <returns>A list of hex coordinates that form a path.  Null if no path possible</returns>
    public List <int[]> PathBetween(int[] startCoords, int[] endCoords)
    {
        //Get references to the start and end path objects
        PathCell cStart = pathGrid[startCoords[0], startCoords[1], startCoords[2]];
        PathCell cEnd   = pathGrid[endCoords[0], endCoords[1], endCoords[2]];

        //If the start is the end, there is no path
        if (cStart == null || cEnd == null)
        {
            return(null);
        }

        //Initialize the open and closed sets.  Sets instead of lists because they need to be unique.
        HashSet <PathCell> closed = new HashSet <PathCell>();
        HashSet <PathCell> open   = new HashSet <PathCell>();

        //Initialize the start node's values
        cStart.g = DistBetween(cStart, cEnd);
        open.Add(cStart);

        //While items exist in the open set
        while (open.Count > 0)
        {
            //Get the lowest g-valued cell;
            PathCell cCell = null;
            foreach (PathCell cell in open)
            {
                if (cCell == null)
                {
                    cCell = cell; continue;
                }
                if (cCell.g > cell.g)
                {
                    cCell = cell;
                }
            }
            //If the current cell is the goal, return the found path
            if (cCell.Equals(cEnd))
            {
                return(ReconstructPath(cCell, cStart));
            }

            //Remove cCell from open and add it to closed
            open.Remove(cCell);
            closed.Add(cCell);

            //Loop through the valid neighbors of cCell
            foreach (PathCell nCell in ValidNeighbors(cCell))
            {
                //If the neighbor node is already in the closed set, don't evaluate
                if (closed.Contains(nCell))
                {
                    continue;
                }

                //If the neighbor isn't in the open set
                if (!open.Contains(nCell))
                {
                    //Initialize it's g-value and parent
                    nCell.g      = cCell.g + DistBetween(cCell, nCell);
                    nCell.parent = cCell;
                    //Add it to the open set
                    open.Add(nCell);
                    //Neighbor is already in the open set
                }
                else
                {
                    //If moving from the cCell would be quicker than the current saved path
                    if (nCell.g > cCell.g + DistBetween(cCell, nCell))
                    {
                        //Override previous shortest-path data to the nCell
                        nCell.g      = cCell.g + DistBetween(cCell, nCell);
                        nCell.parent = cCell;
                    }
                }
            }
        }
        //No path found, return null
        return(null);
    }