예제 #1
0
 public CellPath(CellPath existedPath, CellContent newConnection)
 {
     this.start       = existedPath.start;
     this.connections = new List <CellContent>(existedPath.connections);
     this.connections.Add(newConnection);
     this.path = new List <Cell>(existedPath.path);
     this.path.Add(newConnection.connection);
 }
        public override void Work()
        {
            GetStartValues();
            CheckChunkPath();

            if (ReferenceEquals(startCell, endCell))
            {
                Path path = new Path(start_v3, (MoveState)(int)startCell.passability);
                path.AddMove(end_v3, (MoveState)(int)startCell.passability);
                path.RemoveFirst();
                agent.ReceivePath(path);
                callBack.Invoke();
                return;
            }

            GeneratePaths();

            if (potentialPaths.Count == 0)
            {
                Debug.Log("no path");
                callBack.Invoke();
                return;
            }

            CellPath targetCellPath = potentialPaths.OrderBy(val => val.gh).First();

            funnelPath = new Path(start_v3, (MoveState)(int)targetCellPath.path.First().passability);
            if (applyRaycast)
            {
                RaycastHitNavMesh rhnm;
                Cell c = targetCellPath.connections[0].from;
                Raycast(start_v3, end_v3 - start_v3, out rhnm, Vector3.Distance(start_v3, end_v3), raycastIterations, c.passability, c.area, c);

                if (!rhnm.isOnGraph)
                {
                    //Debuger_K.AddLine(start_v3, rhnm.point, Color.green);
                    //Debuger_K.AddDot(rhnm.point, Color.green, 0.2f);
                    funnelPath.AddMove(end_v3, (MoveState)(int)c.passability);
                }
                else
                {
                    FunnelPath(targetCellPath, end_v3);
                    //Debuger_K.AddLine(start_v3, rhnm.point, Color.red);
                    //Debuger_K.AddDot(rhnm.point, Color.red, 0.2f);
                }
            }
            else
            {
                FunnelPath(targetCellPath, end_v3);
            }
            //FunnelPath(targetCellPath, end_v3);
            agent.ReceivePath(funnelPath);
            callBack.Invoke();
        }
