29.Unity制作自动寻路逻辑的方法
29.1 题目
Unity中想要制作自动寻路逻辑,我们应该怎么做?(请至少说出两种做法)
29.2 深入解析
在Unity中,可以通过以下两种方法来实现自动寻路逻辑:
1. 使用Unity自带的网格寻路系统
Unity提供了一个强大的网格寻路系统,可以使用NavMesh来实现自动寻路。具体步骤如下:
创建NavMesh:
- 在场景中创建一个NavMeshSurface。
- 在场景中选中需要进行寻路的地形或物体,标记为可行走区域。
- 点击Bake生成NavMesh。
添加NavMeshAgent:
- 在需要进行自动寻路的角色上添加NavMeshAgent组件。
- 设置目标位置,并通过NavMeshAgent组件的
SetDestination方法来实现自动寻路。
using UnityEngine;
using UnityEngine.AI;
public class AutoNavigation : MonoBehaviour
{
public Transform target; // 目标位置
private NavMeshAgent agent;
void Start()
{
agent = GetComponent<NavMeshAgent>();
agent.SetDestination(target.position); // 设置目的地
}
void Update()
{
// 不断更新目的地,实现动态寻路
if (target != null)
{
agent.SetDestination(target.position);
}
}
}
2. 自定义寻路算法(比如A星寻路算法)
A星(A*)算法是一种常用的图搜索算法,可以用来实现自定义的寻路逻辑。具体步骤如下:
定义节点类:
- 创建一个节点类来存储每个节点的信息,包括位置、父节点、G值(从起点到当前节点的代价)、H值(当前节点到终点的估算代价)和F值(G值和H值的总和)。
实现A星算法:
- 使用优先队列(或其他合适的数据结构)来存储打开列表(Open List)和关闭列表(Closed List)。
- 在Open List中找到F值最小的节点,检查其邻居节点并进行相应更新。
- 重复以上步骤,直到找到目标节点或Open List为空。
using System.Collections.Generic;
using UnityEngine;
public class AStarPathfinding : MonoBehaviour
{
public Transform startPoint; // 起点
public Transform endPoint; // 终点
private List<Node> openList = new List<Node>();
private List<Node> closedList = new List<Node>();
// 节点类
class Node
{
public Vector3 position; // 节点位置
public Node parent; // 父节点
public float g; // G值
public float h; // H值
public float f => g + h; // F值
}
void Start()
{
// 初始化起点和终点
Node startNode = new Node { position = startPoint.position, g = 0, h = Vector3.Distance(startPoint.position, endPoint.position) };
Node endNode = new Node { position = endPoint.position };
openList.Add(startNode);
// A星算法主循环
while (openList.Count > 0)
{
Node currentNode = GetNodeWithLowestF();
// 找到终点
if (currentNode.position == endNode.position)
{
Debug.Log("路径找到!");
return;
}
openList.Remove(currentNode);
closedList.Add(currentNode);
foreach (Node neighbor in GetNeighbors(currentNode))
{
if (closedList.Contains(neighbor))
continue;
float tentativeG = currentNode.g + Vector3.Distance(currentNode.position, neighbor.position);
if (!openList.Contains(neighbor))
{
openList.Add(neighbor);
}
else if (tentativeG >= neighbor.g)
{
continue;
}
neighbor.parent = currentNode;
neighbor.g = tentativeG;
neighbor.h = Vector3.Distance(neighbor.position, endNode.position);
}
}
Debug.Log("没有找到路径!");
}
Node GetNodeWithLowestF()
{
Node lowestFNode = openList[0];
foreach (Node node in openList)
{
if (node.f < lowestFNode.f)
lowestFNode = node;
}
return lowestFNode;
}
List<Node> GetNeighbors(Node node)
{
List<Node> neighbors = new List<Node>();
// 添加邻居节点的逻辑
// ...
return neighbors;
}
}
总结
Unity自带的网格寻路系统:
- 使用NavMesh进行路径规划和导航。
- 简单易用,适合大多数场景。
自定义寻路算法(比如A星寻路算法):- 灵活可定制,可以根据具体需求实现复杂的路径规划逻辑。
- 适合需要特殊路径规划策略的场景。
这两种方法各有优劣,可以根据具体的项目需求选择合适的寻路方案。
29.3 答题示例
“Unity 中做自动寻路,一种是 NavMesh:在场景中 Bake NavMesh,给角色挂 NavMeshAgent,通过
agent.SetDestination(target)即可;
另一种是 自定义寻路(如 A* 算法):自己构建节点网格,维护 Open/Closed 列表,按 F = G + H 选取最优节点,最终生成路径并逐点移动。”
29.4 关键词联想
- NavMeshSurface / NavMeshAgent
- Bake NavMesh
- SetDestination
- A 算法*
- Open List / Closed List
- F = G + H
- 节点网格
- 路径重建
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com