<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      unity A*尋路 (三)A*算法

      這里我就不解釋A*算法

      如果你還不知道A*算法

      網上有很多簡單易懂的例子

      我發幾個我看過的鏈接

      http://www.rzrgm.cn/lipan/archive/2010/07/01/1769420.html

      https://zhuanlan.zhihu.com/p/24112879

      我這里就當你會A*算法

       

      三角網格的A*算法尋路

      需要用到多邊形方法

      這里我引入了一個Polygon庫

       

      在一個工具類中調用這個庫文件

      如果你想自己寫這些邏輯或者有更好的庫 可以替換

       

      using System.Collections.Generic;
      using Polygon;
      
      namespace AStar
      {
          public class AStarTools
          {
              /// <summary>
              /// 判斷點在哪個三角形中
              /// </summary>
              /// <param name="point"></param>
              /// <param name="allAStarTriangle"></param>
              /// <returns></returns>
              public static Triangle GetAStarTriangleByPoint(Ponit point, List<Triangle> allAStarTriangle)
              {
                  if (allAStarTriangle == null)
                  {
                      return new Triangle();
                  }
      
                  Point Point = new Point(point.x, point.z);
      
                  for (int i = 0; i < allAStarTriangle.Count; i++)
                  {
                      Triangle AStarTriangle = allAStarTriangle[i];
      
                      List<Point> pointList = new List<Point>();
                      pointList.Add(new Point(AStarTriangle.a.x, AStarTriangle.a.z));
                      pointList.Add(new Point(AStarTriangle.b.x, AStarTriangle.b.z));
                      pointList.Add(new Point(AStarTriangle.c.x, AStarTriangle.c.z));
      
                      if (Utility.CheckPointInPolygon(Point, new Polygon.Polygon(pointList)))
                      {
                          return AStarTriangle;
                      }
                  }
                  return new Triangle();
              }
          }
      }
      AStarTools

       

      算法需要用到一些數據 起點 終點  導航網格信息 等等

      我統一保存在一個類中

       

      using UnityEngine;
      
      namespace AStar
      {
          public class AStarData
          {
              /// <summary>
              /// 開始.
              /// </summary>
              public Ponit start;
              /// <summary>
              /// 終點.
              /// </summary>
              public Ponit end;
              /// <summary>
              /// 導航網格信息
              /// </summary>
              public NavMeshInfo navMeshInfo;
      
      
              /// <summary>
              /// 起點所在的三角形
              /// </summary>
              public Triangle startPlace;
              /// <summary>
              /// 終點所在的三角形
              /// </summary>
              public Triangle endPlace;
              /// <summary>
              /// 起點新建三角形
              /// </summary>
              public Triangle startAStarTriangle;
              /// <summary>
              /// 終點新建三角形
              /// </summary>
              public Triangle endAStarTriangle;
      
              public bool Init(Ponit start, Ponit end, NavMeshInfo navMeshInfo)
              {
                  this.start = start;
                  this.end = end;
                  this.navMeshInfo = navMeshInfo;
      
                  startAStarTriangle = new Triangle(start, start, start);
                  endAStarTriangle = new Triangle(end, end, end);
      
                  startPlace = AStarTools.GetAStarTriangleByPoint(start, navMeshInfo.allTriangle);
                  endPlace = AStarTools.GetAStarTriangleByPoint(end, navMeshInfo.allTriangle);
      
                  if (startPlace == new Triangle())
                  {
                      Debug.Log("起點不在導航網格信息中");
                      return false;
                  }
      
                  if (endPlace == new Triangle())
                  {
                      Debug.Log("終點不在導航網格信息中");
                      return false;
                  }
      
                  return true;
              }
          }
      }
      AStarData

       

      最后是我寫的A*算法

       

      using System.Collections.Generic;
      using System.Linq;
      
      namespace AStar
      {
          public delegate void AStarCallback(List<Ponit> list);
      
          public class Pathfinding
          {
              /// <summary>
              /// 數據
              /// </summary>
              AStarData aStarData;
      
      
              /// <summary>
              /// 待計算列表.
              /// </summary>
              List<Triangle> openList;
              /// <summary>
              /// 關閉列表.
              /// </summary>
              List<Triangle> closeList;
      
              /// <summary>
              /// 父級索引.
              /// </summary>
              Dictionary<Triangle, Triangle> parentIndexes;
      
              /// <summary>
              /// G值.
              /// </summary>
              Dictionary<Triangle, float> triangle_G;
              /// <summary>
              /// H值.
              /// </summary>
              Dictionary<Triangle, float> triangle_H;
              /// <summary>
              /// F值.
              /// </summary>
              Dictionary<Triangle, float> triangle_F;
      
              /// <summary>
              /// 回調.
              /// </summary>
              AStarCallback callback;
      
              public void Start(Ponit start, Ponit end, NavMeshInfo navMeshInfo, AStarCallback callback)
              {
                  if (callback == null)
                  {
                      return;
                  }
      
                  aStarData = new AStarData();
      
                  if (aStarData.Init(start, end, navMeshInfo) == false)
                  {
                      return;
                  }
      
      
                  this.callback = callback;
      
      
                  openList = new List<Triangle>();
                  closeList = new List<Triangle>();
                  parentIndexes = new Dictionary<Triangle, Triangle>();
                  triangle_G = new Dictionary<Triangle, float>();
                  triangle_H = new Dictionary<Triangle, float>();
                  triangle_F = new Dictionary<Triangle, float>();
      
                  Core();
              }
      
              /// <summary>
              /// 核心
              /// </summary>
              void Core()
              {
                  openList.Add(aStarData.startAStarTriangle);
      
                  //開始尋路 尋路到終點結束
                  while (!openList.Contains(aStarData.endAStarTriangle) && openList.Count != 0)
                  {
                      Triangle AStarTriangle = GetOpenListMin();
      
                      openList.Remove(AStarTriangle);
      
                      closeList.Add(AStarTriangle);
      
                      Explore(AStarTriangle);
                  }
      
                  List<Triangle> list = new List<Triangle>();
      
                  Triangle T = aStarData.endAStarTriangle;
                  while (parentIndexes.ContainsKey(T) && parentIndexes[T] != null)
                  {
                      list.Add(T);
      
                      T = parentIndexes[T];
                  }
      
                  Callback(list);
              }
      
              /// <summary>
              /// 獲取待計算列表中F值最小的一個.
              /// </summary>
              /// <returns></returns>
              Triangle GetOpenListMin()
              {
                  Triangle AStarTriangle = openList[0];
                  for (int i = 0; i < openList.Count; i++)
                  {
                      if (GetDictionaryValue(triangle_F, AStarTriangle) > GetDictionaryValue(triangle_F, openList[i]))
                      {
                          AStarTriangle = openList[i];
                      }
                  }
      
                  return AStarTriangle;
              }
      
              /// <summary>
              /// 獲取當前三角形周圍的三角形.
              /// </summary>
              /// <param name="current"></param>
              /// <param name="end"></param>
              /// <param name="map"></param>
              void Explore(Triangle current)
              {
                  //獲取當前三角形所有的鄰邊三角形
                  List<Triangle> list = GetRuoundAStarTriangle(current, aStarData);
      
      
                  for (int i = 0; i < list.Count; i++)
                  {
                      Triangle AStarTriangle = list[i];
      
                      //去掉當前三角形
                      if (AStarTriangle == current)
                      {
                          continue;
                      }
      
                      //去掉已經關閉的三角形
                      if (closeList.Contains(AStarTriangle))
                      {
                          continue;
                      }
      
                      //如果不在待檢測的集合  則加入待檢測集合
                      if (!openList.Contains(AStarTriangle))
                      {
                          SetParentIndexes(AStarTriangle, current);
      
                          SetDictionaryValue(triangle_G, AStarTriangle, GetG(AStarTriangle, current));
                          SetDictionaryValue(triangle_H, AStarTriangle, GetH(AStarTriangle));
      
                          openList.Add(AStarTriangle);
                      }
                      //如果在待檢測的集合  則判斷是否修改父級
                      else
                      {
                          float G = GetDictionaryValue(triangle_G, AStarTriangle);
                          float H = GetDictionaryValue(triangle_H, AStarTriangle);
                          float F = GetG(AStarTriangle, current) + GetH(AStarTriangle);
      
                          if (G + H > F)
                          {
                              SetParentIndexes(AStarTriangle, current);
                              SetDictionaryValue(triangle_G, AStarTriangle, GetG(AStarTriangle, current));
                              SetDictionaryValue(triangle_H, AStarTriangle, GetH(AStarTriangle));
      
                              openList.Remove(AStarTriangle);
                          }
                      }
                  }
              }
      
      
      
      
      
              /// <summary>
              /// 獲取G值.
              /// </summary>
              /// <param name="grid"></param>
              /// <param name="parent"></param>
              /// <returns></returns>
              float GetG(Triangle grid, Triangle parent)
              {
                  float distance = Ponit.Distance(grid.centroid, parent.centroid);
      
                  distance += GetDictionaryValue(triangle_G, parent);
      
                  return distance;
              }
      
              /// <summary>
              /// 獲取H值.
              /// </summary>
              /// <param name="grid"></param>
              /// <param name="end"></param>
              /// <returns></returns>
              float GetH(Triangle grid)
              {
                  float distance = Ponit.Distance(grid.centroid, aStarData.end);
      
                  return distance;
              }
      
      
      
      
              /// <summary>
              /// 添加父級索引.
              /// </summary>
              /// <param name="current"></param>
              /// <param name="parent"></param>
              void SetParentIndexes(Triangle current, Triangle parent)
              {
                  if (parentIndexes.ContainsKey(current))
                  {
                      parentIndexes[current] = parent;
                  }
                  else
                  {
                      parentIndexes.Add(current, parent);
                  }
              }
      
      
      
      
              /// <summary>
              /// 回調
              /// </summary>
              /// <param name="listAStarTriangle"></param>
              void Callback(List<Triangle> listAStarTriangle)
              {
                  if (callback == null || listAStarTriangle == null)
                  {
                      return;
                  }
      
      
                  listAStarTriangle.Reverse();
      
                  List<Ponit> list = new List<Ponit>();
      
                  //進距離移動 不超過一個三角形
                  if (listAStarTriangle.Count == 1)
                  {
                      list.Add(aStarData.end);
                      callback(list);
                      return;
                  }
      
                  for (int i = 0; i < listAStarTriangle.Count; i++)
                  {
                      list.Add(listAStarTriangle[i].centroid);
                  }
      
                  callback(list);
      
              }
      
      
      
              /// <summary>
              /// 獲取周圍的三角形
              /// </summary>
              /// <param name="current"></param>
              /// <returns></returns>
              public static List<Triangle> GetRuoundAStarTriangle(Triangle current, AStarData aStarData)
              {
                  //該點為開始點 則獲取該點三角重心來取值
                  if (current.a == aStarData.start && current.b == aStarData.start)
                  {
                      current = aStarData.startPlace;
                  }
      
                  //獲取三角形所有的鄰邊三角形
                  List<Triangle> list = new List<Triangle>();
      
                  list.AddRange(GetListAStarTriangle(current.a, aStarData.navMeshInfo.pointIndexes));
      
                  list.AddRange(GetListAStarTriangle(current.b, aStarData.navMeshInfo.pointIndexes));
      
                  list.AddRange(GetListAStarTriangle(current.c, aStarData.navMeshInfo.pointIndexes));
      
                  //去掉重復的三角形
                  list = list.Distinct().ToList();
      
                  if (list.Contains(aStarData.endPlace))
                  {
                      list.Add(aStarData.endAStarTriangle);
                  }
      
                  return list;
              }
      
              /// <summary>
              /// 獲取頂點對應的三角形列表.
              /// </summary>
              /// <param name="ponit</param>
              /// <param name="map"></param>
              /// <returns></returns>
              public static List<Triangle> GetListAStarTriangle(Ponit ponit, Dictionary<Ponit, List<Triangle>> pointIndexes)
              {
                  List<Triangle> list = null;
      
                  if (pointIndexes == null)
                  {
                      return list;
                  }
      
                  if (pointIndexes.ContainsKey(ponit))
                  {
                      list = pointIndexes[ponit];
                  }
      
                  return list;
              }
      
              /// <summary>
              /// 設置字典的值.
              /// </summary>
              /// <param name="data"></param>
              /// <param name="key"></param>
              /// <param name="value"></param>
              public static void SetDictionaryValue(Dictionary<Triangle, float> data, Triangle key, float value)
              {
                  if (data == null)
                  {
                      return;
                  }
      
                  if (data.ContainsKey(key))
                  {
                      data[key] = value;
                  }
                  else
                  {
                      data.Add(key, value);
                  }
              }
      
              /// <summary>
              /// 獲取字典的值.
              /// </summary>
              /// <param name="data"></param>
              /// <param name="key"></param>
              /// <returns></returns>
              public static float GetDictionaryValue(Dictionary<Triangle, float> data, Triangle key)
              {
                  if (data == null)
                  {
                      return 0;
                  }
      
                  if (!data.ContainsKey(key))
                  {
                      data.Add(key, 0);
                  }
                  return data[key];
              }
          }
      }
      AStar

       

      我們創建一個Capsule游戲對象 

      讓他成為我們需要移動的主角

      掛上簡單的移動代碼

       

      using UnityEngine;
      using System.Collections;
      using System.Collections.Generic;
      using AStar;
      
      public delegate void CharacterMoveCallback();
      
      /// <summary>
      /// 角色移動
      /// </summary>
      public class CharacterMove : MonoBehaviour
      {
          /// <summary>
          /// 目標
          /// </summary>
          public Vector3 target;
          /// <summary>
          /// 速度
          /// </summary>
          public float speed  =  2;
          /// <summary>
          /// 目標距離
          /// </summary>
          public float distance = 0.05f;
      
      
      
          /// <summary>
          /// 移動經過的點
          /// </summary>
          List<Vector3> points;
          /// <summary>
          /// 回調
          /// </summary>
          CharacterMoveCallback callback;
      
          private void Awake()
          {
              target = transform.position;
          }
      
      
          public void Move(Ponit vector3, CharacterMoveCallback callback = null)
          {
              target = Ponit.Convert(vector3);
              this.callback = callback;
          }
      
          public void Move(List<Ponit> points, CharacterMoveCallback callback = null)
          {
              this.points = new List<Vector3>();
      
              for (int i = 0; i < points.Count; i++)
              {
                  this.points.Add(Ponit.Convert(points[i]));
              }
              this.callback = callback;
      
              GetTarget();
          }
      
          void GetTarget()
          {
              if (points != null && points.Count >= 1)
              {
                  target = points[0];
                  points.Remove(points[0]);
      
                  Debug.Log("前進點 :" + target);
              }
          }
      
          void Callback()
          {
              if (callback != null)
              {
                  callback();
                  callback = null;
              }
          }
      
          void Update()
          {
              //當前位置與目標距離小于間距 移動停止
              if (Vector3.Distance(target, transform.position) < distance)
              {
                  Callback();
                  return;
              }
      
              //獲取移動向量;
              Vector3 vector = target - transform.position;
              vector = vector.normalized;
      
              //移動
              transform.position += vector * Time.deltaTime * speed;
      
              //如果到達目標點則替換下一個目標
              if (Vector3.Distance(target, transform.position) < distance)
              {
                  GetTarget();
              }
      
          }
      }
      CharacterMove

       

      再掛上一個簡單的開始測試代碼

       

      using UnityEngine;
      using AStar;
      using System.Collections.Generic;
      
      public class test : MonoBehaviour
      {
          NavMeshInfo navMeshInfo;
      
          void Start()
          {
              NavMeshLoad navMeshLoad = new NavMeshLoad();
      
              navMeshInfo = navMeshLoad.Load(Application.dataPath + "/AStar/obj/test.obj");
          }
      
          private void Update()
          {
              if (Input.GetMouseButtonUp(0))
              {
                  Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
      
                  RaycastHit hit;//
                  if (Physics.Raycast(ray, out hit))//函數是對射線碰撞的檢測
                  {
                      Vector3 Point = hit.point;//得到碰撞點的坐標
      
                      Debug.Log("開始點: " + transform.position);
                      Debug.Log("目標點: " + Point);
                      Debug.Log("目標點對象: " + hit.transform.name);
      
                      Vector3 start = transform.position;
                      Vector3 end = Point;
      
                      NavMeshHit tmpNavMeshHit;
      
                      if (NavMesh.SamplePosition(start, out tmpNavMeshHit, 5.0f, NavMesh.AllAreas))
                      {
                          start = tmpNavMeshHit.position;
                      }
      
                      Debug.Log("修改后 開始點: " + start);
      
                      StartNavigation(start, end, navMeshInfo);
                  }
              }
          }
      
      
          public void StartNavigation(Vector3 start, Vector3 end, NavMeshInfo navMeshInfo)
          {
              if (navMeshInfo == null)
              {
                  return;
              }
      
              Pathfinding pathfinding = new Pathfinding();
      
              Ponit startPonit = new Ponit(start);
              Ponit endPonit = new Ponit(end);
      
      
              pathfinding.Start(startPonit, endPonit, navMeshInfo, (List<Ponit> list) =>
             {
                 CharacterMove controller = GetComponent<CharacterMove>();
      
                 controller.Move(list, () =>
                 {
                     Debug.Log("尋路結束");
                 });
      
             });
          }
      
      
      }
      test

       

      運行 點擊地面  就可以看到Capsule尋路自動行走了

       

      工程下載:

      鏈接: https://pan.baidu.com/s/1qY_zUrqIHB6W4K8wC3PxWQ 密碼: iipb

       

      posted @ 2018-04-09 11:39  鄒強  閱讀(1656)  評論(6)    收藏  舉報
      主站蜘蛛池模板: 亚洲男同志网站| 老司机免费的精品视频| 欧美日韩一线| 成人免费A级毛片无码网站入口| AV最新高清无码专区| 精品久久久久久无码人妻蜜桃 | 少妇激情a∨一区二区三区 | 99RE8这里有精品热视频| 国产在线无码不卡播放| 精品国产精品午夜福利| 99在线视频免费观看| 国产精品一区二区三区黄色| 六十路熟妇乱子伦| 国产福利午夜十八禁久久| 恩平市| 国产台湾黄色av一区二区| 深夜在线观看免费av| 一本一道av无码中文字幕麻豆| 黑人av无码一区| 国产超碰无码最新上传| 欧美日韩国产亚洲沙发| 最新永久免费AV无码网站| 丰满少妇被猛烈进出69影院| 国产成人精品无码一区二区老年人| 国产极品精品自在线不卡| 无码国产精品一区二区免费式芒果 | 男人又大又硬又粗视频| 欧美深度肠交惨叫| 亚洲欧洲日产国码无码网站| 九九在线精品国产| 绍兴市| 69精品丰满人妻无码视频a片| 久久国产福利播放| 少妇人妻偷人精品系列| 少妇高潮水多太爽了动态图| 国产中文99视频在线观看| 丰满老熟妇好大bbbbb| 国内精品久久久久影视| 久久久综合香蕉尹人综合网| 久久国内精品自在自线91| 重口SM一区二区三区视频|