2016-05-10 17:25:36 prcfiona 阅读数 4246

Unity中对于寻路导航算法进行了封装,支持提交将地图进行导航烘焙

如果想在两个不连续的平面之间加一个吊桥,在桥放平时可以使物体通过吊桥,而桥抬起时物体在桥边等待。
地形示意图
1. 给桥的加一个旋转中心如图中蓝色球体,将桥和地面分开,设置两个地面的Navigation值如图,勾选Navigation Static和Generate OffMeshLinks,Navigation Area的值设为Walkable
地面的Navigation值
2. 设置桥体的Navigation值如图,同样勾选Navigation Static和Generate OffMeshLinks,如图在Areas添加标签bridge,并将Navigation Area的值设为bridge
这里写图片描述
3. 给物体1添加组件Navigation->Nav Mesh Agent
这里写图片描述
4.给桥添加脚本代码如下

 private Transform Sphere;
    private bool isOver;
    private GameObject src;
    // Use this for initialization
    void Start ()
    {
        isOver = false;
        Sphere = GameObject.Find("Sphere").transform;
        transform.RotateAround(Sphere.position, Vector3.left, 45);
        src = GameObject.Find("src");
    }

    // Update is called once per frame
    void Update ()
    {
        if(!isOver&&Time.realtimeSinceStartup > 5)
        {
            transform.RotateAround(Sphere.position, Vector3.left, -45);
            isOver = true;
            src.SendMessage("SendMask", -1);
        }

    }

5.给物体1添加脚本

public Transform dest;
    private NavMeshAgent agent;

    // Use this for initialization
    void Start ()
    {
        agent = GetComponent<NavMeshAgent>();
        agent.SetDestination(dest.position);
        agent.areaMask = -1 ^ 1 <<6;//第六个标签   
    }
    void SendMask(int mask)
    {
        agent.areaMask = mask;
    }
2017-01-07 18:31:39 grf123 阅读数 1731

Unity3D中自动寻路的功能:

概述:

别人写的教程,非常详细,细节我就不赘述了。只写一些自己的总结:

1. 什么是导航网格:

“导航网格”,规定了使用自动寻路的GameObject所能或者不能通过的地方。

2. 如何生成导航网格:

菜单栏: Window——Navigation,打开导航网络控制面板。

选择想要生成网格的游戏物体,比如一个Plane,在”导航网格控制面板“中将“Navigation Static”打钩,点击右下角的Bake,烘焙路径,则可以看到自动生成的区域。Navigation Area则决定了这个区域是Walkable还是not Walkable或者是Jump。

3. 如何应用导航网格:

在自己的Player上添加一个“Nav Mesh Agent”组件,这个组件实现了自动寻路的功能,可以看做是一个封装。设计者只要使用这个组件就好了,具体可以看官方说明。

举个例子:

using UnityEngine;
using System.Collections;

public class SetHeroDes : MonoBehaviour
{
    public Transform ds;//用来确定目的地坐标的游戏物体的Transform
    private Vector3 origin;//存储导航网格代理的初始位置
    private NavMeshAgent nma;//存储导航网格代理组件

    void Start()
    {
        nma = gameObject.GetComponent<NavMeshAgent>();   //取得导航网格代理组件
        origin = transform.position;     // 存储一下这个脚本所挂载游戏物体的初始位置
        nma.SetDestination(ds.position); // 关键点:操作NavMeshAgent组件,设置自动寻路的目标位置为我们通过ds所指定的点。
    	}
}


把这个脚本挂到想要自动寻路的游戏物体,并指定目标位置游戏物体。

简单粗暴有木有?

nma.SetDestination(ds.position);

这句代码设置后,所挂载该脚本的游戏物体就开始依据我们通过Bake生成的导航网格自动寻路了。这个过程中,会自动绕过障碍物(通过Bake将这类游戏物体烘焙为not walked)。

4. OffMeshLink是什么?

按照我的理解,这个组件提供了不同的高度和导航网格中断的处理方案,详情看教程吧。


下面是别人教程的地址,非常详细:

有些教程里面的素材如果没有,通通用cube代替,学到东西才是真的。我看这些教程时,由于是几经转载,都看不到图的,就自己随便弄个cube,Metrial之类的搞完再说。


Unity里面的自动寻路(一)

Unity里面的自动寻路(二)

unity自带寻路Navmesh入门教程(一)

unity自带寻路Navmesh入门教程(二)

unity自带寻路Navmesh入门教程(三)


2019-09-07 15:21:14 wutaikun 阅读数 170

什么是导航网格系统?

