Ejemplo n.º 1
0
        public bool CheckForBlock(Vector3 pos)
        {
            float  gridSize   = BuildManager.GetGridSize();
            NodeTD targetNode = PathFinder.GetNearestNode(pos, nodeGraph);

            for (int i = 0; i < subPathList.Count; i++)
            {
                SubPath subPath = subPathList[i];
                if (Vector3.Distance(pos, subPath.startN.pos) < gridSize / 2)
                {
                    return(true);
                }
                if (Vector3.Distance(pos, subPath.endN.pos) < gridSize / 2)
                {
                    return(true);
                }

                if (subPath.IsNodeInPath(targetNode))
                {
                    subPath.altPath = PathFinder.ForceSearch(subPath.startN, subPath.endN, targetNode, nodeGraph);
                    if (subPath.altPath.Count == 0)
                    {
                        return(true);
                    }
                }
            }

            nextBuildNode = targetNode;

            return(false);
        }
Ejemplo n.º 2
0
 public SearchQueue(NodeTD n1, NodeTD n2, NodeTD[] g, SetPathCallbackTD func)
 {
     startNode    = n1;
     endNode      = n2;
     graph        = g;
     callBackFunc = func;
 }
Ejemplo n.º 3
0
 public static void GetPath(NodeTD startN, NodeTD endN, NodeTD[] graph, SetPathCallbackTD callBackFunc)
 {
     if (instance == null)
     {
         Init();
     }
     instance._GetPath(startN, endN, graph, callBackFunc);
 }
Ejemplo n.º 4
0
 public void UnbuildTower(NodeTD node)
 {
     node.walkable = true;
     for (int i = 0; i < subPathList.Count; i++)
     {
         subPathList[i].SearchNewPath(nodeGraph);
     }
 }
Ejemplo n.º 5
0
        public List <Vector3> altPath = new List <Vector3>();     //for checking if there's any block

        public void Init(PlatformTD platform)
        {
            parentPlatform = platform;

            startN = PathFinder.GetNearestNode(connectStart.position, platform.GetNodeGraph());
            endN   = PathFinder.GetNearestNode(connectEnd.position, platform.GetNodeGraph());

            path.Add((connectStart.position + connectEnd.position) / 2);

            SearchNewPath(platform.GetNodeGraph());
        }
Ejemplo n.º 6
0
 public void _GetPath(NodeTD startN, NodeTD endN, NodeTD[] graph, SetPathCallbackTD callBackFunc)
 {
     if (!searching)
     {
         //commence search
         StartCoroutine(_SearchRoutine(startN, endN, graph, callBackFunc));
     }
     else
     {
         //if a serach is in progress, put current request into the queue list
         SearchQueue q = new SearchQueue(startN, endN, graph, callBackFunc);
         searchQueueList.Add(q);
     }
 }
Ejemplo n.º 7
0
        public bool IsNodeInPath(NodeTD node)
        {
            float gridSize = BuildManager.GetGridSize();

            for (int i = 0; i < path.Count; i++)
            {
                float dist = Vector3.Distance(node.pos, path[i]);
                if (dist < gridSize * .85f)
                {
                    return(true);
                }
            }
            return(false);
        }
Ejemplo n.º 8
0
        void ResetSubPath(SubPath platformSubPath)
        {
            if (dummyT == null)
            {
                dummyT = new GameObject().transform;
            }

            Quaternion rot = Quaternion.LookRotation(subPath[subWaypointID] - thisT.position);

            dummyT.rotation = rot;
            dummyT.position = thisT.position;

            Vector3 pos    = dummyT.TransformPoint(0, 0, BuildManager.GetGridSize() / 2);
            NodeTD  startN = PathFinder.GetNearestNode(pos, platformSubPath.parentPlatform.GetNodeGraph());

            PathFinder.GetPath(startN, platformSubPath.endN, platformSubPath.parentPlatform.GetNodeGraph(), this.SetSubPath);
        }
