/// <summary>
        /// True if the node has any blocked connections.
        /// For 4 and 8 neighbours the 4 axis aligned connections will be checked.
        /// For 6 neighbours all 6 neighbours will be checked.
        ///
        /// Internal method used for erosion.
        /// </summary>
        ///

        bool HandingErosionOfOfAnyFalseConnections(GridGraphNode node)
        {
            // Check the 6 hexagonal connections
            if (neighbours == NeighboursNumType.Six)
            {
                for (int i = 0; i < 6; i++)
                {
                    if (!HasConnectionOfNode(node, hexagonNeighbourNodeIndices[i]))
                    {
                        return(true);
                    }
                }
            }
            else
            {
                // Check the four axis aligned connections
                for (int i = 0; i < 4; i++)
                {
                    if (!HasConnectionOfNode(node, i))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
        /// <summary>
        /// 处理单个节点的图层冲突信息
        /// </summary>
        /// <param name="node"></param>
        /// <param name="x"></param>
        /// <param name="z"></param>
        public void HandingCollisonOfSingleNode(GridGraphNode node, int width, int depth)
        {
            float offestNum = 0.5f;

            node.position = (Int3)(Matrix.MultiplyPoint3x4(new Vector3(width + offestNum, 0, depth + offestNum)));

            bool       walkAble = false;
            RaycastHit hitInfo;

            //处理高度和坡度检查
            Vector3 position = graphicCollision.CheckHeight((Vector3)node.position, out hitInfo, out walkAble);

            node.position = (Int3)position;

            if (walkAble && graphicCollision.heightCheck)
            {
                if (hitInfo.normal != Vector3.zero)
                {
                    float angle = Vector3.Dot(hitInfo.normal.normalized, graphicCollision.graphUp);

                    if (angle < Mathf.Cos(maxSlope * Mathf.Deg2Rad))
                    {
                        walkAble = false;
                    }
                }
            }

            //检查障碍物
            bool checkObstacles = graphicCollision.Check((Vector3)node.position);

            node.walkAble = checkObstacles && walkAble;
            //   Debug.Log("ConvertedData::" + ConvertedData + ", x::" + x + ", z::" + z + ",node.walkAble::" + node.walkAble);
        }
Пример #3
0
        public override void OnDrawGizmos(bool drawFlag)
        {
            if (!drawFlag || nodes == null || nodes.Length != nodesInWidth * nodesInDepth)
            {
                return;
            }

            //绘制outLineBound
            Gizmos.color  = Color.white;
            Gizmos.matrix = outLineBoundMatrix;
            Gizmos.DrawWireCube(Vector3.zero, new Vector3(gridSize.x, 0, gridSize.y));

            Gizmos.matrix = Matrix4x4.identity;

            //绘制网格走可走区域
            //   Debug.Log("depth::" + nodesInDepth + ",width::" + nodesInWidth);
            Gizmos.color = Color.green;
            for (int depth = 0; depth < nodesInDepth; depth++)
            {
                for (int width = 0; width < nodesInWidth; width++)
                {
                    var node = nodes[depth * nodesInWidth + width];
                    //  Debug.Log("index::" + (depth * nodesInWidth + width) + "node::" + node.nodeIndex + ", depth::" + depth + ", width::" + width + ",node.walkAble::" + node.walkAble);

                    if (!node.walkAble)
                    {
                        continue;
                    }

                    Vector3 position = (Vector3)node.position;
                    for (int i = 0; i < 8; i++)
                    {
                        if (node.GetConnectionInternal(i))
                        {
                            GridGraphNode other = nodes[node.nodeIndex + neighbourNodeOffsets[i]];
                            Gizmos.DrawLine(position, (Vector3)other.position);
                            //  Debug.Log("connect::" + other.nodeIndex  + ".node::" + node.nodeIndex);
                        }
                    }
                    //   Debug.Log("node::" + node.nodeIndex + ", depth::" + depth + ", width::" + width + ",node.walkAble::" + node.walkAble );
                }
            }


            Gizmos.color = Color.blue;
            for (int i = 0; i < nodes.Length; i++)
            {
                if (nodes[i].walkAble)
                {
                    Gizmos.color = Color.red;
                }
                else
                {
                    Gizmos.color = Color.gray;
                }
                Gizmos.DrawCube((Vector3)nodes[i].position, Vector3.one * 0.5f);
            }
        }
        /// <summary>
        /// 扫描图形内部
        /// </summary>
        public override void ScanGraphicInternal()
        {
            if (nodeSize <= 0) //默认设置为最小数值
            {
                nodeSize = 0.1f;
            }

            UpdateBaseArgs();

            if (nodesInWidth > 1024)
            {
                Debug.LogError("the grid's sides(nodesInWidth) is longer than 1024 nodes!!");
                return;
            }

            if (nodesInDepth > 1024)
            {
                Debug.LogError("the grid's sides(nodesInDepth) is longer than 1024 nodes!!");
                return;
            }

            //设置偏移值和代价
            SetValuesOfOffsetsAndCosts();

            //设置当前当前的网格图层对象
            GridGraphNode.SetGridNavGraph(this.graphIndex, this);

            if (nodes != null)
            {
                for (int i = 0; i < nodes.Length; i++)
                {
                    nodes[i].Destory();
                }
            }

            //创建节点
            nodes = new GridGraphNode[nodesInWidth * nodesInDepth];

            for (int i = 0; i < nodes.Length; i++)
            {
                nodes[i]            = new GridGraphNode();
                nodes[i].graphIndex = this.graphIndex;
                nodes[i].nodeIndex  = i;
            }

            //处理图形冲突,高度坡度检查、障碍物等
            HandingGraphicCollision();

            //处理节点间的连接
            HandingNodesConnections();

            //处理侵蚀的部分
            ErosionNodeOfArea(0, 0, nodesInWidth, nodesInDepth);
        }
        public virtual bool IsValidConnection(GridGraphNode n1, GridGraphNode n2)
        {
            if (!n1.walkAble || !n2.walkAble)
            {
                return(false);
            }

            if (maxDiffPosition > 0 && Mathf.Abs(n1.position[useAxisOfMaxDiffPosition] - n2.position[useAxisOfMaxDiffPosition]) > maxDiffPosition * Int3.Precision)
            {
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// 查看节点是否有连接
        /// </summary>
        /// <param name="node"></param>
        /// <param name="dir"></param>
        /// <returns></returns>
        public bool HasConnectionOfNode(GridGraphNode node, int dir)
        {
            if (!node.GetConnectionInternal(dir))
            {
                return(false);
            }
            if (node.EdgeNode)
            {
                //算出当前的index的行列
                int nodeIndex = node.nodeIndex;
                int depth     = nodeIndex / nodesInWidth;
                int width     = nodeIndex - depth * nodesInWidth;

                return(HasConnectionOfNode(nodeIndex, width, depth, dir));
            }
            else
            {
                return(true);
            }
        }
Пример #7
0
 bool HandingErosionOfOfAnyFalseConnections(GridGraphNode node)
 {
     if (neighbours != NeighboursNumType.Six)
     {
         for (int i = 0; i < 4; i++)
         {
             if (!HasConnectionOfNode(node, i))
             {
                 return(true);
             }
         }
     }
     else
     {
         for (int i = 0; i < 6; i++)
         {
             if (!HasConnectionOfNode(node, hexagonNeighbourNodeIndices[i]))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
        public void HandingCollisonOfSingleNode(GridGraphNode[] nodes, int width, int depth, GridGraphNode node)
        {
            node.ResetConnectionsInternal();

            //All connections are disabled if the node is not walkable
            if (!node.walkAble)
            {
                return;
            }

            int index = node.nodeIndex;

            if (neighbours == NeighboursNumType.Four || neighbours == NeighboursNumType.Eight)
            {
                // Reset the buffer
                if (buffers == null)
                {
                    buffers = new int[4];
                }
                else
                {
                    for (int i = 0; i < 4; i++)
                    {
                        buffers[i] = 0;
                    }
                }

                for (int i = 0, j = 3; i < 4; j = i, i++)
                {
                    int nx = width + neighbourNodeXOffsets[i];
                    int nz = depth + neighbourNodeZOffsets[i];

                    if (nx < 0 || nz < 0 || nx >= nodesInWidth || nz >= nodesInDepth)
                    {
                        continue;
                    }

                    var other = nodes[index + neighbourNodeOffsets[i]];

                    if (IsValidConnection(node, other))
                    {
                        node.SetConnectionInternal(i, true);

                        // Mark the diagonal/corner adjacent to this connection as used
                        buffers[i]++;
                        buffers[j]++;
                    }
                    else
                    {
                        node.SetConnectionInternal(i, false);
                    }
                }

                // Add in the diagonal connections
                if (neighbours == NeighboursNumType.Eight)
                {
                    if (cutCornersOfObstacles)
                    {
                        for (int i = 0; i < 4; i++)
                        {
                            // If at least one axis aligned connection
                            // is adjacent to this diagonal, then we can add a connection
                            if (buffers[i] >= 1)
                            {
                                int nx = width + neighbourNodeXOffsets[i + 4];
                                int nz = depth + neighbourNodeZOffsets[i + 4];

                                if (nx < 0 || nz < 0 || nx >= width || nz >= depth)
                                {
                                    continue;
                                }

                                GridGraphNode other = nodes[index + neighbourNodeOffsets[i + 4]];

                                node.SetConnectionInternal(i + 4, IsValidConnection(node, other));
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < 4; i++)
                        {
                            // If exactly 2 axis aligned connections is adjacent to this connection
                            // then we can add the connection
                            //We don't need to check if it is out of bounds because if both of the other neighbours are inside the bounds this one must be too
                            if (buffers[i] == 2)
                            {
                                GridGraphNode other = nodes[index + neighbourNodeOffsets[i + 4]];

                                node.SetConnectionInternal(i + 4, IsValidConnection(node, other));
                            }
                        }
                    }
                }
            }
            else
            {
                // Hexagon layout

                // Loop through all possible neighbours and try to connect to them
                for (int j = 0; j < hexagonNeighbourNodeIndices.Length; j++)
                {
                    var i = hexagonNeighbourNodeIndices[j];

                    int nx = width + neighbourNodeXOffsets[i];
                    int nz = depth + neighbourNodeZOffsets[i];

                    if (nx < 0 || nz < 0 || nx >= width || nz >= depth)
                    {
                        continue;
                    }

                    var other = nodes[index + neighbourNodeOffsets[i]];

                    node.SetConnectionInternal(i, IsValidConnection(node, other));
                }
            }
        }