Пример #1
0
    //是否有共边节点,是的话返回该节点,否则返回空。参数为边
    NavTriangle GetLinkNode(Vector3[] rim, NavTriangle except)
    {
        for (int i = 0; i < triangleList.Count; i++)
        {
            if (triangleList[i].Equals(except))
            {
                continue;
            }
            Vector3[] verts = triangleList[i].verts;

            //共顶点数量
            int count = 0;

            for (int j = 0; j < 3; j++)
            {
                if (verts[j] == rim[0])
                {
                    count++;
                }
                if (verts[j] == rim[1])
                {
                    count++;
                }
            }
            if (count == 2)
            {
                return(triangleList[i]);
            }
        }
        return(null);
    }
Пример #2
0
    bool IsCloseListContains(NavTriangle navNode)
    {
        for (int i = 0; i < closeList.Count; i++)
        {
            if (closeList[i].node.center == navNode.center)
            {
                return(true);
            }
        }

        return(false);
    }
Пример #3
0
    //取两个三角形的邻边两点
    public static List <Vector3> GetTwoPointsInTwoPath(PathNode p1, PathNode p2)
    {
        NavTriangle n1 = p1.node;
        NavTriangle n2 = p2.node;

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

        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                if (n1.verts[i] == n2.verts[j])
                {
                    pointList.Add(n1.verts[i]);
                }
            }
        }

        if (pointList.Count == 2)
        {
            //Vector3 v1 = pointList[0] - origin;
            //Vector3 v2 = pointList[1] - origin;

            Vector3 v1 = pointList[0] - p1.node.center;
            Vector3 v2 = pointList[1] - p1.node.center;


            Vector3 m = Vector3.Cross(v1, v2);

            //调成顺时针方向。
            if (m.z > 0)
            {
                Vector3 tempP = pointList[0];
                pointList[0] = pointList[1];
                pointList[1] = tempP;
            }

            //Debug.Log("向量:" + m);


            return(pointList);
        }

        return(null);
    }
Пример #4
0
    //初始化三角形相邻关系
    void InitTriangleList()
    {
        for (int i = 0; i < triangleList.Count; i++)
        {
            NavTriangle node = triangleList[i];
            //设置相邻三角形
            Vector3[] verts = node.verts;
            node.nodeArr[0] = GetLinkNode(new Vector3[] { verts[0], verts[1] }, node);
            node.nodeArr[1] = GetLinkNode(new Vector3[] { verts[0], verts[2] }, node);
            node.nodeArr[2] = GetLinkNode(new Vector3[] { verts[1], verts[2] }, node);

            //设置相邻三角形的距离
            for (int j = 0; j < 3; j++)
            {
                if (node.nodeArr[j] != null)
                {
                    node.dis[j] = Vector3.Distance(node.center, node.nodeArr[j].center);
                }
            }
        }
    }
Пример #5
0
    //初始化顶点列表
    void SetVertexList()
    {
        vertsList.Clear();
        triangleList.Clear();

        int count = transform.childCount;

        for (int i = 0; i < count; i++)
        {
            Transform child  = transform.GetChild(i);
            Vector3[] verts  = new Vector3[child.childCount];
            int       countG = child.childCount;

            List <Vector3> posList = new List <Vector3>();
            for (int j = 0; j < countG; j++)
            {
                Vector3 pos = child.GetChild(j).transform.position;
                posList.Add(pos);
            }

            vertsList.AddRange(posList);
            //设置各节点的顶点

            for (int k = 0; k < posList.Count - 2; k++)
            {
                //保存节点信息
                NavTriangle node = new NavTriangle(posList[0], posList[k + 1], posList[k + 2]);

                node.verts = new Vector3[] { posList[0], posList[k + 1], posList[k + 2] };

                if (node == null)
                {
                    print("空节点");
                }
                triangleList.Add(node);
            }
        }
    }
