美文网首页
Astar寻路

Astar寻路

作者: Moment__格调 | 来源:发表于2016-03-27 23:21 被阅读159次

    大家好,这次给大家分享最近学习A* 这款插件的心得,前面我一点点介绍,到最终我们实现一个多个小队寻路的效果。

     首先介绍下怎么样使用这个插件,下载插件后导入unity,新建个地面和障碍物,分别把Layer命名为Ground和Obstacles。在建议一个空物体,命名为A*,单击Component-Pathfinding-Pathfinder 就可以看见Inspector面板出现了一个AstarPath,包含Graphs ,Settings,Save&load,Optimization和About 5个部分。     点击Graphs,添加一个新的Graph,这里就是添加我们的导航图。这里有很多种类型,我们往后一个个介绍,先创建一个基于单元的导航图,单击Grid Graph,会生成一个width*depth的规则网格,将NodeSize设置1,表示节点之间的间距为1个单位,将Center的坐标设置为(0,-0.1,0)因为我们的地面y=0,如果GridGraph的y也为0,在投射射到平面时候,可能会产生浮点误差,所以我们稍微下降一点高度。然后是CollisionTesting 碰撞测试选项里面,改变Mask的值,我们不希望AI在Obstacles层移动,所以设置Mask设置Obstacles层就可以了。接着是HeightTesting 高度测试,我们让射线的长度为100,Mask设置Ground层,就是只在Ground层进行投射,最后点击最下方的Scan,就可以看到生成的网格了。

    下一步,我们添加一个角色,把一个带动画的人物拖入场景,首先添加角色碰撞器,调整好属性,选中人物,点击Component-Pathfinding-Seeker 为角色添加seeker脚本,使角色能够感知A*寻路,然后我们在创建一个移动脚本,让角色能够移动。为角色添加AstarAI.cs 脚本,

    ```using UnityEngine;

    using System.Collections;

    using Pathfinding;

    public class AstartAI : MonoBehaviour {

       //目标位置

       public Transform targetPosition;

       //声明一个seeker类的对象

       private Seeker seeker;

       private CharacterController controller;

       //一个path类的对象。表示路径

       public Path path;

       //角色每秒的速度

       public float speed = 100;

       //当角色与一个航点的距离小于这个值时,角色便可转向路径上的下一个航点

       public float nextWaypointDistance = 3;

       //角色正朝其行进的航点

       private int currentWaypoint = 0;

       void Start()

       {

           //获得对Seeker组件的引用

           seeker = GetComponent();

           controller = GetComponent();

           //注册回调函数,在AstartPath完成寻路后调用该函数。

           seeker.pathCallback += OnPathComplete;

    //调用StartPath函数,开始到目标的寻路

    seeker.StartPath(transform.position, targetPosition.position);

    }

    private int turnSpeed = 100;

    void FixedUpdate()

    {

    if (path == null)

    {

    return;

    }

    //如果当前路点编号大于这条路径上路点的总和,那么已经到达路径的终点

    if (currentWaypoint >= path.vectorPath.Count)

    {

    Debug.Log("EndOfPathReached");

    return;

    }

    //计算出去往当前路点所需的行走方向和距离,控制角色移动

    Vector3 dir = (path.vectorPath[currentWaypoint] - transform.position).normalized;

    dir *= speed*Time.fixedDeltaTime;

    controller.SimpleMove(dir);

    //角色转向目标

    Quaternion targetRotation=Quaternion.LookRotation(dir);

    transform.rotation=Quaternion.Slerp(transform.rotation,targetRotation,Time.deltaTime*turnSpeed);

    //如果当前位置与当前路点的距离小于一个给定值,可以转向下一个路点

    if (Vector3.Distance(transform.position, path.vectorPath[currentWaypoint]) < nextWaypointDistance)

    {

    currentWaypoint++;

    return;

    }

    }

    //当寻路结束后调用这个函数

    public void OnPathComplete(Path p)

    {

    Debug.Log("FindThePath"+p.error);

    //如果找到了一条路径,保存下来,并且把第一个路点设置为当前路点

    if (!p.error)

    {

    path = p;

    currentWaypoint = 0;

    }

    }

    void OnDisable()

    {

    seeker.pathCallback -= OnPathComplete;

    }

    }

    ```

    然后在新建一个小球,用来表示TargetPosition位置,小球放到我们想要移动到最终的目的地,然后拖到TargetPosition上,最后我们运行场景,就可以看到我们的人物绕过障碍物进行移动了,如果需要角色移动的平滑些,可以通过Component-Pathfinding-Modifiers添加,里面有很多种平滑脚本,我们选中SimpleSmooth 添加到角色上,然后慢慢调整参数,就可以看到角色不同程度的平滑移动了。最后,提供工程,运行Test1场景就行了。  

    相关文章

      网友评论

          本文标题:Astar寻路

          本文链接:https://www.haomeiwen.com/subject/hhdjlttx.html