前言:作为刚开始学习unity3d的菜鸟,将学习中觉得值得记笔记的地方分享给大家一起探讨,文中有理解错误的,勿怪哈!
unity3d 的NavMesh导航系统是一种用于动态物体自动寻路的技术。动态物体就是在游戏中可以运动的物体,一般是有生命的游戏角色,比如玩家英雄、怪物等。很多rpg游戏、实时对战游戏都是使用导航寻路,鼠标右击地图上的某点,游戏角色自动找出到达该地点的最佳路线,然后以一定速度前往该目的地,这就是导航寻路。静态物体就是游戏地图中位置和形状稳定的、可以形成导航网格的物体,常见的有地形、建筑物等。
unity3d的NavMesh导航系统的原理是根据A算法演变而来的,A算法是针对2D地图生成导航网格的算法,简单的说是把2D地形分成一个个矩形网格,然后按照广度优先算法,从起始点格子向周围的各自一层层探测,直到探测到目标点所在网格,比如
在这里插入图片描述
从A点导航到B点,首先将地图分成矩形网格,然后从A格子开始向周围的8个格子依次探索,如果周围的8个格子没有找到目标点B,则依次探索8个格子周围未探索的格子,直到找到B点所在格子,然后生成从A点到B点的路线。具体A算法可以自行查找资料。
unity3d的NavMesh所使用的导航网格算法源于A
算法,只不过为了扩展到三维世界的寻路,NavMesh将地图分成三角形网格(梯形也是由三角形组成),然后也使用广度优先算法从起始三角形一层层向外遍历,直到找到目标点所在的三角形,最后生成导航路线。
比如我们搭建一个简单场景
在这里插入图片描述
地面上放置4个立方体,地形plane和4个cube的static都选中Navigation Static,表示这5个对象都参与导航网格的烘焙,其中黑色的两个cube的Navgation Area选项设置为Not Walkable,表示障碍物,障碍物所在区域无法生成行走路线。其余的两个白色cube和地面都设置为Walkable,表示可以通行的区域。我们点击Bake选项卡右下角的Bake按钮对场景进行导航网格的烘焙,可以看到生成的导航网格。
在这里插入图片描述
如图,凡是可以通行的地方都生成了蓝色的导航网格。这张导航网格保存后将作为整个游戏场景的导航网格,在开始游戏后,挂载Nav Mesh Agent组件的游戏角色在使用导航寻路时会按照这张保存的导航网格进行寻路。注意,导航网格是提前烘焙好的静态的地图,即使在游戏中Navgation Static对象发生了变化(移动、变形、毁灭),导航网格也不变,比如事先烘焙一座桥为可行进的导航网格,在游戏中桥被毁坏了,使用导航时游戏角色依然认为桥是存在的,导航路线不变。如果游戏中出现非Navgation Static的对象挡住了导航网格,游戏角色依然认为没有阻挡,不会改变导航路线,只不过行进的路上会被挂载碰撞体的对象所阻挡。
接下来编辑Nav Mesh Agent组件,在场景中放置一个绿球代表玩家hero,放置一个小红球代表目的地。给hero球加上Nav Mesh Agent组件,然后编写脚本TestNavMesh.cs来开启导航系统的使用。代码如下:

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

public class TestNavMesh : MonoBehaviour
{
    public Transform target;
    void Start()
    {
        if(target != null)
        {
            GetComponent<NavMeshAgent>().destination = target.position;
        }
    }
}

将TestNavMesh.cs放到hero球上作为脚本组件,然后将target球赋予target变量。接着运行游戏,即可看到绿球主动走到红球的位置,过程中虽有障碍物,但是导航路线自动避开了障碍物。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2018-07-11 16:56:15 qq_34853692 阅读数 1831

Nav Mesh Agent

效果图