Пример #6
0
    static void Export()
    {
        Debug.Log("ExportNavMesh");

        UnityEngine.AI.NavMeshTriangulation tmpNavMeshTriangulation = UnityEngine.AI.NavMesh.CalculateTriangulation();

        //新建文件
        string tmpPath = Application.dataPath + "/" + SceneManager.GetActiveScene().name + ".lua";

        Debug.Log("=====================" + tmpPath + tmpNavMeshTriangulation.vertices.Length);
        StreamWriter tmpStreamWriter = new StreamWriter(tmpPath);

        tmpStreamWriter.WriteLine("-------本文件是地图导航网格文本");
        tmpStreamWriter.WriteLine("local nav_triangle = {");

        Hashtable pointTable = new Hashtable();

        //顶点
        for (int i = 0; i < tmpNavMeshTriangulation.vertices.Length; i++)
        {
            //tmpStreamWriter.WriteLine("v  " + tmpNavMeshTriangulation.vertices[i].x + " " + tmpNavMeshTriangulation.vertices[i].y + " " + tmpNavMeshTriangulation.vertices[i].z);
            if (!pointTable.ContainsKey(tmpNavMeshTriangulation.vertices[i]))
            {
                pointTable.Add(tmpNavMeshTriangulation.vertices[i], new ArrayList());
            }

            (pointTable[tmpNavMeshTriangulation.vertices[i]] as ArrayList).Add(i);
        }

        //tmpStreamWriter.WriteLine("g pPlane1");

        Hashtable          lineTable = new Hashtable();
        List <NavTriangle> triangles = new List <NavTriangle>();

        int triangleIndex = 1;

        for (int i = 0; i < tmpNavMeshTriangulation.indices.Length;)
        {
            //tmpStreamWriter.WriteLine("f " + (tmpNavMeshTriangulation.indices[i] + 1) + " " + (tmpNavMeshTriangulation.indices[i + 1] + 1) + " " + (tmpNavMeshTriangulation.indices[i + 2] + 1));
            NavTriangle item = new NavTriangle();
            item.tLineKeyArr = new string[3];
            item.tIndex      = triangleIndex;
            SetTriangleInfo(0, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[i + 2]]
                            , tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[i + 1]]
                            , pointTable, item, lineTable);
            SetTriangleInfo(1, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[i + 1]]
                            , tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[i]]
                            , pointTable, item, lineTable);
            SetTriangleInfo(2, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[i + 2]]
                            , tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[i]]
                            , pointTable, item, lineTable);

            triangles.Add(item);
            triangleIndex += 1;
            i              = i + 3;
        }

        for (int i = 0; i < triangles.Count; i++)
        {
            tmpStreamWriter.WriteLine(string.Format("\t[{0}] = {{", triangles[i].tIndex));

            tmpStreamWriter.WriteLine(string.Format("\t\tv = {{{{{0}, {1}, {2}}}, {{{3}, {4}, {5}}},{{{6}, {7}, {8}}}}},"
                                                    , tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3 + 2]].x, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3 + 2]].z, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3 + 2]].y
                                                    , tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3 + 1]].x, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3 + 1]].z, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3 + 1]].y
                                                    , tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3]].x, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3]].z, tmpNavMeshTriangulation.vertices[tmpNavMeshTriangulation.indices[(triangles[i].tIndex - 1) * 3]].y));

            tmpStreamWriter.WriteLine(string.Format("\t\tnedge = {{{0}, {1}, {2}}},"
                                                    , GetSameLine(triangles[i].tLineKeyArr[0], triangles[i].tIndex, lineTable)
                                                    , GetSameLine(triangles[i].tLineKeyArr[1], triangles[i].tIndex, lineTable)
                                                    , GetSameLine(triangles[i].tLineKeyArr[2], triangles[i].tIndex, lineTable)));

            tmpStreamWriter.WriteLine("\t},\n");
        }

        tmpStreamWriter.WriteLine("}");

        tmpStreamWriter.Flush();
        tmpStreamWriter.Close();

        Debug.Log("ExportNavMesh Success");
    }
