Esempio n. 1
0
        /// <summary>
        /// 寻路
        /// </summary>
        /// <param name="strPos">起始位置</param>
        /// <param name="endPos">终点位置</param>
        /// <param name="path">输出路径点</param>
        /// <param name="offset">移动物体大小</param>
        /// <returns>寻路结果</returns>
        public PathResCode Seek(Vector2 startPos, Vector2 endPos, out List <Vector2> path, int offset)
        {
            path = new List <Vector2>();

            if (this.m_lstTriangle == null || this.m_lstTriangle.Count <= 0)
            {
                return(PathResCode.NoMeshData);
            }

            ResetData();


            List <NavTriangle> pathTri;
            PathResCode        res = SeekTrianglePath(ref startPos, ref endPos, out pathTri, offset);

            if (res != PathResCode.Success)
            {
                return(res);
            }

            res = CreateWayPoints(startPos, endPos, pathTri, out path, offset);
            if (res != PathResCode.Success)
            {
                return(res);
            }


            return(res);
        }
Esempio n. 2
0
        /// <summary>
        /// 检查和修复所有错误路径点
        /// </summary>
        /// <param name="sTri"></param>
        /// <param name="startPos"></param>
        /// <param name="eTri"></param>
        /// <param name="endPos"></param>
        /// <returns></returns>
        private PathResCode CheckAndFixPos(ref NavTriangle startTri, ref Vector2 startPos, ref NavTriangle endTri, ref Vector2 endPos)
        {
            if (startTri != null && endTri != null && startTri.GetGroupID() != endTri.GetGroupID())
            {
                return(PathResCode.GroupNotMatch);
            }

            if (endTri == null)
            {
                if (FixPos(ref endTri, ref endPos, startTri, startPos, END_POS_EXTEND_LENGTH) != PathResCode.Success)
                {
                    return(PathResCode.Failed);
                }
            }

            if (startTri == null)
            {
                PathResCode fixRet = FixPos(ref startTri, ref startPos, endTri, endPos, START_POS_EXTEND_LENGTH);
            }

            if (startTri == null || endTri == null)
            {
                return(PathResCode.Failed);
            }

            if (startTri.GetGroupID() != endTri.GetGroupID())
            {
                return(PathResCode.GroupNotMatch);
            }

            return(PathResCode.Success);
        }
Esempio n. 3
0
    Vector2 m_TargetPos;                        // 走路的终点

    // 建立导航网格路径
    int BuildNavMeshPath(Vector2 fvCurrent, Vector2 fvTarget, int nPassLevel)
    {
        // 先清空路径.
        m_vPosStack.Clear();
        List <Vector2> pathList = null;

        PathResCode pathResult = PathFinder.Instance.FindPath(fvCurrent, fvTarget, out pathList, 0);

        if (pathList.Count >= 2)
        {
            PathUnit pu = new PathUnit();
            pu.fvStart = pathList[0];
            for (int i = 1; i < pathList.Count; i++)
            {
                Vector2 pt = pathList[i];
                pu.fvTarget = pt;
                m_vPosStack.Add(pu);
                pu.fvStart = pu.fvTarget;
            }
        }
        return(m_vPosStack.Count);
    }