Ejemplo n.º 9
0
        public static NodeTD GetNearestNode(Vector3 point, NodeTD[] graph, int searchMode)
        {
            float  dist           = Mathf.Infinity;
            float  currentNearest = Mathf.Infinity;
            NodeTD nearestNode    = null;

            foreach (NodeTD node in graph)
            {
                if (searchMode == 0)
                {
                    dist = Vector3.Distance(point, node.pos);
                    if (dist < currentNearest)
                    {
                        currentNearest = dist;
                        nearestNode    = node;
                    }
                }
                else if (searchMode == 1)
                {
                    if (node.walkable)
                    {
                        dist = Vector3.Distance(point, node.pos);
                        if (dist < currentNearest)
                        {
                            currentNearest = dist;
                            nearestNode    = node;
                        }
                    }
                }
                else if (searchMode == 2)
                {
                    if (!node.walkable)
                    {
                        dist = Vector3.Distance(point, node.pos);
                        if (dist < currentNearest)
                        {
                            currentNearest = dist;
                            nearestNode    = node;
                        }
                    }
                }
            }
            return(nearestNode);
        }
Ejemplo n.º 10
0
        public void BuildTower(Vector3 pos, UnitTower tower)
        {
            //pathfinding related code, only call if this platform is walkable;
            if (!walkable)
            {
                return;
            }

            if (tower.type != _TowerType.Mine)
            {
                NodeTD node = PathFinder.GetNearestNode(pos, nodeGraph);
                node.walkable = false;
                tower.SetPlatform(this, node);

                //if the node has been check before during CheckForBlock(), just use the altPath
                if (node == nextBuildNode)
                {
                    for (int i = 0; i < subPathList.Count; i++)
                    {
                        if (subPathList[i].IsNodeInPath(node))
                        {
                            subPathList[i].SwitchToSubPath();
                        }
                    }
                    return;
                }

                for (int i = 0; i < subPathList.Count; i++)
                {
                    if (subPathList[i].IsNodeInPath(node))
                    {
                        subPathList[i].SearchNewPath(nodeGraph);
                    }
                }
            }
        }
Ejemplo n.º 11
0
        //make cause system to slow down, use with care
        public static List <Vector3> ForceSearch(NodeTD startN, NodeTD endN, NodeTD blockN, NodeTD[] graph, int footprint = -1)
        {
            if (blockN != null)
            {
                blockN.walkable = false;
            }

            bool pathFound = true;

            int searchCounter = 0;              //used to count the total amount of node that has been searched

            List <NodeTD> closeList = new List <NodeTD>();

            NodeTD[] openList = new NodeTD[graph.Length];

            List <int> openListRemoved = new List <int>();
            int        openListCounter = 0;

            NodeTD currentNode = startN;

            float currentLowestF = Mathf.Infinity;
            int   id             = 0;   //use element num of the node with lowest score in the openlist during the comparison process
            int   i = 0;                //universal int value used for various looping operation

            while (true)
            {
                if (currentNode == endN)
                {
                    break;
                }

                closeList.Add(currentNode);
                currentNode.listState = _ListStateTD.Close;

                currentNode.ProcessNeighbour(endN);

                foreach (NodeTD neighbour in currentNode.neighbourNode)
                {
                    if (neighbour.listState == _ListStateTD.Unassigned && neighbour.walkable)
                    {
                        neighbour.listState = _ListStateTD.Open;
                        if (openListRemoved.Count > 0)
                        {
                            openList[openListRemoved[0]] = neighbour;
                            openListRemoved.RemoveAt(0);
                        }
                        else
                        {
                            openList[openListCounter] = neighbour;
                            openListCounter          += 1;
                        }
                    }
                }

                currentNode = null;

                currentLowestF = Mathf.Infinity;
                id             = 0;
                for (i = 0; i < openListCounter; i++)
                {
                    if (openList[i] != null)
                    {
                        if (openList[i].scoreF < currentLowestF)
                        {
                            currentLowestF = openList[i].scoreF;
                            currentNode    = openList[i];
                            id             = i;
                        }
                    }
                }

                if (currentNode == null)
                {
                    pathFound = false;
                    break;
                }

                openList[id] = null;
                openListRemoved.Add(id);

                searchCounter += 1;
            }


            List <Vector3> p = new List <Vector3>();

            if (pathFound)
            {
                while (currentNode != null)
                {
                    p.Add(currentNode.pos);
                    currentNode = currentNode.parent;
                }

                p = InvertArray(p);
                p = SmoothPath(p);
            }

            if (blockN != null)
            {
                blockN.walkable = true;
            }

            ResetGraph(graph);

            return(p);
        }