Пример #7
0
    public static void SetTriangleInfo(int index, Vector3 pos1, Vector3 pos2, Hashtable pointTable, NavTriangle item, Hashtable lineTable)
    {
        int    point1, point2;
        string lineKey;

        point1 = Convert.ToInt32((pointTable[pos1] as ArrayList)[0]);
        point2 = Convert.ToInt32((pointTable[pos2] as ArrayList)[0]);

        lineKey = point1 < point2?string.Format("{0}_{1}", point1, point2) : string.Format("{0}_{1}", point2, point1);

        item.tLineKeyArr[index] = lineKey;
        if (!lineTable.ContainsKey(lineKey))
        {
            lineTable.Add(lineKey, new ArrayList());
        }

        (lineTable[lineKey] as ArrayList).Add(item.tIndex);
    }
Пример #8
0
    void FindNextPath(PathNode start, NavTriangle endNode, List <PathNode> openList, List <PathNode> closeList)
    {
        for (int i = 0; i < 3; i++)
        {
            if (start == null)
            {
                Debug.Log("是空的");
            }
            if (start.node.nodeArr[i] == null || IsCloseListContains(start.node.nodeArr[i]))
            {
                continue;
            }
            float    g    = start.dis + start.node.dis[i];
            float    h    = Vector3.Distance(start.node.nodeArr[i].center, endNode.center);
            float    f    = g + h;
            PathNode path = new PathNode();
            path.node   = start.node.nodeArr[i];
            path.dis    = f;
            path.parent = start;

            openList.Add(path);
        }

        //取最小F节点,加入闭合列表
        for (int i = 0; i < openList.Count; i++)
        {
            for (int j = i + 1; j < openList.Count; j++)
            {
                if (openList[i].dis > openList[j].dis)
                {
                    PathNode path = openList[i];
                    openList[i] = openList[j];
                    openList[j] = path;
                }
            }
        }

        //如果最小路径是错误的路径,则标记错误。

        PathNode curPath = null;

        if (openList.Count > 0)
        {
            curPath = openList[0];

            openList.RemoveAt(0);
            closeList.Add(curPath);

            //将结束点加入闭合列表中
            if (openList == null)
            {
                Debug.Log("是空的");
            }
            if (curPath.node.center == endNode.center)
            {
                //PathNode path = new PathNode();
                //path.node = endNode;
                //path.parent = curPath;
                //closeList.Add(path);
                return;
            }
        }

        FindNextPath(curPath, endNode, openList, closeList);
    }
Пример #9
0
    public List <PathNode> FindCenterPointPath(Vector3 start, Vector3 end)
    {
        //标记开始结束点
        startVertex = FindNodeByPoint(start);
        endVertex   = FindNodeByPoint(end);

        if (startVertex == null && endVertex == null)
        {
            return(null);
        }
        else if (startVertex == null)
        {
            startVertex = FindNearestNode(start);
        }
        else if (endVertex == null)
        {
            endVertex = FindNearestNode(end);
        }

        PathNode startNode = new PathNode();

        startNode.node = startVertex;
        PathNode endNode = new PathNode();

        endNode.node = endVertex;

        //如果起点和终点在同一个三角形中,则返回一个节点
        if (startVertex.center == endVertex.center)
        {
            pathList.Clear();
            pathList.Add(startNode);
            return(pathList);
        }
        //如果起点和终点在两个相邻的三角形中,则返回二个节点
        else if (TriangleUtil.GetTwoPointsInTwoPath(startNode, endNode) != null)
        {
            pathList.Clear();
            pathList.Add(startNode);
            pathList.Add(endNode);
            return(pathList);
        }

        List <PathNode> openList = new List <PathNode>();

        closeList = new List <PathNode>();


        PathNode path = new PathNode();

        path.node = startVertex;
        path.dis  = 0;

        closeList.Add(path);

        FindNextPath(path, endVertex, openList, closeList);

        //记录并显示路径
        if (showProcessPath)
        {
            ShowProcessPath();
        }
        else
        {
            ShowCenterPath();
        }
        return(pathList);
    }