Esempio n. 4
0
        /// <summary>
        /// 寻路路径三角形
        /// </summary>
        /// <param name="strPos">起始点</param>
        /// <param name="endPos">终点</param>
        /// <param name="pathTriangle">输出三角形</param>
        /// <param name="offset">移动物品大小</param>
        /// <returns>结果</returns>
        private PathResCode SeekTrianglePath(ref Vector2 startPos, ref Vector2 endPos, out List <NavTriangle> pathList, int offset)
        {
            pathList = new List <NavTriangle>();
            NavTriangle startTri = null, endTri = null;

            //获得起始与终点三角形
            foreach (NavTriangle navTri in this.m_lstTriangle)
            {
                if (startTri == null)
                {
                    if (navTri.IsPointIn(startPos))
                    {
                        startTri = navTri;
                    }
                }

                if (endTri == null)
                {
                    if (navTri.IsPointIn(endPos))
                    {
                        endTri = navTri;
                    }
                }

                if (startTri != null && endTri != null)
                {
                    break;
                }
            }

            //检查和修复位置
            PathResCode posErr = CheckAndFixPos(ref startTri, ref startPos, ref endTri, ref endPos);

            if (posErr != PathResCode.Success)
            {
                return(posErr);
            }

            //////////////////////////////////// A*算法 ///////////////////////////////////////

            int  pathSessionId           = 1;
            bool foundPath               = false;
            List <NavTriangle> openList  = new List <NavTriangle>(); //开放列表
            List <NavTriangle> closeList = new List <NavTriangle>();

            startTri.SetSessionID(pathSessionId);

            openList.Add(startTri);
            while (openList.Count > 0)
            {
                // 1. 把当前节点从开放列表删除, 加入到封闭列表
                NavTriangle currNode;
                currNode = openList[openList.Count - 1];
                openList.Remove(currNode);
                closeList.Add(currNode);

                //已经找到目的地
                if (currNode.GetID() == endTri.GetID())
                {
                    foundPath = true;
                    break;
                }

                // 2. 对当前节点相邻的每一个节点依次执行以下步骤:
                // 遍历所有邻接三角型
                for (int i = 0; i < 3; i++)
                {
                    int         neighborID = currNode.GetNeighbor(i);
                    NavTriangle neighborTri;

                    // 3. 如果该相邻节点不可通行,则什么操作也不执行,继续检验下一个节点;
                    if (neighborID < 0)
                    {
                        //没有该邻居节点
                        continue;
                    }
                    else
                    {
                        neighborTri = this.m_lstTriangle[neighborID];

                        if (neighborTri == null || neighborTri.GetID() != neighborID)
                        {
                            return(PathResCode.NavIDNotMatch);
                        }
                    }
                    if (neighborTri.GetGroupID() == startTri.GetGroupID())
                    {
                        if (neighborTri.GetSessionID() != pathSessionId)
                        {
                            // 4. 如果该相邻节点不在开放列表中,则将该节点添加到开放列表中,
                            //    并将该相邻节点的父节点设为当前节点,同时保存该相邻节点的G和F值;
                            neighborTri.SetSessionID(pathSessionId);
                            neighborTri.SetParentID(currNode.GetID());
                            neighborTri.SetOpen(true);

                            // 计算启发值h
                            neighborTri.CalcHeuristic(endPos);
                            // 计算三角形花费g
                            neighborTri.SetGValue(currNode.GetGValue() + currNode.GetCost(neighborTri.GetID()));

                            //放入开放列表并排序
                            openList.Add(neighborTri);
                            openList.Sort(CompareTriWithGValue);

                            //保存穿入边
                            neighborTri.SetArrivalWall(currNode.GetID());
                        }
                        else
                        {
                            // 5. 如果该相邻节点在开放列表中,
                            //    则判断若经由当前节点到达该相邻节点的G值是否小于原来保存的G值,
                            //    若小于,则将该相邻节点的父节点设为当前节点,并重新设置该相邻节点的G和F值
                            if (neighborTri.GetOpen())
                            {
                                if (neighborTri.GetGValue() + neighborTri.GetCost(currNode.GetID()) < currNode.GetGValue())
                                {
                                    currNode.SetGValue(neighborTri.GetGValue() + neighborTri.GetCost(currNode.GetID()));
                                    currNode.SetParentID(neighborTri.GetID());
                                    currNode.SetArrivalWall(neighborTri.GetID());
                                }
                            }
                            else
                            {
                                neighborTri = null;
                                continue;
                            }
                        }
                    }
                }
            }

            if (closeList.Count != 0)
            {
                NavTriangle path = closeList[closeList.Count - 1];
                pathList.Add(path);
                while (path.GetParentID() != -1)
                {
                    pathList.Add(this.m_lstTriangle[path.GetParentID()]);
                    path = this.m_lstTriangle[path.GetParentID()];
                }
            }

            if (!foundPath)
            {
                return(PathResCode.NotFoundPath);
            }
            else
            {
                return(PathResCode.Success);
            }
        }