예제 #3
0
        protected void AddCellNode(CellPath node)
        {
            LinkedListNode <CellPath> targetNode = null;

            for (LinkedListNode <CellPath> currentPath = linkedPaths.First;
                 currentPath != null && currentPath.Value.gh < node.gh;
                 currentPath = currentPath.Next)
            {
                targetNode = currentPath;
            }

            if (targetNode == null)
            {
                linkedPaths.AddFirst(node);
            }
            else
            {
                linkedPaths.AddAfter(targetNode, node);
            }
        }
        protected void FunnelPath(CellPath path, Vector3 endV3)
        {
            List <Cell> cellPath = path.path;

            List <CellContent> cellPathConnections = path.connections;

#if UNITY_EDITOR
            if (Debuger_K.debugPath)
            {
                for (int i = 0; i < cellPath.Count - 1; i++)
                {
                    Debuger_K.AddPath(cellPath[i].centerV3 + Vector3.up, cellPath[i + 1].centerV3 + Vector3.up, Color.magenta, 0.1f);
                }
            }
#endif
            int keyGate = 0;

            while (true)
            {
                if (keyGate >= cellPathConnections.Count)
                {
                    break;
                }

                int curKeyGate;

                List <CellContentGenericConnection> gateSiquence = new List <CellContentGenericConnection>();
                for (curKeyGate = keyGate; curKeyGate < cellPathConnections.Count; curKeyGate++)
                {
                    var c = cellPathConnections[curKeyGate];
                    if (c is CellContentGenericConnection)
                    {
                        gateSiquence.Add((CellContentGenericConnection)c);
                    }
                    else
                    {
                        break;
                    }
                }

                if (keyGate != curKeyGate)
                {
                    DoFunnelIteration(funnelPath.lastV3, curKeyGate == cellPathConnections.Count ? endV3 : (cellPathConnections[curKeyGate] as CellContentPointedConnection).enterPoint, gateSiquence);
                }

                if (curKeyGate != cellPathConnections.Count)
                {
                    if (cellPathConnections[curKeyGate] is CellContentPointedConnection)
                    {
                        CellContentPointedConnection ju = cellPathConnections[curKeyGate] as CellContentPointedConnection;
                        if (ju.jumpState == ConnectionJumpState.jumpUp)
                        {
                            funnelPath.AddMove(ju.lowerStandingPoint, (MoveState)(int)ju.from.passability);
                            funnelPath.AddJumpUp(ju.lowerStandingPoint, ju.axis);
                            funnelPath.AddMove(ju.exitPoint, (MoveState)(int)ju.connection.passability);
                        }
                        else
                        {
                            funnelPath.AddMove(ju.enterPoint, (MoveState)(int)ju.from.passability);
                            funnelPath.AddMove(ju.axis, (MoveState)(int)ju.from.passability);
                            funnelPath.AddJumpDown(ju.axis, ju.lowerStandingPoint);
                            funnelPath.AddMove(ju.exitPoint, (MoveState)(int)ju.connection.passability);
                        }
                    }
                    else
                    {
                        Debug.LogErrorFormat("idk type of CellConnectionAbstract node {0}", cellPathConnections[curKeyGate].GetType().Name);
                    }
                }

                keyGate = curKeyGate + 1;
            }

            funnelPath.AddMove(endV3, (MoveState)(int)cellPath[cellPath.Count - 1].passability);

#if UNITY_EDITOR
            if (Debuger_K.debugPath)
            {
                var resultNodes = funnelPath.nodes;
                for (int i = 0; i < resultNodes.Count - 1; i++)
                {
                    Debuger_K.AddPath(resultNodes[i].positionV3, resultNodes[i + 1].positionV3, Color.green);
                }
                //for (int i = 0; i < resultNodes.Count; i++) {
                //    Debuger3.AddDot(resultNodes[i].positionV3, Color.green, 0.03f, DebugGroup.path);
                //    Debuger3.AddLabel(resultNodes[i].positionV3, resultNodes[i].ToString(), DebugGroup.path);
                //}
            }
#endif
            funnelPath.RemoveFirst();
        }
        private void GeneratePaths()
        {
            CellPath path = new CellPath(startCell, start_v3);

            if (startCell == endCell)
            {
                potentialPaths.Add(path);
                return;
            }

#if UNITY_EDITOR
            float totalDist = Debuger_K.doDebug ? Vector3.Distance(start_v3, end_v3) : 0f;
#endif

            path.h = EuclideanDistance(start_v3);
            excluded.Clear();
            excluded.Add(startCell);

            foreach (var connection in startCell.connections)
            {
                CellPath newPath = new CellPath(path, connection);
                newPath.g = connection.Cost(properties, ignoreCrouchCost);
                if (connection is CellContentPointedConnection)
                {
                    newPath.h = EuclideanDistance((connection as CellContentPointedConnection).exitPoint);
                }
                else
                {
                    newPath.h = EuclideanDistance(connection.connection);
                }
                AddCellNode(newPath);
            }

            int limit = 0;
            while (true)
            {
                limit++;
                if (limit > 1500)
                {
                    Debug.Log("limit > 1500");
                    break;
                }

                CellPath current = TakeCellNode();
                if (current == null)
                {
                    break;
                }

                Cell currentCell = current.last;

                if (currentCell == endCell)
                {
                    potentialPaths.Add(current);
#if UNITY_EDITOR
                    if (Debuger_K.doDebug)
                    {
                        float lerped = Mathf.InverseLerp(0, totalDist, Vector3.Distance(end_v3, currentCell.centerV3));
                        Debuger_K.AddPath(current.path[current.path.Count - 2].centerV3 + Vector3.up, current.path[current.path.Count - 1].centerV3 + Vector3.up, new Color(lerped, 1 - lerped, 0, 1f));
                    }
#endif
                    if (potentialPaths.Count >= maxPaths)
                    {
                        break;
                    }
                    else
                    {
                        continue;
                    }
                }

                if (excluded.Contains(currentCell))
                {
                    continue;
                }
                else
                {
                    excluded.Add(currentCell);
                }

#if UNITY_EDITOR
                if (Debuger_K.doDebug)
                {
                    float lerped = Mathf.InverseLerp(0, totalDist, Vector3.Distance(end_v3, currentCell.centerV3));
                    Debuger_K.AddPath(current.path[current.path.Count - 2].centerV3 + (Vector3.up * 0.3f), current.path[current.path.Count - 1].centerV3 + (Vector3.up * 0.3f), new Color(lerped, 1 - lerped, 0, 1f));
                }
#endif

                foreach (var connection in currentCell.connections)
                {
                    Cell newCell = connection.connection;

                    if (current.Contains(newCell) == false)
                    {
                        CellPath newPath = new CellPath(current, connection);
#if UNITY_EDITOR
                        if (Debuger_K.debugPath)
                        {
                            Debuger_K.AddLabel(SomeMath.MidPoint(current.last.centerV3, newCell.centerV3), connection.Cost(properties, ignoreCrouchCost), DebugGroup.path);
                        }
#endif

                        newPath.g = current.g + connection.Cost(properties, ignoreCrouchCost);
                        if (connection is CellContentPointedConnection)
                        {
                            newPath.h = EuclideanDistance((connection as CellContentPointedConnection).exitPoint);
                            //Debuger3.AddLabel((connection as CellPointedConnection).exitPoint, newPath.h);
                        }
                        else
                        {
                            newPath.h = EuclideanDistance(connection.connection);
                        }

                        AddCellNode(newPath);
                    }
                }
            }
        }
예제 #6
0
        //just use Dijkstra to find nearest cover
        private List <NodeCoverPoint> SearchCover()
        {
            List <NodeCoverPoint> result = new List <NodeCoverPoint>();
            CellPath path = new CellPath(startCell, start_v3);

            if (startCell.covers != null)
            {
                result.AddRange(startCell.covers);
            }

            excluded.Add(startCell);

            foreach (var connection in startCell.connections)
            {
                CellPath newPath = new CellPath(path, connection);
                newPath.g = connection.Cost(start_v3, properties, ignoreCrouchCost);
                AddCellNode(newPath);
            }

            while (true)
            {
                CellPath current = TakeCellNode();
                if (current == null || current.g > maxMoveCost)
                {
                    break;
                }

                Cell currentCell = current.last;

                if (excluded.Contains(currentCell))
                {
                    continue;
                }
                else
                {
                    excluded.Add(currentCell);
                }

#if UNITY_EDITOR
                if (Debuger_K.debugPath)
                {
                    Debuger_K.AddPath(current.path[current.path.Count - 2].centerV3, current.path[current.path.Count - 1].centerV3, Color.green);
                }
#endif

                if (currentCell.covers != null)
                {
                    result.AddRange(currentCell.covers);
                }

                foreach (var connection in currentCell.connections)
                {
                    Cell newCell = connection.connection;

                    if (current.Contains(newCell) == false)
                    {
                        CellPath newPath = new CellPath(current, connection);
                        newPath.g = current.g + connection.Cost(properties, ignoreCrouchCost);
                        AddCellNode(newPath);
                    }
                }
            }
            return(result);
        }