Ejemplo n.º 12
0
        IEnumerator _SearchRoutine(NodeTD startN, NodeTD endN, NodeTD[] graph, SetPathCallbackTD callBackFunc)
        {
            //mark that a serac has started, any further query will be queued
            searching = true;
            bool pathFound = true;

            int searchCounter = 0;              //used to count the total amount of node that has been searched
            int loopCounter   = 0;              //used to count how many node has been search in the loop, if it exceed a value, bring it to the next frame
            //float LoopTime=Time.realtimeSinceStartup;

            //closelist, used to store all the node that are on the path
            List <NodeTD> closeList = new List <NodeTD>();

            //openlist, all the possible node that yet to be on the path, the number can only be as much as the number of node in the garph
            NodeTD[] openList = new NodeTD[graph.Length];

            //an array use to record the element number in the open list which is empty after the node is removed to be use as currentNode,
            //so we can use builtin array with fixed length for openlist, also we can loop for the minimal amount of node in every search
            List <int> openListRemoved = new List <int>();
            //current count of elements that are occupied in openlist, openlist[n>openListCounter] are null
            int openListCounter = 0;

            //set start as currentNode
            NodeTD currentNode = startN;

            //use to compare node in the openlist has the lowest score, alwyas set to Infinity when not in used
            float currentLowestF = Mathf.Infinity;
            int   id             = 0;   //use element num of the node with lowest score in the openlist during the comparison process
            int   i = 0;                //universal int value used for various looping operation

            //loop start
            while (true)
            {
                //if we have reach the destination
                if (currentNode == endN)
                {
                    break;
                }

                //for gizmo debug purpose
                //currentNodeBeingProcess=currentNode;

                //move currentNode to closeList;
                closeList.Add(currentNode);
                currentNode.listState = _ListStateTD.Close;

                //loop through the neighbour of current loop, calculate  score and stuff
                currentNode.ProcessNeighbour(endN);

                //put all neighbour in openlist
                foreach (NodeTD neighbour in currentNode.neighbourNode)
                {
                    if (neighbour.listState == _ListStateTD.Unassigned && neighbour.walkable)
                    {
                        //set the node state to open
                        neighbour.listState = _ListStateTD.Open;
                        //if there's an open space in openlist, fill the space
                        if (openListRemoved.Count > 0)
                        {
                            openList[openListRemoved[0]] = neighbour;
                            //remove the number from openListRemoved since this element has now been occupied
                            openListRemoved.RemoveAt(0);
                        }
                        //else just stack on it and increase the occupication counter
                        else
                        {
                            openList[openListCounter] = neighbour;
                            openListCounter          += 1;
                        }
                    }
                }

                //clear the current node, before getting a new one, so we know if there isnt any suitable next node
                currentNode = null;

                //get the next point from openlist, set it as current point
                //just loop through the openlist until we reach the maximum occupication
                //while that, get the node with the lowest score
                currentLowestF = Mathf.Infinity;
                id             = 0;
                for (i = 0; i < openListCounter; i++)
                {
                    if (openList[i] != null)
                    {
                        if (openList[i].scoreF < currentLowestF)
                        {
                            currentLowestF = openList[i].scoreF;
                            currentNode    = openList[i];
                            id             = i;
                        }
                    }
                }

                //if there's no node left in openlist, path doesnt exist
                if (currentNode == null)
                {
                    pathFound = false;
                    break;
                }

                //remove the new currentNode from openlist
                openList[id] = null;
                //put the id into openListRemoved so we know there's an empty element that can be filled in the next loop
                openListRemoved.Add(id);

                //increase the counter
                searchCounter += 1;
                loopCounter   += 1;

                //if exceed the search limit per frame, bring the search to the next frame
                if (loopCounter > ScanNodeLimitPerFrame)
                {
                    loopCounter = 0;                    //reset the loopCounter for the next frame
                    yield return(null);
                }
            }


            //trace back the path through closeList
            List <Vector3> p = new List <Vector3>();

            if (pathFound)
            {
                //track back the node's parent to form a path
                while (currentNode != null)
                {
                    p.Add(currentNode.pos);
                    currentNode = currentNode.parent;
                }

                //since the path is now tracked from endN ot startN, invert the list
                p = InvertArray(p);
                p = SmoothPath(p);
            }

            callBackFunc(p);

            //clear searching so indicate the search has end and a new serach can be called
            searching = false;

            ResetGraph(graph);
        }
