首页 > 其他分享 >Unity3D 打造基于AStar的寻路与导航详解

Unity3D 打造基于AStar的寻路与导航详解

时间:2024-04-19 16:47:43浏览次数:14  
标签:Unity3D currentNode openSet AStar 寻路 public

Unity3D 打造基于AStar的寻路与导航详解

BYCW丶零夜 BYCW丶零夜     2 人赞同了该文章

前言

寻路与导航是游戏开发中非常重要的一部分,它可以让游戏中的角色自动寻找到目标位置,并避开障碍物。本文将介绍如何使用Unity3D 打造基于AStar算法的寻路与导航解,包括技术详解和代码实现。

对惹,这里有一个游戏开发交流小组,希望大家可以点击进来一起交流一下开发经验呀!

一、AStar算法简介

AStar算法是一种常用的寻路算法,它可以在图形结构中找到从起点到终点的最佳路径。AStar算法的核心思想是通过启发式搜索,不断扩展当前最优的路径,直到找到终点。它具有高效性和准确性的特点,适用于各种复杂的场景。

AStar算法的基本步骤如下:

  1. 初始化起点和终点,并将起点加入开放列表中;
  2. 重复以下步骤直到找到终点或开放列表为空:
    a. 从开放列表中选择F值最小的节点作为当前节点,并将其从开放列表中移除;
    b. 将当前节点加入关闭列表中;
    c. 遍历当前节点的相邻节点,计算它们的G值、H值和F值,并更新它们的父节点;
    d. 将未在关闭列表中的相邻节点加入开放列表中;
  3. 如果终点在关闭列表中,则找到了最优路径,否则无法到达终点。

二、Unity3D中的寻路与导航

在Unity3D中,可以通过NavMesh系统实现寻路与导航功能。NavMesh是一种基于网格的寻路技术,可以在场景中生成一个可行走区域的网格,角色可以根据这个网格自动寻找路径。Unity3D提供了NavMesh Agent组件和NavMesh Obstacle组件,分别用于角色的移动和障碍物的设置。

使用NavMesh系统实现寻路与导航的基本步骤如下:

  1. 在场景中创建一个NavMesh Surface对象,并设置可行走区域的大小和高度;
  2. 在场景中放置障碍物,并添加NavMesh Obstacle组件,设置障碍物的大小和形状;
  3. 创建一个角色对象,并添加NavMesh Agent组件,设置移动速度、加速度等参数;
  4. 编写脚本控制角色的移动,通过NavMesh Agent组件的SetDestination方法设置目标位置。

三、基于AStar算法的寻路与导航解

虽然Unity3D提供了NavMesh系统来实现寻路与导航功能,但有时候我们需要更灵活和精确的路径规划,这时就需要使用AStar算法来实现自定义的寻路与导航解。下面将介绍如何在Unity3D中实现基于AStar算法的寻路与导航功能。

  1. 创建一个Grid类表示地图的网格结构,包括每个网格的位置、是否可行走等信息。
public class Grid {
    public int width;
    public int height;
    public Node[,] nodes;

    public Grid(int width, int height) {
        this.width = width;
        this.height = height;
        nodes = new Node[width, height];
        // 初始化网格信息
    }
}
  1. 创建一个Node类表示每个网格节点,包括节点的位置、是否可行走、G值、H值、F值等信息。
public class Node {
    public bool walkable;
    public Vector3 position;
    public int gridX;
    public int gridY;
    public int gCost;
    public int hCost;
    public Node parent;

    public int fCost {
        get {
            return gCost + hCost;
        }
    }
}
  1. 实现AStar算法,通过启发函数计算节点的H值,通过开放列表和关闭列表来搜索最优路径。
public List<Node> FindPath(Vector3 startPos, Vector3 targetPos) {
    Node startNode = grid.NodeFromWorldPoint(startPos);
    Node targetNode = grid.NodeFromWorldPoint(targetPos);

    List<Node> openSet = new List<Node>();
    HashSet<Node> closedSet = new HashSet<Node>();

    openSet.Add(startNode);

    while (openSet.Count > 0) {
        Node currentNode = openSet[0];
        for (int i = 1; i < openSet.Count; i++) {
            if (openSet[i].fCost < currentNode.fCost || openSet[i].fCost == currentNode.fCost && openSet[i].hCost < currentNode.hCost) {
                currentNode = openSet[i];
            }
        }

        openSet.Remove(currentNode);
        closedSet.Add(currentNode);

        if (currentNode == targetNode) {
            return RetracePath(startNode, targetNode);
        }

        foreach (Node neighbour in grid.GetNeighbours(currentNode)) {
            if (!neighbour.walkable || closedSet.Contains(neighbour)) {
                continue;
            }

            int newCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour);
            if (newCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour)) {
                neighbour.gCost = newCostToNeighbour;
                neighbour.hCost = GetDistance(neighbour, targetNode);
                neighbour.parent = currentNode;

                if (!openSet.Contains(neighbour)) {
                    openSet.Add(neighbour);
                }
            }
        }
    }

    return null;
}

 

  1. 实现RetracePath方法,根据父节点逆向遍历获取最优路径。
