示例#1
0
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        NavigationMesh2D navMesh = target as NavigationMesh2D;

        if (!navMesh)
        {
            return;
        }

        EditorGUILayout.Separator();
        EditorGUILayout.Separator();

        if (GUILayout.Button("Generate NavMesh"))
        {
            Undo.RecordObject(navMesh, "Generate 2D Navigation Map.");
            navMesh.GenerateNavMesh();
            serializedObject.ApplyModifiedProperties();
        }

        if (GUILayout.Button("Clear"))
        {
            Undo.RecordObject(navMesh, "Clear 2D Navigation Map.");
            navMesh.Clear();
            serializedObject.ApplyModifiedProperties();
        }
    }
 public NodeConnection(NavigationMesh2D owner, int id, Node node1, Node node2, bool diagonal)
     : this(owner, id, node1, node2)
 {
     if (diagonal)
     {
         cost = diagonalCost;
     }
 }
    public Node(NavigationMesh2D owner, int localId, int gridX, int gridY, Vector2 position)
    {
        this.owner = owner;

        this.localId = localId;
        x            = gridX; y = gridY;

        this.position = position;
    }
    public NodeConnection(NavigationMesh2D owner, int id, Node node1, Node node2)
    {
        this.owner = owner;

        this.localId = id;

        nodeId1 = node1.GetLocalId;
        nodeId2 = node2.GetLocalId;

        if ((node1 != null && !node1.IsValid) || (node2 != null && !node2.IsValid))
        {
            valid = false;
        }
    }
示例#5
0
    /// <summary>
    /// Método que devuelve un array de puntos a seguir, siempre devolverá el más corto que llegue al destino,
    /// y si no llega, el más cercano.
    /// </summary>
    /// <param name="origin">La posición de origen</param>
    /// <param name="destination">La posición de origen</param>
    /// <param name="maxIterations">La cantidad máxima que repite la búsqueda de nodos</param>
    /// <returns></returns>
    public IEnumerator GetPath(Vector2 origin, Vector2 destination, int maxIterations)
    {
        path.Clear();

        //Verificar que el NavMesh2D exista
        NavigationMesh2D navMesh = NavigationMesh2D.FindMap(transform.position);

        if (navMesh == null)
        {
            Debug.LogWarning("No 2D Navigation Mesh found.");
            enabled = false;
            yield break;
        }

        //Tomar los nodos válidos más cercanos al origen y destino
        Node originNode      = navMesh.GetNearestValidNode(origin);
        Node destinationNode = navMesh.GetNearestValidNode(destination);

        //En la open list se guardan los breadCrumb que se van a considerar y ser procesados.
        openList.Clear();
        //En la closed list se guardan los breadCrumb que ya se procesaron.
        //Se agrega primero el del nodo de origen, ya que no necesita ser considerado.
        closedList.Clear();
        closedList.Add(new BreadCrumb(originNode));

        //Esta variable nos indica que breadCrumb estamos procesando.
        BreadCrumb currentBc = closedList[0];

        //Procesar el breadCrumb actual, repetir llegar al destino o se superen las iteraciones.
        int iterations = 0;

        while (iterations < maxIterations && currentBc != null && currentBc.node != destinationNode)
        {
            if (stepByStepMode)
            {
                yield return(new WaitForSeconds(stepTime));
            }
            currentBc = FindBestBreadCrumb(currentBc, destinationNode, openList, closedList);
            iterations++;
        }

        //Transformar el BreadCrumb más cercano al objetivo en un camino a partir de sus
        //BreadCrumbs anteriores (previous)
        float lowestHeuristicCost = closedList.Min(bc => bc.heuristicCost);

        currentBc = closedList.Find(bc => bc.heuristicCost <= lowestHeuristicCost);
        Node closestNode = currentBc?.node;

        //Creamos una lista 'camino invertido' y agregamos las posiciones de los BreadCrumbs hasta que no
        //haya un anterior BreadCrumb.
        linePath.Clear();
        List <Vector2> reversedPath = new List <Vector2>();

        while (currentBc != null)
        {
            Vector3 position = currentBc.node.GetPosition;
            linePath.Add(position);

            if (stepByStepMode)
            {
                yield return(new WaitForSeconds(stepTime));

                UpdateLineRenderer();
            }

            reversedPath.Add(position);
            currentBc = currentBc.previous;
        }


        List <Vector2> pathToFollow = reversedPath;

        if (closestNode == destinationNode)
        {
            pathToFollow = pathToFollow.Skip(1).Reverse().ToList();
            pathToFollow.Add(destination);
        }
        else
        {
            pathToFollow.Reverse();
        }

        //Devolver el camino salteando el primer nodo.
        path.Clear();
        path.AddRange(pathToFollow.Skip(1).ToArray());

        if (!stepByStepMode)
        {
            openList.Clear();
            closedList.Clear();

            linePath.Clear();
            linePath.AddRange(path);
            UpdateLineRenderer();
        }
    }
 public NodePath(Node toNode, NodeConnection connection)
 {
     owner        = toNode.GetOwner;
     toNodeId     = toNode.GetLocalId;
     connectionId = connection.GetLocalId;
 }