public static void CellTester(Vector3 origin, AgentProperties properties)
        {
            Graph graph;

            if (TryGetGraph(ToChunkPosition(origin), properties, out graph) == false || graph.canBeUsed == false)
            {
                return;
            }

            Cell    cell;
            bool    outsideCell;
            Vector3 closestPosToCell;

            graph.GetClosestCell(origin, out cell, out outsideCell, out closestPosToCell);

            foreach (var pair in cell.dataContentPairs)
            {
                Debuger_K.AddLine(pair.Key, Color.magenta);

                if (pair.Value == null)
                {
                    continue;
                }

                Cell connection = pair.Value.connection;
                Debuger_K.AddLabel(pair.Key.centerV3, connection.Contains(pair.Key));
            }
        }
        void Update()
        {
            if (properties == null)
            {
                return;
            }

            RaycastHit raycastHit;

            if (!Physics.Raycast(transform.position, Vector3.down, out raycastHit, 10))
            {
                return;
            }

            Vector3 p = raycastHit.point;

            Debug.DrawLine(transform.position, p, Color.red);

            //Debuger_K.ClearGeneric();

            RaycastHitNavMesh raycastHitNavMesh;

            for (int i = 0; i < tests; i++)
            {
                float x = Mathf.Cos((i / (float)tests) * 2 * Mathf.PI);
                float z = Mathf.Sin((i / (float)tests) * 2 * Mathf.PI);

                //var q = Quaternion.LookRotation(transform.forward + new Vector3(x, 0, z), Vector3.up);

                PathFinder.Raycast(p, new Vector3(x, 0, z), properties, out raycastHitNavMesh);
                if (raycastHitNavMesh.isOnGraph)
                {
                    Debuger_K.AddLine(p, raycastHitNavMesh.point, Color.blue);
                    Debuger_K.AddLabel(raycastHitNavMesh.point, "H");
                }
            }

            //PathFinder.Raycast(p, transform.forward * -1, properties, out raycastHitNavMesh);
            //if (raycastHitNavMesh.isOnGraph) {
            //    Debuger_K.AddLine(p, raycastHitNavMesh.point, Color.blue);
            //    Debuger_K.AddLabel(raycastHitNavMesh.point, "B");
            //}
            //PathFinder.Raycast(p, transform.transform.right * -1, properties, out raycastHitNavMesh);
            //if (raycastHitNavMesh.isOnGraph) {
            //    Debuger_K.AddLine(p, raycastHitNavMesh.point, Color.blue);
            //    Debuger_K.AddLabel(raycastHitNavMesh.point, "L");
            //}
            //PathFinder.Raycast(p, transform.right, properties, out raycastHitNavMesh);
            //if (raycastHitNavMesh.isOnGraph) {
            //    Debuger_K.AddLine(p, raycastHitNavMesh.point, Color.blue);
            //    Debuger_K.AddLabel(raycastHitNavMesh.point, "R");
            //}
        }
        private void GeneratePaths()
        {
            CellPath path = new CellPath(startCell, start_v3);

            if (startCell == endCell)
            {
                potentialPaths.Add(path);
                return;
            }

#if UNITY_EDITOR
            float totalDist = Debuger_K.doDebug ? Vector3.Distance(start_v3, end_v3) : 0f;
#endif

            path.h = EuclideanDistance(start_v3);
            excluded.Clear();
            excluded.Add(startCell);

            foreach (var connection in startCell.connections)
            {
                CellPath newPath = new CellPath(path, connection);
                newPath.g = connection.Cost(properties, ignoreCrouchCost);
                if (connection is CellContentPointedConnection)
                {
                    newPath.h = EuclideanDistance((connection as CellContentPointedConnection).exitPoint);
                }
                else
                {
                    newPath.h = EuclideanDistance(connection.connection);
                }
                AddCellNode(newPath);
            }

            int limit = 0;
            while (true)
            {
                limit++;
                if (limit > 1500)
                {
                    Debug.Log("limit > 1500");
                    break;
                }

                CellPath current = TakeCellNode();
                if (current == null)
                {
                    break;
                }

                Cell currentCell = current.last;

                if (currentCell == endCell)
                {
                    potentialPaths.Add(current);
#if UNITY_EDITOR
                    if (Debuger_K.doDebug)
                    {
                        float lerped = Mathf.InverseLerp(0, totalDist, Vector3.Distance(end_v3, currentCell.centerV3));
                        Debuger_K.AddPath(current.path[current.path.Count - 2].centerV3 + Vector3.up, current.path[current.path.Count - 1].centerV3 + Vector3.up, new Color(lerped, 1 - lerped, 0, 1f));
                    }
#endif
                    if (potentialPaths.Count >= maxPaths)
                    {
                        break;
                    }
                    else
                    {
                        continue;
                    }
                }

                if (excluded.Contains(currentCell))
                {
                    continue;
                }
                else
                {
                    excluded.Add(currentCell);
                }

#if UNITY_EDITOR
                if (Debuger_K.doDebug)
                {
                    float lerped = Mathf.InverseLerp(0, totalDist, Vector3.Distance(end_v3, currentCell.centerV3));
                    Debuger_K.AddPath(current.path[current.path.Count - 2].centerV3 + (Vector3.up * 0.3f), current.path[current.path.Count - 1].centerV3 + (Vector3.up * 0.3f), new Color(lerped, 1 - lerped, 0, 1f));
                }
#endif

                foreach (var connection in currentCell.connections)
                {
                    Cell newCell = connection.connection;

                    if (current.Contains(newCell) == false)
                    {
                        CellPath newPath = new CellPath(current, connection);
#if UNITY_EDITOR
                        if (Debuger_K.debugPath)
                        {
                            Debuger_K.AddLabel(SomeMath.MidPoint(current.last.centerV3, newCell.centerV3), connection.Cost(properties, ignoreCrouchCost), DebugGroup.path);
                        }
#endif

                        newPath.g = current.g + connection.Cost(properties, ignoreCrouchCost);
                        if (connection is CellContentPointedConnection)
                        {
                            newPath.h = EuclideanDistance((connection as CellContentPointedConnection).exitPoint);
                            //Debuger3.AddLabel((connection as CellPointedConnection).exitPoint, newPath.h);
                        }
                        else
                        {
                            newPath.h = EuclideanDistance(connection.connection);
                        }

                        AddCellNode(newPath);
                    }
                }
            }
        }
        /// <summary>
        /// return used edges,
        /// </summary>
        private void MakeCell(TriangulatorEdge target, bool aFirst, List <TriangulatorEdge>[] edgesDictionary, TriangulatorNode[] nodes, out List <int> cellNodes, out List <TriangulatorEdge> cellEdges)
        {
            cellNodes = new List <int>();
            cellEdges = new List <TriangulatorEdge>();
            cellEdges.Add(target);
            int startNode;

            if (aFirst)  //a are origin
            {
                startNode = target.a;
                cellNodes.Add(target.a);
                cellNodes.Add(target.b);
            }
            else
            {
                startNode = target.b;
                cellNodes.Add(target.b);
                cellNodes.Add(target.a);
            }

            int limit = 0;

            harhar++;

            while (true)
            {
                limit++;
                if (limit > 50)
                {
#if UNITY_EDITOR
                    if (Debuger_K.doDebug && Debuger_K.debugOnlyNavMesh == false)
                    {
                        for (int i = 0; i < cellNodes.Count - 1; i++)
                        {
                            Vector3 a1 = nodes[cellNodes[i]].positionV3 + (Vector3.up * 0.02f * i);
                            Vector3 a2 = nodes[cellNodes[i + 1]].positionV3 + (Vector3.up * 0.02f * i);

                            Debuger_K.AddTriangulatorDebugLine(pos.x, pos.z, properties, a1, a2, Color.red);
                            //Debuger_K.AddTriangulatorDebugLabel(chunk, properties, SomeMath.MidPoint(a1, a2), i);
                        }
                    }
#endif
                    Debug.LogError("error while making cells " + harhar);
                    break;
                }

                int nodeMinus   = cellNodes[cellNodes.Count - 2];
                int nodeCurrent = cellNodes[cellNodes.Count - 1];
                int?nodePlus    = null;
                TriangulatorEdge?connectionPlus = null;

                Vector2 directionToMinus = (nodes[nodeMinus].positionV2 - nodes[nodeCurrent].positionV2).normalized;
                float   lowestAngle      = 180f;
                List <TriangulatorEdge> searchConnections = edgesDictionary[nodeCurrent];

                foreach (var connection in searchConnections)
                {
                    int potentialNodePlus = connection.GetOtherNode(nodeCurrent);

                    if (nodeMinus == potentialNodePlus)
                    {
                        continue;
                    }

                    Vector2 directionToPotentialPlus = (nodes[potentialNodePlus].positionV2 - nodes[nodeCurrent].positionV2).normalized;
                    float   cross        = SomeMath.V2Cross(directionToMinus, directionToPotentialPlus);
                    float   currentAngle = Vector2.Angle(directionToMinus, directionToPotentialPlus);

                    if (cross > 0f & currentAngle != 180)
                    {
                        continue;
                    }

                    if (currentAngle > lowestAngle)
                    {
                        continue;
                    }

                    connectionPlus = connection;
                    nodePlus       = potentialNodePlus;
                    lowestAngle    = currentAngle;
                }

                if (nodePlus == null)
                {
                    #region error
#if UNITY_EDITOR
                    if (Debuger_K.doDebug)
                    {
                        Debuger_K.AddTriangulatorDebugLine(pos.x, pos.z, properties, nodes[cellNodes[0]].positionV3, nodes[cellNodes[0]].positionV3 + SmallV3(0.3f), Color.green);

                        for (int i = 0; i < cellNodes.Count - 1; i++)
                        {
                            Debuger_K.AddTriangulatorDebugLine(pos.x, pos.z, properties, nodes[cellNodes[i]].positionV3 + SmallV3(0.1f), nodes[cellNodes[i + 1]].positionV3 + SmallV3(0.1f), Color.red);
                        }
                        for (int i = 0; i < cellNodes.Count - 1; i++)
                        {
                            Vector3 a1 = nodes[cellNodes[i]].positionV3 + SmallV3(0.02f * i);
                            Vector3 a2 = nodes[cellNodes[i + 1]].positionV3 + SmallV3(0.02f * i);
                            Debuger_K.AddTriangulatorDebugLine(pos.x, pos.z, properties, a1, a2, Color.red);
                        }

                        foreach (var connection in searchConnections)
                        {
                            int potentialNodePlus = connection.GetOtherNode(nodeCurrent);

                            if (nodeMinus == potentialNodePlus)
                            {
                                continue;
                            }

                            Vector2 directionToPotentialPlus = (nodes[potentialNodePlus].positionV2 - nodes[nodeCurrent].positionV2).normalized;

                            float cross = SomeMath.V2Cross(directionToMinus, directionToPotentialPlus);

                            Debuger_K.AddLabel(nodes[potentialNodePlus].positionV3, cross);
                            Debuger_K.AddLabel(nodes[nodeCurrent].positionV3, Vector2.Angle(directionToMinus, directionToPotentialPlus));
                            //Debuger_K.AddTriangulatorDebugLabel(chunk, properties, nodes[potentialNodePlus].positionV3, cross);
                            //Debuger_K.AddTriangulatorDebugLabel(chunk, properties, nodes[nodeCurrent].positionV3, Vector2.Angle(directionToMinus, directionToPotentialPlus));
                        }
                    }
#endif
                    #endregion
                    Debug.LogError("nodePlus == null");
                    break;
                }

                cellEdges.Add(connectionPlus.Value);

                if (nodePlus == startNode)
                {
                    break;
                }

                cellNodes.Add(nodePlus.Value);
            }
        }