Esempio n. 1
0
    /// <summary>
    /// 得到指定点周围的八个点
    /// </summary>
    private void OnGetStartBorderPos(gridItem gridItem_)
    {
        // 得到周围格子中位置最小点(目标格子相邻左下角的格子)
        float findMinX = gridItem_.gridPos.x - (1 + space);
        float findMinZ = gridItem_.gridPos.z - (1 + space);

        // 得到周围的格子
        for (int i = 0; i < 3; ++i)
        {
            for (int j = 0; j < 3; ++j)
            {
                float x = i * (1 + space);
                float z = j * (1 + space);

                Vector3 nPos = new Vector3(findMinX + x, 0, findMinZ + z);

                // 在格子列表中查找格子
                gridItem gridItem = null;
                foreach (KeyValuePair <GameObject, gridItem> val in gridDict)
                {
                    // 通过位置找到相邻格子
                    if (val.Value.gridPos == nPos)
                    {
                        // 过滤掉自己和障碍物和寻到的格子
                        if (val.Value.gridObj != startPosObj && !barrierGridDict.ContainsKey(val.Value.gridObj) && !pathList.ContainsKey(val.Value.gridObj))
                        {
                            gridItem = val.Value;
                            break;
                        }
                    }
                }

                // 如果格子存在,填充到零时列表中
                if (gridItem != null)
                {
                    //Debug.Log("找到 " + nPos);
                    borderGridList.Add(gridItem);
                }
                else
                {
                    //Debug.Log("没有找到 " + nPos);
                }
            }
        }
    }
Esempio n. 2
0
    /// <summary>
    /// 得到相邻格子的移动成本
    /// </summary>
    private void OnGetBorderGridMoveCost(gridItem startPos_)
    {
        for (int i = 0; i < borderGridList.Count; ++i)
        {
            gridItem item = borderGridList[i];

            if (item.gridPos.x == startPos_.gridPos.x || item.gridPos.z == startPos_.gridPos.z)
            {
                //Debug.Log("成本小 " + item.gridObj.name);
                item.moveCost = 10;
            }
            else
            {
                //Debug.Log("成本大 " + item.gridObj.name);
                item.moveCost = 14;
            }
        }
    }
Esempio n. 3
0
    /// <summary>
    /// 创建格子
    /// </summary>
    private void OnCreatGrid()
    {
        for (int i = 0; i < xNum; ++i)
        {
            for (int j = 0; j < yNum; ++j)
            {
                float posX = i + (i * space);
                float posY = 0;
                float posZ = j + (j * space);

                GameObject gridObj = GameObject.Instantiate(objTemp);
                gridObj.name  = "Grid   X=" + posX + " Z=" + posZ;
                gridObj.layer = LayerMask.NameToLayer("Grid");
                gridObj.gameObject.SetActive(true);
                gridObj.transform.SetParent(parent.transform);
                gridObj.transform.position = new Vector3(posX, posY, posZ);

                gridDict[gridObj] = new gridItem(new Vector3(posX, posY, posZ), gridObj);
            }
        }
    }
Esempio n. 4
0
    /// <summary>
    /// 得到相邻格子到目标到的长度
    /// </summary>
    private void OnGetBorderGridTargetLength(gridItem targetGridItem_)
    {
        for (int i = 0; i < borderGridList.Count; ++i)
        {
            gridItem item = borderGridList[i];

            // ---------曼哈顿估价法(自己的实现)--------- (乘10是为了简化估价计算)
            // PS:计算估价有三种算法:曼哈顿估价法、几何估价法、对角线估价法
            // 曼哈顿估价法和我这里实现是一样,不过有些问题,如果两个格子在同一行(x轴相同),并且中间隔了障碍物。这个时候在起始点会多寻出点
            // 具体原因:是因为查找相邻八个格子顺序问题,导致先找到的格子会被先使用。暂时没有想到更好的办法
            //float xLength = Mathf.Abs(targetGridItem_.gridPos.x - item.gridPos.x) * 10;
            //float zLength = Mathf.Abs(targetGridItem_.gridPos.z - item.gridPos.z) * 10;
            //item.targetLength = (int)(xLength + zLength);
            // ---------曼哈顿估价法(自己的实现)---------


            // ---------对角线估价法(网上的算法)---------
            // 为了解决上面曼哈顿算法的问题和使计算步长更优,这里就使用对角线算法。
            // 当然还有几何算法,但是个人感觉不是最优的,因为对角线是集合了曼哈顿和几何算法思路的。
            // 对角线估价法,暂时还没弄的很明白,乘14和乘10应该也是为了简化计算和计算移动代价没关系
            float cntX = Mathf.Abs(item.gridPos.x - targetGridItem_.gridPos.x);
            float cntZ = Mathf.Abs(item.gridPos.z - targetGridItem_.gridPos.z);

            if (cntX > cntZ)
            {
                item.targetLength = (int)(14 * cntZ + 10 * (cntX - cntZ));
            }
            else
            {
                item.targetLength = (int)(14 * cntX + 10 * (cntZ - cntX));
            }
            // ---------对角线估价法(网上的算法)---------

            // 计算权重(因为这里是得到计算权重值的最后一个参数)
            item.weight = item.moveCost + item.targetLength;
            //Debug.Log(item.gridObj.name + " 步长 " + item.targetLength);
        }
    }
Esempio n. 5
0
 /// <summary>
 /// 添加格子到路径列表中
 /// </summary>
 private void OnAddPaht(gridItem pathGrid_)
 {
     // 加入新的路径
     pathList[pathGrid_.gridObj] = pathGrid_;
 }
Esempio n. 6
0
    /// <summary>
    /// 执行寻路
    /// </summary>
    private void OnPlayerFindPath()
    {
        // 清空相邻格子
        borderGridList.Clear();

        gridItem startGridItem  = gridDict[startPosObj];
        gridItem targetGridItem = gridDict[TargetPosObj];

        // 得到八个相邻格子
        OnGetStartBorderPos(startGridItem);
        // 得到相邻格子的移动成本
        OnGetBorderGridMoveCost(startGridItem);
        // 得到相邻格子到目标到的步长
        OnGetBorderGridTargetLength(targetGridItem);

        // 得到下一个移动点(权重最小的格子)
        gridItem newStarGridItem = null;

        for (int i = 0; i < borderGridList.Count; ++i)
        {
            gridItem item = borderGridList[i];

            //Debug.Log("权重 " + item.weight);
            if (newStarGridItem != null)
            {
                if (item.weight < newStarGridItem.weight)
                {
                    newStarGridItem = item;
                }
            }
            else
            {
                newStarGridItem = item;
            }
        }

        //Debug.Log("权重最小 "+ newStarGridItem.gridObj.name +" " + newStarGridItem.weight);

        // 将新的路径点加入路径列表并更新起始点
        if (newStarGridItem != null)
        {
            // ------------判断是否需要继续寻路------------
            bool isFindPath = true;
            for (int i = 0; i < borderGridList.Count; ++i)
            {
                gridItem item = borderGridList[i];
                if (item.gridObj == targetGridItem.gridObj)
                {
                    isFindPath = false;
                    break;
                }
            }

            if (isFindPath)
            {
                startPosObj = newStarGridItem.gridObj;
                OnAddPaht(newStarGridItem);
                // 将路径格子改变颜色(调试使用功能)
                OnSetModelMaterColor(newStarGridItem.gridObj, Color.gray);

                OnPlayerFindPath();
            }

            // ------------判断是否需要继续寻路------------
        }
    }