效果图

  1. 创建地面.
    1.1 在Hierarchy下创建一个空的游戏对象命名为Ground:
    右键 –> Create Empty –>重命名为Ground.
    Ground下面创建五个Plane游戏对象:
    右键 –> 3D Object –> Plane, 创建一个之后进行复制即可.`
    提示:创建一个之后,按Ctrl + D 进行复制即可.
    1.2 两个Plane分开,中间用另外三个Plane游戏对象进行连接.

  2. 添加导航.
    2.1 先添加导航窗口: 菜单栏Window –> Navigation
    2.2 进行烘焙: 选中Ground下所有的Plane –> 点击Inspector下static边上的三角形 –> 选中Navigation Static –> 切换到Navigation窗口 –> 点击Bake –> 直接点击 Bake进行烘焙.
    烘焙之后的效果

  3. Hierarchy下创建一个Cube作为导航的目标点.创建一个Sphere最为Player.
    选中Player –> Inspector界面下Add Component 添加组件 –> 搜索Nav Mesh Agent(实现自动导航)组件进行添加 –> 在Project下创建一个Scripts用来存放C#脚本 –> 右键Create一个C#脚本,起名字为PlayController
  4. 编写C#脚本
       public class PlayController : MonoBehaviour
       {
           //定义接收导航网络组件
           private NavMeshAgent nav;
           //定义目的地的方块
           public Transform cubePos;
           void Start()
           {
               //赋值
               nav = this.transform.GetComponent<NavMeshAgent>();
           }
           void Update()
           {
               //设置目的地的位置为方块的位置
               nav.SetDestination(cubePos.position);
           }
       }       

编写完成后, 将脚本拖拽到之前创建好的Sphere上面, 然后会在Inspector界面下看到该脚本下有一个CubePos,是用来设置目的地的位置,直接将之前创建好的Cube拖拽到CubePos上面即可.
5. 添加材质.
5.1 在Project中创建一个空的文件夹Metarials用来存放所有材质.
5.2 右键 –> Create –> Material –> Albedo –> 设置颜色 –> 拖动创建好的Material到游戏对象上面.
注意:一个材质只能使用一种颜色,不能为多个游戏对象添加颜色.可以创建多个材质来实现.
5.3 为桥和小球添加相应颜色的材质.
5.4 Ctrl + D 复制多个小球, 这里创建了三个材质,颜色分别是Red,Green,Blue.所以创建一个三个空的游戏对象用来存放不同颜色额的小球.
可以运行看一下效果.
6. 指定导航路径.
6.1 在之前添加的Navigation窗口下的Areas里面添加三个区域, Name分别为Red, Green, Blue.
6.2 分别选中三座桥,在各自的Navigation窗口下的Object里的Navigation Area中选中相对应的颜色(默认是地面).之后重新烘焙.
注意:改过Navigation Area之后要重新烘焙.
6.3 导航走的区域已经分好了, 但是默认状态下可以走所有的区域.下面修改每种颜色的Sphere可以走的区域. 选中需要修改的Sphere –> 在Nav Mesh Agent 组件里面的最下方有个 Area Mask –> 选中 Walkable(默认是全部) 和 自己可以走的颜色.
7. 运行之后会发现小球会在cube的外面转圈, 这是因为小球是有质量的, 可以在
Nav Mesh Agent组件中的Quality调整为None, 在运行.

面板中的一些参数

Object
Navigation Static 勾选后表示该对象参与导航网格的烘焙
Generate OffMeshLinks 勾选后可以跳跃导航网格和下落
Navigation Area 物体烘焙网格属于哪个图层, 可通过代码让游戏人物走不同的路
Bake
Agent Radius 具有代表性的物体半径, 半径越小生成的网格面积越大.和边缘的距离
Agent Height 具有代表性物体的高度
Max Slope 斜坡的坡度
Step Height 台阶高度
Drop Height 允许跳跃最大下落距离
Jump Distance 允许最大的跳跃距离
Manual Voxel Size 手动输入像素值
Min Region Area 网格面积小于该值则不生成导航网格
Height Mesh 选中该项,将会保存高度信息,同事也会消耗一些性能和存储空间

Nav Mesh Agent 组件面板

Agent Size 尺寸控制
Radius 物体的半径
Height 物体的高度
Base Offset 偏移度
Steering 行动控制
Speed 物体进行的最大速度
Angular Speed 行进过程中转向是的角速度
Acceleration 物体的行进加速度
Stopping Distance 距离目标点小于多远距离后便停止行进
Obstacle Avoidance 躲避障碍参数
Quality 质量
Priority 优先级
Path Finding 路径寻找
Auto Traverse Off Mesh Link 是否采用默认方式度过连接路径
Auto Repath 在行进过程中,因某些原因中断的情况下,是否重新开始寻路
Auto Mask 自动遮罩
2017-08-20 14:03:40 hs2589758 阅读数 362

首先,搭建一下场景,场景要求:有遮挡,设置好不可走区域为navigation static 以及 not walkable。在人身上添加Nav Mesh Agent。设置好后勾选显示导航网格,就可以看见哪些地方是可走的,哪些是不可走的。下面是我搭建的一个小场景:


人的设置如下:



接着编写代码,代码如下:

using UnityEngine;
using System.Collections;

public class test : MonoBehaviour {
    
    NavMeshAgent ag;
    void Awake() { 
    }
	// Use this for initialization
	void Start () {

        ag = GetComponent<NavMeshAgent>();
	}
	
	// Update is called once per frame
    void Update()
    {
        //如果鼠标按下了左键
        if (Input.GetMouseButtonDown(0))
        {
           
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//返回一条射线从摄像机通过鼠标点击的位置
            RaycastHit hit;
            if (!Physics.Raycast(ray, out hit)) {                       //检测没有交点
                return;
            }
            Vector3 pos = hit.point;
            ag.destination = pos;                                       //如果有交点,hit点就是要走到的点
            if(ag.pathStatus==NavMeshPathStatus.PathInvalid)            //点是有效的
            {
             return;
            }
        }

    }
   
}


下面展示运行之后的效果就是我点击哪里,他就会自动寻路:





unity 3D AI自动寻路

阅读数 501

Unity3d 导航系统

阅读数 663

没有更多推荐了,返回首页