示例#1
0
    private List <路径区块> 寻找周围路径(路径区块 中心路径点, List <路径区块> 关闭列表, 路径区块[,] 导航数据, AI导航 请求者)
    {
        List <路径区块> 列表 = new List <路径区块>();

        for (int i = 0; i < 9; i++)
        {
            int x = 中心路径点.x - 导航数据[0, 0].x;
            int y = 中心路径点.y - 导航数据[0, 0].y;
            switch (i)
            {
            case 0: break;

            case 1: y++; break;

            case 2: x++; break;

            case 3: y--; break;

            case 4: x--; break;

            case 5: x++; y++; break;

            case 6: x++; y--; break;

            case 7: x--; y--; break;

            case 8: x--; y++; break;
            }

            try
            {
                if (!导航数据[x, y].障碍物 && !关闭列表.Contains(导航数据[x, y]))
                {
#if 可视化
                    if (请求者.调试模式)
                    {
                        导航烘焙.烘焙数据[x + 导航数据[0, 0].x, y + 导航数据[0, 0].y].GetComponent <SpriteRenderer>().color = Color.green;
                    }
#endif
                    列表.Add(导航数据[x, y]);
                }
            }
            catch { continue; }
        }
        return(列表);
    }
示例#2
0
 public 导航数据(AI导航 发起人, 路径区块[,] 地图数据, 路径区块 起点)
 {
     this.发起人  = 发起人;
     this.地图数据 = 地图数据;
     this.起点   = 起点;
 }
示例#3
0
    public 路径区块[,] 导航权重绘制(导航区块 起点, 导航区块 终点, AI导航 请求者)
    {
        if (!终点)
        {
#if 消息台
            if (请求者.调试模式)
            {
                Debug.LogWarning("导航烘焙:参数错误):尝试修复>>1.检查目标是否越界或卡于障碍物中", 请求者);
            }
#endif
            return(null);
        }

        //确定需复制的数据范围
        int 长   = Mathf.Abs(终点.路径数据.x - 起点.路径数据.x) + 烘焙补偿;
        int 宽   = Mathf.Abs(终点.路径数据.y - 起点.路径数据.y) + 烘焙补偿;
        int 原点x = Mathf.Min(起点.路径数据.x, 终点.路径数据.x) - 烘焙补偿 / 2;
        int 原点y = Mathf.Min(起点.路径数据.y, 终点.路径数据.y) - 烘焙补偿 / 2;

        //防止烘焙补偿越界
        #region 烘焙补偿优化
        if (原点x < 0)
        {
            长  += 原点x;
            原点x = 0;
        }
        if (原点y < 0)
        {
            宽  += 原点y;
            原点y = 0;
        }
        int 超长 = 长 + 原点x + 1 - 烘焙数据.GetLength(0);
        if (超长 > 0)
        {
            长 -= 超长;
        }
        int 超宽 = 宽 + 原点y + 1 - 烘焙数据.GetLength(1);
        if (超宽 > 0)
        {
            宽 -= 超宽;
        }
        #endregion

        路径区块[,] 路径数据 = new 路径区块[长, 宽];

        for (int y = 宽 - 1; y >= 0; y--)
        {
            for (int x = 长 - 1; x >= 0; x--)
            {
                路径数据[x, y] = new 路径区块(烘焙数据[x + 原点x, y + 原点y].路径数据);     //复制导航烘焙数据
                if (!路径数据[x, y].障碍物)
                {
#if 可视化
                    if (请求者.调试模式)
                    {
                        if (x * y == 0 || x == 长 - 1 || y == 宽 - 1)
                        {
                            烘焙数据[x + 原点x, y + 原点y].GetComponent <SpriteRenderer>().color = Color.yellow;
                        }
                        else
                        {
                            烘焙数据[x + 原点x, y + 原点y].GetComponent <SpriteRenderer>().color = Color.white;
                        }
                    }
#endif
                    路径数据[x, y].权重初始化(1, (烘焙数据[x + 原点x, y + 原点y].transform.position - 终点.transform.position).sqrMagnitude);      //计算【路径区块】终点距离权重
                }
            }
        }
        return(路径数据);
    }
示例#4
0
    public Stack <路径区块> 导航(路径区块 起点, 路径区块[,] 导航数据, AI导航 请求者)
    {
        if (起点 == null || 导航数据 == null)
        {
#if 消息台
            if (请求者.调试模式)
            {
                Debug.LogWarning("导航:参数错误):尝试修复>>1.检查AI是否越界或卡在障碍物中", 请求者);
            }
#endif
            return(null);
        }

        List <路径区块>  开启列表  = new List <路径区块>();
        List <路径区块>  关闭列表  = new List <路径区块>();
        Stack <路径区块> 路径列表  = new Stack <路径区块>();    //栈结构便于正向输出路径
        路径区块         当前路径点 = 起点;
        当前路径点.起点距离 = 0;
        开启列表.Add(当前路径点);

        while (开启列表.Count != 0)
        {
            路径区块 临时路径点 = 当前路径点;
            开启列表.Remove(当前路径点);
            关闭列表.Add(当前路径点);

            List <路径区块> 周围路径 = 寻找周围路径(当前路径点, 关闭列表, 导航数据, 请求者);
            foreach (路径区块 路径点 in 周围路径)
            {
                float 距离 = 当前路径点 - 路径点;     //计算【路径区块】起点距离权重
                if (!开启列表.Contains(路径点))
                {
                    路径点.一个路径点 = 当前路径点;
                    路径点.起点距离  = 当前路径点.起点距离 + 距离;
                    路径点.总距离   = 路径点.起点距离 + 路径点.终点距离;
                    开启列表.Add(路径点);
                }
                else if (路径点.起点距离 > 当前路径点.起点距离 + 距离)
                {
                    路径点.一个路径点 = 当前路径点;
                    路径点.起点距离  = 当前路径点.起点距离 + 距离;
                    路径点.总距离   = 路径点.起点距离 + 路径点.终点距离;
                }
            }
            当前路径点 = 寻找最小终点距离(开启列表);
            //录入路径
            if (当前路径点 == null)
            {
#if 消息台
                if (请求者.调试模式)
                {
                    Debug.LogWarning("导航:无法获取最小路径):尝试修复>>1.检测【路径区块】距离权重值 2.检测是否无可走路径", 请求者);
                }
#endif
                return(null);
            }

            if (当前路径点.终点距离 == 0)
            {
                do
                {
#if 可视化
                    if (请求者.调试模式)
                    {
                        导航烘焙.烘焙数据[当前路径点.x, 当前路径点.y].GetComponent <SpriteRenderer>().color = Color.blue;
                    }
#endif
                    路径列表.Push(当前路径点);
                    当前路径点 = 当前路径点.一个路径点;
                } while (当前路径点.一个路径点 != null);
                break;
            }
        }
        return(路径列表);
    }