寻路-运动问题

问题描述 投票:-1回答:1

大家好!

我将以新的C#学习者的身份和平来到这里:)

我的项目基于具有等距方向的寻路,因此我首先阅读了基于节点的基于网格的教程,这对我很有帮助!有五个脚本:网格,节点,路径查找器,堆,

在学习完本教程之后,我开始解决一些问题,并踢了教程中设置的目标设置,以使播放机能够找到我的mouseClicks。

我很高兴在控制台中没有任何错误,但代码看起来不错,但是无论如何,当我单击播放时,播放器没有移动,即使经过了很长时间,我也无法弄清楚为什么...任何想法?

您可以在我的GitHub上找到Hole项目:https://github.com/Felloggs/Astar-MAP,这是代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class PathFinder : MonoBehaviour{


public bool displayPathGizmos;
public Transform seeker;
public LayerMask targetMask;
int targetIndex;
bool StartFindPath = false;
float speed = 20;
float rotationSpeed = 20;
Vector3[] path;
Grid grid;

void OnEnable()
{
    grid = GetComponent<Grid>();
}

void Update()
{
    if (Input.GetMouseButton(0))
    {
        Vector3 target = -Vector3.one;
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit, 100f, targetMask))
        {
            target = hit.point;
            if (hit.collider.tag == "Walkable")
            {
                StartFindPath = true;
            }
        }
    }
    if (StartFindPath)
    {
        if (seeker.position == target.position)
        {
            StartFindPath = false;
        }
    }
}

IEnumerator FindPath(Vector3 startPos, Vector3 endPos)
{
    Vector3[] waypoints = new Vector3[0];
    bool pathSuccess = false;
    Node startNode = grid.NodeFromWorldPoint(endPos);
    Node endNode = grid.NodeFromWorldPoint(endPos);
    if (startNode.walkable && endNode.walkable)
    {
        Heap<Node> openSet = new Heap<Node>(grid.MaxSize);
        HashSet<Node> closedSet = new HashSet<Node>();
        openSet.Add(startNode);
        while (openSet.Count > 0)
        {
            Node currentNode = openSet.RemoveFirst();
            closedSet.Add(currentNode);
            if (currentNode == endNode)
            {
                pathSuccess = true;
                break;
            }
            foreach (Node neighbour in grid.GetNeighbours(currentNode))
            {
                if (!neighbour.walkable || closedSet.Contains(neighbour))
                {
                    continue;
                }
                int newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour);
                if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour))
                {
                    neighbour.gCost = newMovementCostToNeighbour;
                    neighbour.hCost = GetDistance(neighbour, endNode);
                    neighbour.parent = currentNode;
                    if (!openSet.Contains(neighbour))
                    {
                        openSet.Add(neighbour);
                    }
                    // optimization?
                    // else{
                    //      openSet.UpdateItem(neighbour);}
                }
            }
        }
    }
    yield return null;
    if (pathSuccess)
    {
        waypoints = RetracePath(startNode, endNode);
    }
}

Vector3[] RetracePath(Node startNode, Node endNode)
{
    List<Node> path = new List<Node>();
    Node currentNode = endNode;
    while (currentNode != startNode)
    {
        if (currentNode == startNode)
        {
            path.Add(currentNode);
        }
        currentNode = currentNode.parent;
    }
    path.Add(startNode);
    Vector3[] waypoints = Path(path);
    Array.Reverse(waypoints);
    return waypoints;
}

Vector3[] Path(List<Node> path)
{
    List<Vector3> waypoints = new List<Vector3>();
    Vector2 directionOld = Vector2.zero;
    // optimization?
    // waypoints.Add(path[0].worldPosition);
    for (int i = 1; i < path.Count; i++)
    {
        Vector2 directionNew = new Vector2(path[i - 1].gridX - path[i].gridX, path[i - 1].gridY - path[i].gridY);
        if (directionNew != directionOld)
        {
            // "- 1" optimization? eventually limit 1 grid distances, check if "waypoints.Add(path[0].worldPosition);" before doesn't solve the problem!
            waypoints.Add(path[i - 1].worldPosition);
        }
        directionOld = directionNew;
    }
    // optimization?
    // if (path.Count > 0){
    //      waypoints.Add(path[path.Count - 1].worldPosition);}
    return waypoints.ToArray();
}

int GetDistance(Node nodeA, Node nodeB)
{
    int dstX = Mathf.Abs(nodeA.gridX - nodeB.gridX);
    int dstY = Mathf.Abs(nodeA.gridY - nodeB.gridY);
    if (dstX > dstY)
    {
        return 14 * dstY + 10 * (dstX - dstY);
    }
    return 14 * dstX + 10 * (dstY - dstX);
}

public void OnPathFound(Vector3[] newPath, bool pathSuccessful)
{
    if (pathSuccessful)
    {
        path = newPath;
        targetIndex = 0;
        StopCoroutine("FollowPath");
        StartCoroutine("FollowPath");
    }
}

IEnumerator FollowPath()
{
    Vector3 currentWaypoint = path[0];
    // optimization?
    // targetIndex = 0;
    while (true)
    {
        if (seeker.position == currentWaypoint)
        {
            targetIndex++;
            if (targetIndex >= path.Length)
            {
                targetIndex = 0;
                path = new Vector3[0];
                yield break;
            }
            currentWaypoint = path[targetIndex];
        }
        Vector3 targetDir = currentWaypoint - seeker.position;
        float step = rotationSpeed * Time.deltaTime;
        Vector3 newDir = Vector3.RotateTowards(seeker.forward, targetDir, step, 0.0f);
        seeker.rotation = Quaternion.LookRotation(newDir);
        seeker.position = Vector3.MoveTowards(seeker.position, currentWaypoint, speed * Time.deltaTime);
        yield return null;
    }
}

void OnDrawGizmos()
{
    if (path != null)
    {
        for (int i = targetIndex; i < path.Length; i++)
        {
            Gizmos.color = Color.black;
            Gizmos.DrawCube(path[i], Vector3.one);
            if (i == targetIndex)
            {
                Gizmos.DrawLine(seeker.position, path[i]);
            }
            else
            {
                Gizmos.DrawLine(path[i - 1], path[i]);
            }
        }
    }
}

}

unity3d nodes grid-layout path-finding
1个回答
0
投票

尝试解决您的问题。拿起您的基本动作代码,这会动作吗?现在将A *算法的各个部分拼凑起来,并使用断点或Debug.Logs找出正在发生的事情。然后,当您对问题有更具体的想法时,可以回来,我们应该能够提供帮助,使用所有这些代码确实很难。不幸的是stackoverflow并不是真的意味着这种问题。

  1. Debug via Visual Studio
© www.soinside.com 2019 - 2024. All rights reserved.