unity A*尋路 (二)讀取NavMesh數據


上一章節我們已經看了怎么獲得NavMesh數據保存為obj

 

這一章節我們來讀取NavMesh數據

 

首先我們要定義兩個結構體

點 和 三角形

為什么不用unity自帶的Vector3呢?

相信你們應該已經知道  我們的尋路不能使用浮點運算

這時候我們就要確定一個精度

 

我這里設置為10000

namespace AStar
{
    public class AStarConfig 
    {
        /// <summary>
        /// 精度
        /// </summary>
        public const int precision = 10000;
    }
}

 

 

點結構體:

using UnityEngine;

namespace AStar
{
    /// <summary>
    /// 點.
    /// </summary>
    public struct AStarPonit
    {
        public int x;
        public int y;
        public int z;

        /// <summary>
        /// 構造函數
        /// </summary>
        /// <param name="point"></param>
        public AStarPonit(Vector3 point)
        {
            x = (int)(point.x * AStarConfig.precision);
            y = (int)(point.y * AStarConfig.precision);
            z = (int)(point.z * AStarConfig.precision);
        }
    }
}

 

 

三角形結構體:

namespace AStar
{
    /// <summary>
    /// 三角形
    /// </summary>
    public struct AStarTriangle
    {
        //三角形的三個點坐標
        public AStarPonit a;
        public AStarPonit b;
        public AStarPonit c;

        /// <summary>
        /// 三角形重心
        /// </summary>
        public AStarPonit centroid;

        /// <summary>
        /// 構造函數
        /// </summary>
        public AStarTriangle(AStarPonit a, AStarPonit b, AStarPonit c)
        {
            this.a = a;
            this.b = b;
            this.c = c;

            //計算重心
            centroid.x = (a.x + b.x + c.x) / 3;
            centroid.y = (a.y + b.y + c.y) / 3;
            centroid.z = (a.z + b.z + c.z) / 3;
        }
    }
}

 

 

我們需要一個類來保存導航網格信息方便 方便算法使用數據

using System.Collections.Generic;

namespace AStar
{
    /// <summary>
    /// 導航網格信息
    /// </summary>
    public class NavMeshInfo
    {
        /// <summary>
        /// 所有的三角形
        /// </summary>
        public List<AStarTriangle> allTriangle = new List<AStarTriangle>();
        /// <summary>
        /// 所有的重心
        /// </summary>
        public List<AStarPonit> allCentroid = new List<AStarPonit>();
        /// <summary>
        /// 三角形索引 key點 .value點構成的所有三角形  正常情況為三個
        /// </summary>
        public Dictionary<AStarPonit, List<AStarTriangle>> pointIndexes = new Dictionary<AStarPonit, List<AStarTriangle>>();
    }
}

 

讀取導航網格信息代碼:

using UnityEngine;
using System.IO;
using System.Collections.Generic;

namespace AStar
{
    public class NavMeshLoad
    {
        List<Vector3> allPoint = new List<Vector3>();

        /// <summary>
        /// 讀取導航網格信息
        /// </summary>
        /// <param name="path">路徑</param>
        public NavMeshInfo Load(string path)
        {
            List<string> fileInfo = LoadFile(path);

            NavMeshInfo navMeshInfo = ReadInfo(fileInfo);

            return navMeshInfo;
        }

        /// <summary>
        /// 讀取文件
        /// </summary>
        /// <param name="path">路徑</param>
        List<string> LoadFile(string path)
        {
            StreamReader sr = new StreamReader(path);

            string line;
            List<string> fileInfo = new List<string>();
            while ((line = sr.ReadLine()) != null)
            {
                //一行一行的讀取
                //將每一行的內容存入數組鏈表容器中
                fileInfo.Add(line);
            }
            //關閉流
            sr.Close();
            //銷毀流
            sr.Dispose();
            //將數組鏈表容器返回
            return fileInfo;
        }

        /// <summary>
        /// 讀取數據
        /// </summary>
        /// <param name="fileInfo">文件信息</param>
        /// <returns></returns>
        NavMeshInfo ReadInfo(List<string> fileInfo)
        {
            NavMeshInfo navMeshInfo = new NavMeshInfo();

            for (int i = 0; i < fileInfo.Count; i++)
            {
                string str = fileInfo[i];

                string[] Split = str.Split(' ');

                if (Split[0] == "v")
                {
                    allPoint.Add(new Vector3(float.Parse(Split[2]), float.Parse(Split[3]), float.Parse(Split[4])));
                }
                else if (Split[0] == "f")
                {
                    int a = int.Parse(Split[1]);
                    int b = int.Parse(Split[2]);
                    int c = int.Parse(Split[3]);

                    Vector3 aa = allPoint[a - 1];
                    Vector3 bb = allPoint[b - 1];
                    Vector3 cc = allPoint[c - 1];

                    AStarPonit aaa = new AStarPonit(aa);
                    AStarPonit bbb = new AStarPonit(bb);
                    AStarPonit ccc = new AStarPonit(cc);

                    AStarTriangle triangle = new AStarTriangle(aaa, bbb, ccc);

                    navMeshInfo.allCentroid.Add(triangle.centroid);

                    navMeshInfo.allTriangle.Add(triangle);

                    AddPointIndexes(navMeshInfo.pointIndexes, aaa, triangle);
                    AddPointIndexes(navMeshInfo.pointIndexes, bbb, triangle);
                    AddPointIndexes(navMeshInfo.pointIndexes, ccc, triangle);
                }
            }

            return navMeshInfo;
        }

        /// <summary>
        /// 添加頂點索引
        /// </summary>
        /// <param name="navMeshInfo"></param>
        /// <param name="ponit"></param>
        /// <param name="triangle"></param>
        void AddPointIndexes(Dictionary<AStarPonit, List<AStarTriangle>> navMeshInfo, AStarPonit ponit, AStarTriangle triangle)
        {
            if (navMeshInfo.ContainsKey(ponit))
            {
                navMeshInfo[ponit].Add(triangle);
            }
            else
            {
                List<AStarTriangle> list = new List<AStarTriangle>();
                list.Add(triangle);
                navMeshInfo.Add(ponit, list);
            }
        }
    }
}

 

我們來寫個測試代碼看下是否能獲得:

using UnityEngine;
using AStar;

public class test : MonoBehaviour
{
    void Start()
    {
        NavMeshLoad navMeshLoad = new NavMeshLoad();

        NavMeshInfo navMeshInfo = navMeshLoad.Load(Application.dataPath + "/AStar/obj/test.obj");
    }
}

斷點后 我們看navMeshInfo變量  已經可以看到有數據了

 

 

鏈接: https://pan.baidu.com/s/1Y3BDlp506x7_diq7_d48zw 密碼: ihvh


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM