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