Ejemplo n.º 13
0
 public void SetPlatform(PlatformTD platform, NodeTD node)
 {
     occupiedPlatform = platform;
     occupiedNode     = node;
 }
Ejemplo n.º 14
0
        public static NodeTD[] GenerateNode(PlatformTD platform, float heightOffset)
        {
            if (instance == null)
            {
                Init();
            }

            Transform platformT = platform.thisT;

            float gridSize = BuildManager.GetGridSize();

            float scaleX = platform.thisT.localScale.x;
            float scaleZ = platform.thisT.localScale.z;

            int countX = (int)(scaleX / gridSize);
            int countZ = (int)(scaleZ / gridSize);


            float x = -scaleX / 2 / scaleX;
            float z = -scaleZ / 2 / scaleZ;


            Vector3 point = platformT.TransformPoint(new Vector3(x, 0, z));

            thisT.position = point;
            thisT.rotation = platformT.rotation;

            thisT.position = thisT.TransformPoint(new Vector3(gridSize / 2, heightOffset, gridSize / 2));

            NodeTD[] nodeGraph = new NodeTD[countZ * countX];

            int counter = 0;

            for (int i = 0; i < countZ; i++)
            {
                for (int j = 0; j < countX; j++)
                {
                    Vector3 pos = thisT.position;
                    pos.y = pos.y + 5000;

                    LayerMask  mask = 1 << LayerManager.LayerTower();
                    RaycastHit hit1;
                    if (Physics.Raycast(pos, Vector3.down, out hit1, Mathf.Infinity, ~mask))
                    {
                        nodeGraph[counter] = new NodeTD(new Vector3(pos.x, hit1.point.y + heightOffset, pos.z), counter);
                    }
                    else
                    {
                        nodeGraph[counter]          = new NodeTD(pos, counter);
                        nodeGraph[counter].walkable = false;
                    }

                    counter += 1;

                    thisT.position = thisT.TransformPoint(new Vector3(gridSize, 0, 0));
                }
                thisT.position = thisT.TransformPoint(new Vector3(-(countX) * gridSize, 0, gridSize));
            }

            thisT.position = Vector3.zero;
            thisT.rotation = Quaternion.identity;


            counter = 0;
            foreach (NodeTD cNode in nodeGraph)
            {
                if (cNode.walkable)
                {
                    //check if there's anything within the point
                    LayerMask mask = 1 << LayerManager.LayerPlatform();
                    mask |= 1 << LayerManager.LayerTower();
                    if (LayerManager.LayerTerrain() >= 0)
                    {
                        mask |= 1 << LayerManager.LayerTerrain();
                    }
                    Collider[] cols = Physics.OverlapSphere(cNode.pos, gridSize * 0.45f, ~mask);
                    if (cols.Length > 0)
                    {
                        cNode.walkable = false;
                        counter       += 1;
                    }
                }
            }


            float neighbourDistance = 0;
            float neighbourRange;

            if (instance.connectDiagonalNeighbour)
            {
                neighbourRange = gridSize * 1.5f;
            }
            else
            {
                neighbourRange = gridSize * 1.1f;
            }

            counter = 0;
            //assign the neighouring  node for each node in the grid
            foreach (NodeTD currentNode in nodeGraph)
            {
                //only if that node is walkable
                if (currentNode.walkable)
                {
                    //create an empty array
                    List <NodeTD> neighbourNodeList = new List <NodeTD>();
                    List <float>  neighbourCostList = new List <float>();

                    NodeTD[] neighbour = new NodeTD[8];
                    int      id        = currentNode.ID;

                    if (id > countX - 1 && id < countX * countZ - countX)
                    {
                        //print("middle rows");
                        if (id != countX)
                        {
                            neighbour[0] = nodeGraph[id - countX - 1];
                        }
                        neighbour[1] = nodeGraph[id - countX];
                        neighbour[2] = nodeGraph[id - countX + 1];
                        neighbour[3] = nodeGraph[id - 1];
                        neighbour[4] = nodeGraph[id + 1];
                        neighbour[5] = nodeGraph[id + countX - 1];
                        neighbour[6] = nodeGraph[id + countX];
                        if (id != countX * countZ - countX - 1)
                        {
                            neighbour[7] = nodeGraph[id + countX + 1];
                        }
                    }
                    else if (id <= countX - 1)
                    {
                        //print("first row");
                        if (id != 0)
                        {
                            neighbour[0] = nodeGraph[id - 1];
                        }
                        if (nodeGraph.Length > id + 1)
                        {
                            neighbour[1] = nodeGraph[id + 1];
                        }
                        if (countZ > 0)
                        {
                            if (nodeGraph.Length > id + countX - 1)
                            {
                                neighbour[2] = nodeGraph[id + countX - 1];
                            }
                            if (nodeGraph.Length > id + countX)
                            {
                                neighbour[3] = nodeGraph[id + countX];
                            }
                            if (nodeGraph.Length > id + countX + 1)
                            {
                                neighbour[4] = nodeGraph[id + countX + 1];
                            }
                        }
                    }
                    else if (id >= countX * countZ - countX)
                    {
                        //print("last row");
                        neighbour[0] = nodeGraph[id - 1];
                        if (id != countX * countZ - 1)
                        {
                            neighbour[1] = nodeGraph[id + 1];
                        }
                        if (id != countX * (countZ - 1))
                        {
                            neighbour[2] = nodeGraph[id - countX - 1];
                        }
                        neighbour[3] = nodeGraph[id - countX];
                        neighbour[4] = nodeGraph[id - countX + 1];
                    }



                    //scan through all the node in the grid
                    foreach (NodeTD node in neighbour)
                    {
                        //if this the node is not currentNode
                        if (node != null && node.walkable)
                        {
                            //if this node is within neighbour node range
                            neighbourDistance = GetHorizontalDistance(currentNode.pos, node.pos);
                            if (neighbourDistance < neighbourRange)
                            {
                                //if nothing's in the way between these two
                                LayerMask mask = 1 << LayerManager.LayerPlatform();
                                mask |= 1 << LayerManager.LayerTower();
                                if (!Physics.Linecast(currentNode.pos, node.pos, ~mask))
                                {
                                    //if the slop is not too steep
                                    //if(Mathf.Abs(GetSlope(currentNode.pos, node.pos))<=maxSlope){
                                    //add to list
                                    //if(!node.walkable) Debug.Log("error");
                                    neighbourNodeList.Add(node);
                                    neighbourCostList.Add(neighbourDistance);
                                    //}//else print("too steep");
                                }                //else print("something's in the way");
                            }                    //else print("out of range "+neighbourDistance);
                        }                        //else print("unwalkable");
                    }

                    //set the list as the node neighbours array
                    currentNode.SetNeighbour(neighbourNodeList, neighbourCostList);

                    //if(neighbourNodeList.Count==0)
                    //Debug.Log("no heighbour. node number "+counter+"  "+neighbourNodeList.Count);
                }

                counter += 1;
            }

            return(nodeGraph);
        }
Ejemplo n.º 15
0
 public void ProcessNeighbour(NodeTD node)
 {
     ProcessNeighbour(node.pos);
 }