private List<Node> RetracePath(Node startNode, Node endNode) {
    List<Node> path = new List<Node>();
    Node currentNode = endNode;

    while (currentNode != startNode) {
        path.Add(currentNode);
        currentNode = currentNode.parent;
    }

    path.Reverse();
    return path;
}
  1. 在Unity3D中使用AStar算法实现寻路与导航功能,创建一个角色对象并添加脚本控制移动。
public class AStarPathfinding : MonoBehaviour {
    public Transform target;
    private List<Node> path;

    void Update() {
        if (Input.GetMouseButtonDown(0)) {
            Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            path = FindObjectOfType<Grid>().FindPath(transform.position, mousePos);
        }

        if (path != null) {
            int currentWaypoint = 0;
            if (currentWaypoint < path.Count) {
                Vector3 targetPos = path[currentWaypoint].position;
                transform.position = Vector3.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);

                if (transform.position == targetPos) {
                    currentWaypoint++;
                }
            }
        }
    }
}

通过以上步骤,我们就可以在Unity3D中实现基于AStar算法的寻路与导舨功能。这种自定义的寻路解决方案可以应用于各种复杂的场景,提供更灵活和精确的路径规划。希望本文能够帮助读者更好地理解Unity3D中的寻路与导航功能,并应用到实际的游戏开发中。

更多教学视

Unity​www.bycwedu.com/promotion_channels/2146264125 发布于 2024-04-16 16:14・IP 属地湖南

标签:Unity3D,currentNode,openSet,AStar,寻路,public
From: https://www.cnblogs.com/sexintercourse/p/18146304

相关文章

  • 2-77. 修正 CropGenerator 和 AStar 地图节点生成
    修复Bug可以看到房子的上面生成了一棵树修改CropGenerator修改AStar我不太理解,反正照着改就算了吧项目相关代码代码仓库:https://gitee.com/nbda1121440/farm-tutorial.git标签:20240413_1246......
  • 2-74. 利用 AStar 实现 NPC 的移动
    运行游戏看看人物能否到网格中点修改NPCMovement修改Settings修改AStarTest调试修复Bug一开始人物未显示原因是currentScene没有进行赋值,可能currentScene是通过StartScene变量进行赋值的,但是我并没有找到赋值的地方,所以我暂时先写死这个变量算了......
  • Unity3D代码混淆方案详解
    背景Unity引擎使用Mono运行时,而C#语言易受反编译影响,存在代码泄露风险。本文通过《QQ乐团》项目实践,提出一种适用于Unity引擎的代码混淆方案,以保护代码逻辑。引言在Unity引擎下,为了防止代码被轻易反编译,需要采取相应的保护措施。本文将分享一种基于实践经验的可行方案,希......
  • Unity3D代码混淆方案详解
    背景Unity引擎使用Mono运行时,而C#语言易受反编译影响,存在代码泄露风险。本文通过《QQ乐团》项目实践,提出一种适用于Unity引擎的代码混淆方案,以保护代码逻辑。引言在Unity引擎下,为了防止代码被轻易反编译,需要采取相应的保护措施。本文将分享一种基于实践经验的可行方案,希......
  • A*寻路
    A*寻路算法在开始节点寻找四周节点,然后计算每个节点到终点需要走的步数,优先从最少的步数的节点开始走每个节点都记录是如何过来的,在最后找到终点后反向获取整个路程效果:packagetest;importjava.util.*;importjava.util.stream.Collectors;/***@authorJame!*......
  • 蓝桥杯 2013 国 AC 网络寻路 第四届国赛 洛谷P8605
    [蓝桥杯2013国AC]网络寻路题目描述XXX国的一个网络使用若干条线路连接若干个节点。节点间的通信是双向的。某重要数据包,为了安全起见,必须恰好被转发两次到达目的地。该包可能在任意一个节点产生,我们需要知道该网络中一共有多少种不同的转发路径。源地址和目标地......
  • 基于Unity3d的google小恐龙游戏8-------背景音乐与第六个BOSS
    前言大家好,上一次unity练习记录中我添加了背景以及第五个boss,丰富了一下游戏内容,但是玩的时候发现好像有一些空洞,所以决定再次添加一些东西。本次练习主要是想要搞两个UI,以及背景音乐,然后再添加一个新的boss。其实我也很想再添加一些小怪,这些就是后话了。先把前面三个功能添加......
  • Unity3D 基础 05 场景加载
    Unity3D基础系列(第五期)场景配置首先,在资源文件夹里创建一个LoadScene场景,摆放一些物体,用来做初始场景。然后创建一个Stage文件夹,并创建两个场景Stage1、Stage2。两个Stage场景也可以简单布置一下,方便区分。接着,打开BuildSettings,把需要加载的场景添加到配置......
  • 洛谷 B3625 迷宫寻路
    本道题需要注意:如果孩子的起始位置就是‘#’,那孩子就无路可走,出不来了。所以需要特判一下,代码如下:(这是废话,不需要特判,注意题目要求)if(ch[1][1]=='#'){ printf("No\n"); }注意边界条件:if(nx<1||nx>n||ny<1||ny>m){ continue; } if(vis[nx][ny]==1){ cont......
  • Unity3D 基于ECS的AOI设计与实现详解
    EntityComponentSystem(ECS)是Unity3D引擎中的一种编程模式,它将游戏对象分解为实体(Entity)和组件(Component),以提高游戏性能和可维护性。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发的技术大佬,欢迎你来交流学习。在游戏开发中,Are......