unity自动寻路_unity3d 自动寻路算法 - CSDN
精华内容
参与话题
  • Unity自动寻路功能的实现(一)

    千次阅读 2018-08-11 23:25:07
    Unity自动寻路功能的实现 在Unity中,要实现自动寻路功能,其实是有很多办法的,今天我就介绍三种比较简单的办法,入手即会。 方法一:使用自带的Navigation寻路组件 操作如下:打开Unity,新建项目,新建一个...

    Unity自动寻路功能的实现

    在Unity中,要实现自动寻路功能,其实是有很多办法的,今天我就介绍三种比较简单的办法,入手即会。

    方法一:使用自带的Navigation寻路组件

    操作如下:打开Unity,新建项目,新建一个Plane,随便建一两堵墙,创建一个cube作为玩家,创建一个空物体,作为目的地,如下图
    这里写图片描述
    然后,把地面Plane和wall设置为静态,
    这里写图片描述
    点开Windows菜单栏,选择Navigation,打开Bake烘焙,点击Bake,可以看到蓝色部分,便是玩家可以行走的部分
    这里写图片描述
    随后给玩家也就是Cube加上Nav Mesh Agent组件
    这里写图片描述
    再新建一个名为NavTest脚本,挂在Cube上,脚本如下:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.AI;
    public class NavTest : MonoBehaviour {
    
        public Transform targetpos;
        private NavMeshAgent nav;
        void Start () {
            nav = GetComponent<NavMeshAgent>();
            nav.SetDestination(targetpos.position);
        }
    
        // Update is called once per frame
        void Update () {
    
        }
    }

    把目标点赋上去,运行,发现玩家走向目标点,而且还机智地避开墙壁。

    展开全文
  • Unity自动寻路的几种方法(一)

    万次阅读 2014-11-19 19:03:58
    在游戏中,我们经常会用到角色自动寻路这个功能,

    在游戏制作中,我们经常会用到角色自动寻路这个功能,点击小地图或者场景中的某一处时,角色会自动走向目的地,并且自动避开期间的障碍物。不单单在游戏的制作中用得到这个功能,在虚拟现实的项目中同样有时候会需要这样的功能。

    在Unity中,有多种方法能够实现寻路的功能,我试用的有以下这些方法建议大家可以尝试。首先是在一些游戏制作中用得最多的A星寻路,其次是插件iTween,他提供了很多方法,用起来也十分的简单,Unity也有自带的寻路组件Navigation,还有就是一些程序逻辑来编写,类似于AI,或者结合Lookat方法自主编写随机或者预定好的行走路线。下面我会详细地介绍一下以上途径的具体实现方法:

    首先是A星寻路。这是在一些三维游戏制作以及VR中用得比较多的一个寻路插件。其原理是A星寻路算法,如果想对A星算法做深入的了解可以谷歌一下,网络上有一些大神对该算法做了详细得剖析,下面我介绍一下这个插件怎么在Unity实现自动寻路的功能。

    首先先从网上下载到A星寻路插件,百度下到处是,导入到Unity中,插件中已有了很多个示例。讲解了在多种情况下,游戏主题如何拐过障碍物,到达目的地的。我主要介绍一下这一实现过程。在新场景中建一个Plane作为地面,新建一个胶囊体作为移动对象,建一个球体作为移动的目的地,再建立一些障碍物。如下图所示:


    在移动对象上挂上AIFollow.cs脚本,再添加了这个脚本之后,它会自动帮你添加上Character Controller和Seeker脚本,同时,在该对象上再添加上Funnel Modifier.cs,Simple Smooth Modifier.cs,Navmesh Controller.cs这三个脚本,如下图所示:


    其主要脚本就是AIFollow.cs这个脚本。其Target就是你的目的地,下面是一些关于他更新 途中结点的频率,移动速度,旋转速度等等变量,可以控制是否画出路径等等。这些参数可以自行调节,上图仅供参考。

    接下来在场景中建一个空对象,挂上Astar Path.cs脚本,选择RecastGraph选项,如下图所示:


    下面就是关于这些变量的设置,Cell Size变量跟你障碍物之间间隙有关,当你的障碍物之间间隙比较小的时候,建议这个值设小一点,下面是一些可走区域的高度,攀爬高度,以及对象半径等参数,下面可以设置区域的坡度,Max Edge Length这个参数跟你线的复杂度有关,最小可设置到0.05,当然数据特别小的时候,线圈布局很繁忙,很耗资源,一般设置几百就好了,效果可以自行调节调试。设置完成之后可以点击一下Snap bounds to scene,来规定界限。也可以自己微调其区域大小和位置。

    在Settings中设置一下以上属性,如上图所示。还有一些参数可以参考插件中的一些demo场景。

    一切都设置好了之后,运行场景就可以看到下面的效果:


    其绿色部分为求即将行走的路线,黄色的圈是球会在途中去寻找结点,也就是读取地上生成的线条 来确定走的路线。

    展开全文
  • 参考文章:Unity3D深入浅出 - 导航网格自动寻路(Navigation Mesh) http://blog.csdn.net/yuxikuo_1/article/details/44974739 unity3D——自带寻路Navmesh入门教程(二) ... Unity3D自动寻路系统Navig

    推荐阅读

    参考文章:列表

    Unity3D深入浅出 - 导航网格自动寻路(Navigation Mesh)
    unity3D——自带寻路Navmesh入门教程(二)
    Unity3D自动寻路系统Navigation(三)之人物上下斜坡设置
    Unity手游之路<八>自动寻路Navmesh之入门
    Unity手游之路<十>自动寻路Navmesh之跳跃,攀爬,斜坡
    NavMesh Agent

    一、Navigation面板

    这里写图片描述

    Navigation面板中包括几个模块

    Agents
    这里写图片描述
    这个是可以添加多个NabigationAgents可以用不同的Agents
    参数:
    Name:设置烘培Agents的名字
    Radius:烘培的半径,也就是物体的烘培的半径。这个值影响物体能通过的路径的大小
    越小,能行走的路径越大,边缘区域越小
    Height: 具有代表性的物体的高度,可以通过的最低的空间高度。这个值越小,能通过的最小高度越小。打个比方就是,1m7的人能通过1m7的洞是正常的,你可以设置height为1m,就能通过1m的高度
    Step Height :梯子的高度,这个还是要看模型阶梯的高度来设置
    Max Slope:烘培的最大的角度,就是坡度了

    Areas
    这里写图片描述
    这个是可以设置自动寻路烘培的层
    配合Nav Mesh Agents使用
    这里写图片描述
    Nav Mesh Agents->Area Mask->可以设置可以通过哪些层
    Back
    这里写图片描述
    这个就是设置烘培参数的
    参数:
    Radius:具有代表性的物体半径,半径越小生成的网格面积越大。
    Height:具有代表性的物体的高度。
    Max Slope:斜坡的坡度。
    Ste Height:台阶高度。
    Drop Height:允许最大的下落距离。
    Jump Distance:允许最大的跳跃距离。
    Min Region Area:网格面积小于该值则不生成导航网格。
    Height Mesh:勾选后会保存高度信息,同时会消耗一些性能和存储空间。

    Object
    这里写图片描述
    这个是设置去烘培哪个对象,比如地形之类的,就是可以行走的范围路径

    参数:

    Scene Filter:选择场景中那些对象,可以选择全部(All),地形(Terrains),有网格对象(Mesh Renderers)
    Navigation Static:可以烘培
    Generate OffMeshLinks:可以跳跃的地方
    两种生成OffMeshLink的方法:
    第一种生成OffMeshLink的方法
    添加OffMeshLink组件
    在这里插入图片描述
    参数:
    Start:设置起点
    End:设置终点
    两者顺序没有关系
    Cost Override:这个参数还没有研究
    BI Directional:同上
    Activated:同上
    Auto Update Position:同上
    Navigation Area:同上

    第二种生成OffMeshLink的方法
    在Navigation面板的Object栏里面把OffMeshLink Generation选项打上勾
    这里写图片描述
    这里要说的一点是,是不是有的人把OffMeshLink Generation选项打上勾之后Back之后还是没有出现OffMeshLink
    这里写图片描述
    这是因为你没有设置Jump Distance的值
    这里写图片描述
    这个值越大,能跳的距离越远,然后能跳的越高

    Navigation Area:表示是哪个Area,这个需要先设置,系统默认是Walkble、Jump、NotWalkble三种
    这个也要配合Nav Mesh Agent使用
    这里写图片描述

    二、NavMeshAgent组件

    2.1 Agent Size

    Radius
    物体的半径
    Height
    物体的高度,如果AgentHeight的值大于这个值,那么就不能通过
    Base Offset
    偏移值

    2.2 Steering

    Speed
    物体自动寻路的速度
    Angular Speed
    转角的速度,就是转弯的速度
    Acceleration
    加速度
    Stopping Distance
    物体停下来的距离,设置为0就是跟目标点的距离为0时停下来
    Auto Braking
    是否自动停下来

    2.3 Obstacle Avoidance

    Quality
    如果要防止一群寻路的物体围住目标点
    可以设置Quality为None,即可以让寻路物体互相穿过
    Priority
    优先权

    2.4 Path Finding自动寻路

    Auto Traverse Off Mesh Link
    自动跳跃链接
    Auto Repath
    自动复制路径
    Area Mask
    能通过的Maks层,这个可以配合Navigation组件中Areas(设置层的)使用

    三、NavMeshObstacle组件 障碍物组件

    这里写图片描述
    如果想要在场景中,动态的放置障碍物,然后也不想在场景开始前就洪培好地形的话,就可以在物体上加上这个组件,然后设置好参数,将自动寻路组件NavMeshAgent的寻路避让优先级调高一点
    Shape
    障碍物的模型,有Box和Capsule两个选项,从单词意思就可以看出来什么意思就不解释了
    Center
    中心点,如果障碍模型的中心点不在模型的中心点上就可以做一些调整
    Size
    设置大小
    Carve
    Move Threshold 模型 移动某个距离后进行烘焙
    Time To Stationary 指定模型在某个位置停止一段时间 后 在进行烘焙
    Carve One Stationary 勾选后,模型移动时不会实时烘焙

    四、实例例子

    步骤一般是这样的:
    1.在场景中摆放各种模型,包括地板,斜坡,山体,扶梯等
    2.为所有的模型加上Navigation Static和OffMeshLink Generatic(这个根据需要,例如地板与斜坡相连,斜坡就不需要添加OffMeshLink)
    3.特殊处理扶梯,需要手动添加Off Mesh Link,设置好开始点和结束点
    4.保存场景,烘焙场景

    例子一:简单寻路

    我们要实现一个功能:点击场景中的一个位置,角色可以自动寻路过去。角色会绕过各种复杂的障碍,找到一条理论上”最短路径“。

    步骤:
    1.创建地形
    2.添加角色
    3.创建多个障碍物,尽量摆的复杂一点,来检查Navmesh的可用性和效率。
    4.选中地形,在Navigation窗口中,设置Navigation Static
    5.依次选中障碍物,在avigation窗口中,设置Navigation Static
    7.Navigation窗口中,选择Bake(烘焙)界面,点击Bake按钮,进程场景烘焙,就可以烘焙出寻路网格了
    8.为角色添加NavMeshAgent组件。Component->Navigation->Nav Mesh Agent
    9.为角色新增一个脚本PlayerController.cs,实现点击目标,自动寻路功能

    代码:

    using UnityEngine;
    using System.Collections;
    
    public class PlayerController : MonoBehaviour
    {
        private NavMeshAgent agent;
    
    
        void Start()
        {
            //获取组件
            agent = GetComponent<NavMeshAgent>();
        }
    
    
        void Update()
        {
            //鼠标左键点击
            if (Input.GetMouseButtonDown(0))
            {
                //摄像机到点击位置的的射线
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit))
                {
                    //判断点击的是否地形
                    if (!hit.collider.name.Equals("Terrain"))
                    {
                        return;
                    }
                    //点击位置坐标
                    Vector3 point = hit.point;
                    //转向
                    transform.LookAt(new Vector3(point.x, transform.position.y, point.z));
                    //设置寻路的目标点
                    agent.SetDestination(point);
                }
            }
    
    
            //播放动画,判断是否到达了目的地,播放空闲或者跑步动画
            if (agent.remainingDistance == 0)
            {
                animation.Play("idle");
            }
            else
            {
                animation.Play("run");
            }
            
        }
    }
    

    例子二:上下斜坡

    烘焙上下斜坡的问题
    这里写图片描述
    在用Unity的自动寻路系统的时候,如果人物不能实现按照规定到达目的地,有绝大的原因是烘焙寻路出现了问题,所以这是我们首先需要重视的地方。
    下面就是一开始我烘焙的寻路,大家可能发现问题了,就是在两个红圈的位置是没有烘焙上的,并且区域很大,当人物寻路到这里的时候很容易卡在这里。
    这里写图片描述

    那就让我们来设置烘焙的参数吧。
    这里写图片描述
    首先来介绍一个各个参数的含义:
    Agent Radius:烘焙的半径,其数值越小则烘焙效果越好;
    Agent Height:烘焙的高度,人物通过的高度;
    Max Slope:烘焙的最大坡度,大于这个坡度的面将不会烘焙;
    Step Height:烘焙的台阶高度,如果高度差小于设置值,将视为连接。

    烘焙参数设置

    所以我们将烘焙半径调小点就可以解决这个问题了。
    我将烘焙半径设置为0.1,烘焙效果如下图,上坡和下边的地面连接处没有烘焙上的区域就很小啦。

    烘焙好的效果图
    这里写图片描述
    斜坡角度和连接问题
    如果上坡的角度很大,人物也会卡在上坡中,我现在设置的上坡角度是40度。如果把角度设置为30度或者以下,人物就可以很顺利的爬上斜坡啦。

    上坡角度很大
    这里写图片描述
    如果下坡的角度很大,人物就会直接跳下斜坡,我现在设置的下破的角度是50度。可以从图中看到人物是直接跳下来的。如果把角度设置为40度或者以下,人物就可以很顺利的下斜坡啦。

    下坡角度很大
    这里写图片描述

    还有就是斜坡与地面和站台连接处的问题,它们的连接之间一定不能有空隙,否则人物也容易卡在空隙处。如下图中,斜坡与站台没有完全连接上,有个很小的缝隙,即使寻路也烘焙得没有问题,人物有时候也会卡在这个地方。

    斜坡连接处处理
    这里写图片描述
    人物容易卡在寻路的边缘处

    因为寻路就是解决的人物通过查找最短的路径(在忽略消耗体力值前提下),并最终达到目的地的问题,所以在上下坡也经常会遇到人物会沿着斜坡一边运动,这个就可能使人物卡在烘焙好的寻路边缘处。
    我的解决办法是设置中间目标物,让其绕开寻路边缘运动,这就需要设置几个中间目标,当人物到达一个目标的时候,然后向着下一个目标运动。
    从图中可以看出设置了三个目标物,这样人物就可以顺利到达目标3啦。
    这里写图片描述

    代码:

    [RequireComponent(typeof(NavMeshAgent))]
    public class NavigationTest : MonoBehaviour {
    
        public Transform targetOne;
        public Transform targetTwo;
        public Transform targetThree;
    
        private NavMeshAgent navAgent;
    
        private float distanceOne;
        private float distanceTwo;
        // Use this for initialization
        void Start () {
    
            navAgent = transform.GetComponent<NavMeshAgent>();
    
            navAgent.SetDestination(targetOne.position);
        }
    
        // Update is called once per frame
        void Update () 
        {
    
            CheckReachTarget();
        }
    
        void CheckReachTarget()
        {
    
            distanceOne = Vector3.Distance(transform.position,targetOne.position);
            distanceTwo = Vector3.Distance(transform.position,targetTwo.position);
            if (distanceOne < 1f)
            {
                navAgent.SetDestination(targetTwo.position);
            }
    
            if (distanceTwo<1f)
            {
                navAgent.SetDestination(targetThree.position);
            }
        }
    }
    
    

    例子三:简单的自动寻路

    1.在Scene中新建三个Cube,如下图摆放。

    这里写图片描述

    2.选中上图三个Cube,并在Inspector面板中选中为静态(static)下拉选项的Navigation Static,如下图。
    这里写图片描述

    3.依次选择菜单栏中的Windows - Navigation ,打开后面板如下。
    这里写图片描述

    单击该面板右下角的Bake按钮,即可生成导航网格,下图为已生成的导航网格。

    在这里插入图片描述
    4.下面就可以让一个运动体根据一个导航网格运动到目标位置。

    首先新建一个Cube为目标位置,起名TargetCube。然后创建一个capsule(胶囊)运动体,为该胶囊挂在一个Nav Mesh Agent(Component - Navigation - Nav Mesh Agent);最后写一个脚本就可以实现自动寻路了。脚本如下:

    using UnityEngine;
    using System.Collections;
    
    public class Run : MonoBehaviour {
    
        public Transform TargetObject = null;
     
        void Start () {
            if (TargetObject != null)
            {
                GetComponent<NavMeshAgent>().destination = TargetObject.position;
            }
        } 
        void Update () {
        
        }
    }
    

    脚本新建完成后挂载到胶囊体上,然后将TargetCube赋予给胶囊体的Run脚本,运行场景,如下图,胶囊体会按照箭头的方向运动到Cube位置。

    这里写图片描述

    这样一个简单的自动寻路就完成了,如果要更精细的寻路,或要实现上坡,钻"桥洞"等,可根据下面介绍的相关参数进行调节。

    下面介绍Navigation组件和Nav Mesh Agent组件的相关参数。

    Navigation

    Object:物体参数面板
    Navigation Static:勾选后表示该对象参与导航网格的烘培。
    OffMeshLink Generation:勾选后可跳跃(Jump)导航网格和下落(Drop)。
    Bake:烘培参数面板  
    Radius:具有代表性的物体半径,半径越小生成的网格面积越大。
    Height:具有代表性的物体的高度。
    Max Slope:斜坡的坡度。
    Ste Height:台阶高度。
    Drop Height:允许最大的下落距离。
    Jump Distance:允许最大的跳跃距离。
    Min Region Area:网格面积小于该值则不生成导航网格。
    Height Mesh:勾选后会保存高度信息,同时会消耗一些性能和存储空间。
    Nav Mesh Agent:导航组建参数面板

    Radius:物体的半径
    Speed:物体的行进最大速度
    Acceleration:物体的行进加速度
    Augular Speed:行进过程中转向时的角速度。
    Stopping Distance:离目标距离还有多远时停止。
    Auto Traverse Off Mesh Link:是否采用默认方式度过链接路径。
    Auto Repath:在行进某些原因中断后是否重新开始寻路。
    Height:物体的高度。
    Base Offset:碰撞模型和实体模型之间的垂直偏移量。
    Obstacle Avoidance Type:障碍躲避的的表现登记,None选项为不躲避障碍,另外等级越高,躲避效果越好,同时消耗的性能越多。
    Avoidance Priority:躲避优先级。
    NavMesh Walkable:该物体可以行进的网格层掩码。

    例子四:Navigation实现高低落差以及跳跃的做法

    在这里插入图片描述
    在这里插入图片描述

    不管是爬楼梯,还是跳跃,NavMesh都是通过了OffMeshLink来做的。创建OffMeshLink的方法有两种,接下来会通过制作上面的例子来进行说明:
    这里写图片描述

    为了做这个例子,我们预先在场景里面准备了一些物体:摄像机是必须的,一个作为地面的Plane,然后是F1——F5几个高低落差不一样的台阶,L1和L2是楼梯模型, 控制人物主体man,还有移动的目标点target。
    其中man身上必须带有NavMesh Agent组件,为了观察方便在target身上带了light组件。

    这里写图片描述
    按照上一节所讲的,plane和F1——F5台阶在Navigation面板勾选Navigation Static选项,然后Bake,观察Scene视窗,会发现已经生成了我们所要的NavMesh网格,现在我们可以像上一节那样在plane上面给人物做寻路和移动了,但人物是不会爬楼梯的。

    这时候,我们找到L1楼梯,在楼梯的开始和结束的位置放置两个点,这两个点只需要拾取它的位移的,你可以用empty Gameobject来做,我这里为了便于观察,就拿了cube来做。开始点命名为startPoint,结束点命名为endPoint。

    这里写图片描述
    注意:startPoint和endPoint的位置要稍微比所在的平面高一点点。

    接下来介绍第一种生成OffMeshLink的方法。选择L1楼梯,然后在Component下拉选项中选择Navigation——Off Mesh Link。

    这里写图片描述

    选择后,OffMeshLink组件已经添加到了L1的身上,我们可以在Inspector面板看到:

    我们把刚才放置在场景里面的startPoint和endPoint指定到OffmeshLink组件的Start和End位置,其他选项默认不改变

    这里写图片描述

    再次Bake

    这里写图片描述
    这里写图片描述

    现在我们发现,在scene面板里面,在startPoint和endPoint之间生成了一条线,而方向是从startPoint指向endPoint的。

    在这里插入图片描述

    这时候,你应该可以通过移动目标点让角色开始爬楼梯了。但爬上去之后角色暂时不能跳下来,如果把目标点移动到plane上,角色会顺着楼梯爬下来。

    我们使用同样的方法对L2进行生成OffMeshLink。这时候,角色应该可以爬两层楼梯了。到此第一个目标完成了。

    接下来我们进行第二个目标的制作,首先先来分析一下我们的场景:

    这里写图片描述
    我们希望人物能从2.5M的高度往下跳,超过2.5M人物就不能跳了,太高会有危险。然后横向我们希望人物能跳过2米的沟。

    根据这个设定,我们的场景会是这样的情况:L1和L2只能通过爬楼梯,L2和L3之间可以跳跃,L3——L5是可以往下跳的。

    于是,我们在Navigation面板里面找到Bake栏,Drop Height(掉落高度)填2.5,Jump Distance(跳跃距离)填2,单位都是米

    这里写图片描述

    接下来介绍第二种生成OffMeshLink的方法:

    我们把L1——L5的物体选中,在Navigation面板的Object栏里面把OffMeshLink Generation选项打上勾

    这里写图片描述

    再次Bake,回到scene视窗:
    这里写图片描述

    这时候,场景里面会出现很多心的OffMeshLink,这是unity通过计算,把可以跳跃或者下落的地方自动生成了OffMeshLink了。

    这时候,你应该已经可以通过移动目标点,让角色进行跳跃和下落了。

    进行到这里,我们的第二个目标也完成了。

    不过有些朋友可能会提出疑问,在做的过程中,假如没有这个大兵的模型,而是用一个胶囊体来代替人物的话,它爬楼梯和跳跃的时候好像是在一瞬间完成的,没有大兵那个爬楼梯和跳跃动作的过程。如这样:

    这里写图片描述
    这里写图片描述
    的确是这样,因为默认的NaveMesh Agent组件上面是勾选了Auto Traverse Off Mesh Link(自动通过OffMeshLink)选项的。这样的意思是人物只要到了OffMeshLink的开始点,就会自动的移动到OffMeshLink的结束点。

    这里写图片描述

    假如各位需要对越过OffMeshLink时候进行自己的控制,是需要另外写脚本的。我这里简单的介绍一下方法,有兴趣的朋友可以自己试试。

    首先各位最好有用状态来控制角色的概念。比如人物可以分为站立、走路、跑步、上下楼梯、横向跳跃和往下掉落几种状态,针对NavMesh来说,人物简单的可以分为站立、正常的NavMesh寻路,和通过OffMeshLink移动几种状态。

    先把 Auto Traverse Off Mesh Link选项取消。

    然后,当人物在通过OffMeshLink移动的状态(可以用NavMeshAgent.isOnOffMeshLink来判断),获取到当前通过的OffMeshLink:

    OffMeshLinkData link = NavMeshAgent.currentOffMeshLinkData;

    这样你就能获取到link的开始点和结束点的坐标(link.startPos和link.endPos),这时候你的人物就可以用最简单的Vector3.Lerp来进行移动,当人物的位移到达了结束点的坐标,人物的OffMeshLink移动状态就可以结束,又重新变回正常寻路或者站立的状态了。在这个Vector3.Lerp的过程中,你可以随意的控制人物的爬行或者跳跃的动作。

    例子五:自动寻路Navmesh之跳跃,攀爬,斜坡

    步骤:
    1.在场景中摆放各种模型,包括地板,斜坡,山体,扶梯等
    2.为所有的模型加上Navigation Static和OffMeshLink Generatic(这个根据需要,例如地板与斜坡相连,斜坡就不需要添加OffMeshLink)
    3.特殊处理扶梯,需要手动添加Off Mesh Link,设置好开始点和结束点
    4.保存场景,烘焙场景
    5.添加角色模型,为其加Nav Mesh Agent组件
    6.为角色添加一个新脚本,AgentLocomotion.cs,用来处理自动寻路,已经角色动画变换。代码比较长,大家可以结合注释来理解

    代码:

    using UnityEngine;  
    using System.Collections;  
      
    public class AgentLocomotion : MonoBehaviour  
    {  
        private Vector3 target;//目标位置  
        private NavMeshAgent agent;  
        private Animation anim;//动画  
        private string locoState = "Locomotion_Stand";  
        private Vector3 linkStart;//OffMeshLink的开始点  
        private Vector3 linkEnd;//OffMeshLink的结束点  
        private Quaternion linkRotate;//OffMeshLink的旋转  
        private bool begin;//是否开始寻路  
      
        // Use this for initialization  
        void Start()  
        {  
            agent = GetComponent<NavMeshAgent>();  
            //自动移动并关闭OffMeshLinks,即在两个隔离障碍物直接生成的OffMeshLink,agent不会自动越过  
            agent.autoTraverseOffMeshLink = false;  
            //创建动画  
            AnimationSetup();  
            //起一个协程,处理动画状态机  
            StartCoroutine(AnimationStateMachine());  
        }  
      
        void Update()  
        {  
            //鼠标左键点击  
            if (Input.GetMouseButtonDown(0))  
            {  
                //摄像机到点击位置的的射线  
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);  
                RaycastHit hit;  
                if (Physics.Raycast(ray, out hit))  
                {  
                    //判断点击的是否地形  
                    if (hit.collider.tag.Equals("Obstacle"))  
                    {  
                        begin = true;  
                        //点击位置坐标  
                        target = hit.point;  
                    }  
                }  
            }  
            //每一帧,设置目标点  
            if (begin)  
            {  
                agent.SetDestination(target);  
            }  
        }  
      
        IEnumerator AnimationStateMachine()  
        {  
            //根据locoState不同的状态来处理,调用相关的函数  
            while (Application.isPlaying)  
            {  
                yield return StartCoroutine(locoState);  
            }  
        }  
      
        //站立  
        IEnumerator Locomotion_Stand()  
        {  
            do  
            {  
                UpdateAnimationBlend();  
                yield return new WaitForSeconds(0);  
            } while (agent.remainingDistance == 0);  
            //未到达目标点,转到下一个状态Locomotion_Move  
            locoState = "Locomotion_Move";  
            yield return null;  
        }  
      
        IEnumerator Locomotion_Move()  
        {  
            do  
            {  
                UpdateAnimationBlend();  
                yield return new WaitForSeconds(0);  
                //角色处于OffMeshLink,根据不同的地点,选择不同动画  
                if (agent.isOnOffMeshLink)  
                {  
                    locoState = SelectLinkAnimation();  
                    return (true);  
                }  
            } while (agent.remainingDistance != 0);  
            //已经到达目标点,状态转为Stand  
            locoState = "Locomotion_Stand";  
            yield return null;  
        }  
      
        IEnumerator Locomotion_Jump()  
        {  
            //播放跳跃动画  
            string linkAnim = "RunJump";  
            Vector3 posStart = transform.position;  
      
            agent.Stop(true);  
            anim.CrossFade(linkAnim, 0.1f, PlayMode.StopAll);  
            transform.rotation = linkRotate;  
      
            do  
            {  
                //计算新的位置  
                float tlerp = anim[linkAnim].normalizedTime;  
                Vector3 newPos = Vector3.Lerp(posStart, linkEnd, tlerp);  
                newPos.y += 0.4f * Mathf.Sin(3.14159f * tlerp);  
                transform.position = newPos;  
      
                yield return new WaitForSeconds(0);  
            } while (anim[linkAnim].normalizedTime < 1);  
            //动画恢复到Idle  
            anim.Play("Idle");  
            agent.CompleteOffMeshLink();  
            agent.Resume();  
            //下一个状态为Stand  
            transform.position = linkEnd;  
            locoState = "Locomotion_Stand";  
            yield return null;  
        }  
        //梯子  
        IEnumerator Locomotion_Ladder()  
        {  
            //梯子的中心位置  
            Vector3 linkCenter = (linkStart + linkEnd) * 0.5f;  
            string linkAnim;  
            //判断是在梯子上还是梯子下  
            if (transform.position.y > linkCenter.y)  
                linkAnim = "Ladder Down";  
            else  
                linkAnim = "Ladder Up";  
      
            agent.Stop(true);  
      
            Quaternion startRot = transform.rotation;  
            Vector3 startPos = transform.position;  
            float blendTime = 0.2f;  
            float tblend = 0f;  
      
            //角色的位置插值变化(0.2内变化)  
            do  
            {  
                transform.position = Vector3.Lerp(startPos, linkStart, tblend / blendTime);  
                transform.rotation = Quaternion.Lerp(startRot, linkRotate, tblend / blendTime);  
      
                yield return new WaitForSeconds(0);  
                tblend += Time.deltaTime;  
            } while (tblend < blendTime);  
            //设置位置  
            transform.position = linkStart;  
            //播放动画  
            anim.CrossFade(linkAnim, 0.1f, PlayMode.StopAll);  
            agent.ActivateCurrentOffMeshLink(false);  
            //等待动画结束  
            do  
            {  
                yield return new WaitForSeconds(0);  
            } while (anim[linkAnim].normalizedTime < 1);  
            agent.ActivateCurrentOffMeshLink(true);  
            //恢复Idle状态  
            anim.Play("Idle");  
            transform.position = linkEnd;  
            agent.CompleteOffMeshLink();  
            agent.Resume();  
            //下一个状态Stand  
            locoState = "Locomotion_Stand";  
            yield return null;  
        }  
      
        private string SelectLinkAnimation()  
        {  
            //获得当前的OffMeshLink数据  
            OffMeshLinkData link = agent.currentOffMeshLinkData;  
            //计算角色当前是在link的开始点还是结束点(因为OffMeshLink是双向的)  
            float distS = (transform.position - link.startPos).magnitude;  
            float distE = (transform.position - link.endPos).magnitude;  
      
            if (distS < distE)  
            {  
                linkStart = link.startPos;  
                linkEnd = link.endPos;  
            }  
            else  
            {  
                linkStart = link.endPos;  
                linkEnd = link.startPos;  
            }  
            //OffMeshLink的方向  
            Vector3 alignDir = linkEnd - linkStart;  
            //忽略y轴  
            alignDir.y = 0;  
            //计算旋转角度  
            linkRotate = Quaternion.LookRotation(alignDir);  
      
            //判断OffMeshLink是手动的(楼梯)还是自动生成的(跳跃)  
            if (link.linkType == OffMeshLinkType.LinkTypeManual)  
            {  
                return ("Locomotion_Ladder");  
            }  
            else  
            {  
                return ("Locomotion_Jump");  
            }  
        }  
      
        private void AnimationSetup()  
        {  
            anim = GetComponent<Animation>();  
      
            // 把walk和run动画放到同一层,然后同步他们的速度。  
            anim["Walk"].layer = 1;  
            anim["Run"].layer = 1;  
            anim.SyncLayer(1);  
      
            //设置“跳跃”,“爬楼梯”,“下楼梯”的动画模式和速度  
            anim["RunJump"].wrapMode = WrapMode.ClampForever;  
            anim["RunJump"].speed = 2;  
            anim["Ladder Up"].wrapMode = WrapMode.ClampForever;  
            anim["Ladder Up"].speed = 2;  
            anim["Ladder Down"].wrapMode = WrapMode.ClampForever;  
            anim["Ladder Down"].speed = 2;  
      
            //初始化动画状态为Idle  
            anim.CrossFade("Idle", 0.1f, PlayMode.StopAll);  
        }  
        //更新动画融合  
        private void UpdateAnimationBlend()  
        {  
            //行走速度  
            float walkAnimationSpeed = 1.5f;  
            //奔跑速度  
            float runAnimationSpeed = 4.0f;  
            //速度阀值(idle和walk的临界点)  
            float speedThreshold = 0.1f;  
      
            //速度,只考虑x和z  
            Vector3 velocityXZ = new Vector3(agent.velocity.x, 0.0f, agent.velocity.z);  
            //速度值  
            float speed = velocityXZ.magnitude;  
            //设置Run动画的速度  
            anim["Run"].speed = speed / runAnimationSpeed;  
            //设置Walk动画的速度  
            anim["Walk"].speed = speed / walkAnimationSpeed;  
      
            //根据agent的速度大小,确定animation的播放状态  
            if (speed > (walkAnimationSpeed + runAnimationSpeed) / 2)  
            {  
                anim.CrossFade("Run");  
            }  
            else if (speed > speedThreshold)  
            {  
                anim.CrossFade("Walk");  
            }  
            else  
            {  
                anim.CrossFade("Idle", 0.1f, PlayMode.StopAll);  
            }  
        }  
    }  
    

    效果图:

    点击任何一个地点,角色都可以自动寻路过去。中间可能经过不同的障碍物,我们可以看到角色如我们所预料的一样,可以跳跃下来,可以爬楼梯,最终到达目标点。
    这里写图片描述
    源码:
    https://pan.baidu.com/s/1tSzaGhKPj8m0AtC8pkwbPQ

    例子六:自动寻路Navmesh之高级主题

    隔离层自动生成寻路网格
    1.创建Plane实例P1,P2,两者之间出现一条鸿沟。直接控制角色位移是无法通过的。
    2.打开Navigation窗口,分别选中P1,P2,分别设置Navigation Static 和OffMeshLink Generatic
    这里写图片描述
    3.保存场景,点击场景烘焙按钮Bake。结束后我们可以看到P1,P2除了自身生产寻路网格外,它们直接还生成了连接纽带。
    4.添加角色模型Solder,为其添加NavMeshAgent(Component->Navigation->NavMeshAgent)
    5.给Solder添加PlayerController脚本

    代码:

    using UnityEngine;  
    using System.Collections;  
      
    public class PlayerController : MonoBehaviour  
    {  
        private NavMeshAgent agent;  
      
        public bool setAgentWalkMask;//是否需要动态修改寻路层,在scene4的实例中要用到  
      
        void Start()  
        {  
            //获取寻路组件  
            agent = GetComponent<NavMeshAgent>();  
        }  
      
        void Update()  
        {  
            //鼠标左键点击  
            if (Input.GetMouseButtonDown(0))  
            {  
                //摄像机到点击位置的的射线  
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);  
                RaycastHit hit;  
                if (Physics.Raycast(ray, out hit))  
                {  
                    //判断点击的是否地形  
                    if (!hit.collider.tag.Equals("Plane"))  
                    {  
                        return;  
                    }  
                    //点击位置坐标  
                    Vector3 point = hit.point;  
                    //转向  
                    transform.LookAt(new Vector3(point.x, transform.position.y, point.z));  
                    //设置寻路的目标点  
                    agent.SetDestination(point);  
                }  
            }  
      
            //播放动画  
            if (agent.remainingDistance == 0)  
            {  
                animation.Play("Idle");  
            }  
            else  
            {  
                animation.Play("Run");  
            }  
              
        }  
    }  
    

    5.点击任意的位置,可以看到角色都能自动寻路过去
    效果图
    这里写图片描述
    手动指定寻路网格方向
    1.将P1,P2的OffMeshLink Generatic去除
    2.在P1上新建一个空的GameObject Start,P2上新建一个空的GameObject End
    3.选中start,为它添加Off Mesh Link组件 Component->Navigation->OffMeshLink
    4.设置Off Mesh Link组件的属性,Start Point 为 start,End Point为end
    5.烘焙场景。我们可以看到有一条纽带从start指向end
    点击地图,可以看到角色如果要跨越P1和P2,一定是沿着我们手动创建的路径
    这里写图片描述
    导航网格障碍物 Navmesh Obstacle
    之前我们都是用固定的物体作为障碍物,然后烘焙场景。Unity还提供了动态的障碍物。任何一个GameObject都可以添加Navmesh Obstacle组件,变成一个障碍物。具体步骤是Component->Navigation->Navmesh Obstacle.它有两个属性:半径和高度,可以设置跟你的物品差不多的体积大小。

    寻路网格层的应用
    1.新建P1,P2,P3,P4等4个Plane,具体摆设形状见效果图
    2.在Navigation窗口中,添加两个层Layers:Blue层和Red层
    3.P1,P2的Navigation Layer设置为Default,P4的Navigation层设置为Red,P3设置为Blue
    4.添加两个角色,设置他们的NavMeshAgent寻路层(NavMesh Walkable)。一个将Red层去掉,一个将Blue层去掉
    5.点击P2的坐标,可以看到他们沿着不同的路径去目标点,一个走上层路线,一个走下层路线了。
    效果图
    这里写图片描述
    动态改变寻路网格层
    1.在scene3.unity基础上做一下修改。只保留一个角色
    2.新增两个按钮,“走上层”和“走下层”,在游戏运行时,可以改变Agent的寻路层。

    代码:

    //动态设置寻路路径层  
     void OnGUI()  
       {  
           if (!setAgentWalkMask)  
           {  
               return;  
           }  
           if (GUI.Button(new Rect(0, 0, 100, 50), "走下层"))  
           {  
               agent.walkableMask = 65;  
           }  
      
           if (GUI.Button(new Rect(0, 100, 100, 50), "走上层"))  
           {  
               agent.walkableMask = 129;  
           }  
       }  
    

    3.重新点击寻路,可以看到,选择不同的寻路层,角色的寻路路径也不同
    这里写图片描述
    看到代码中的agent.walkableMask = 65和129,大家会比较迷惑,其实寻路层每一层都是2的幂,见下图
    这里写图片描述
    所以上层的mask = Default(1)+Blue(128) = 129,下层的mak = Default(1)+Red(64) = 65

    例子七:Navigation烘焙

    Building a NavMesh
    在Unity中,NavMesh 的生成操作需要Navigation窗口(在Window> Navigation)

    在你的场景中构建NavMesh只需要4个步骤:

    这里写图片描述
    在这里插入图片描述
    选择场景中需要生成寻路的几何体-可行走表面和障碍物。
    在NavMesh面板中选择需要烘焙寻路的物体,检测是否勾选Navigation Static.
    根据你的agent大小来调整bake 面板的设置。
    Agent Radius : agent可以距离墙体 ,窗户或边缘多近的距离。
    Agent Height : agent可以通过的最低的空间高度。
    Max Slope : agent可以直接行走上去的最小坡度。
    Step Height: agent可以踩上(走上)的障碍物最高高度。
    点击bake按钮烘焙NavMesh。
    当你的Navigation窗口打开并且可见时,烘焙的NavMesh结果在场景中会以蓝色的覆盖层在物体的几何体表面显示。
    这里写图片描述

    烘焙完成后,您将在与NavMesh所属场景同名的文件夹中找到一个NavMesh资产文件。例如,如果在Assets文件夹中有一个名为First Level的场景,NavMesh将位于 Assets > First Level > NavMesh.asset.当烘焙结束后,你可以找到一个名字和你的场景名一样的文件夹,里面有一个NavMesh的资源文件,是属于这个场景的NavMesh。

    让物体可烘焙的其他方法
    这里写图片描述

    直接选择物体在Inspector面板顶部的Static 菜单,你可以直接选择Navigation Static,而不用再打开Navigation 窗口。

    NavMesh烘焙的高级设置
    最小区域面积
    这里写图片描述
    这里写图片描述

    Min Region Area 允许你剔除掉小的非连接NavMesh区域,当NavMesh区域小于指定值时将被剔除。

    请注意:有些区域可能无法被移除,尽管有Min Region Area 的设置,原因是NavMesh的构建是一个个的网格并行构建。当一个区域横跨两个网格将不会被移除,因为区域修剪过程中无法获取到周围的网格。

    Voxel Size 立体像素尺寸

    Manual voxel size :允许你改变烘焙操作过程中的精确性。

    Navigation在构建寻路网格过程中,第一遍会把场景光栅化为体素,然后提取可行走区域,最后可行走区域会烘焙成网格。因此体素尺寸Voxel Size的决定了寻路网格烘焙的精准性。

    提示:默认的体素设置最好的权衡了准确性和烘焙速度。在烘焙场景寻路的过程中,体素的增加会造成4x倍的内存消耗和4x倍的时间消耗。因此通常,你不需要自己去设置Voxel Size。
    这里写图片描述

    Smaller Agent Radius

    系统烘焙寻路是也会减小voxel size。如果你的agent尺寸保持不变,可能不需要增加NavMesh的构建分辨率。

    更简单的方法如下所示:

    设置你的半径为真实agent半径
    打开Manual Voxel Size,这会保持当前的voxel的大小并且冻结它。
    人为的将你的Agent Radius设置小,因为你已经勾选了Manual Voxel Size ,voxel size将不会改变。
    Height mesh : 允许你为角色提供更精准的位置。
    这里写图片描述

    导航时,NavMesh代理被约束在NavMesh的表面。由于NavMesh是可步行空间的近似,所以在构建NavMesh时,一些特性会被平均化。例如,楼梯可能在NavMesh中显示为一个斜坡。如果你的游戏需要准确的位置代理,你应该启用高度网格建设时,你烤NavMesh。该设置可以在导航窗口的高级设置中找到。注意,建筑高度网格将占用内存和处理在运行时,它将需要更长的时间来烘烤NavMesh。

    尽管普通的NavMesh 已经可以很好的运行,但是由于NavMesh只是一个近似的可行走的空间,只保持了一些均衡的特性,如果你的游戏agent需要更精准的行走位置,你可以启用高度网格Height Mesh,

    注意:高度网格Height Mesh将占用你“运行时”的内存和cpu,并且需要更多的烘焙时间。

    结束。。。

    这篇文章吸取了很多人的精华,有什么不对的地方希望都可以私信我。

    参考文章:
    Unity3D深入浅出 - 导航网格自动寻路(Navigation Mesh)
    http://blog.csdn.net/yuxikuo_1/article/details/44974739
    unity3D——自带寻路Navmesh入门教程(二)
    http://www.cnblogs.com/wangweixznu/p/5443071.html
    Unity3D自动寻路系统Navigation(三)之人物上下斜坡设置
    http://blog.csdn.net/qq_27678295/article/details/53730252
    Unity手游之路<八>自动寻路Navmesh之入门
    http://blog.csdn.net/janeky/article/details/17457533
    NavMesh Agent
    https://docs.unity3d.com/Manual/class-NavMeshAgent.html
    Unity 之Navigation烘焙
    http://blog.csdn.net/yupu56/article/details/54932049

    这里写图片描述

    展开全文
  • unity 自动寻路

    千次阅读 2018-10-28 12:04:36
    在项目开发中有时候,会用到unity自带的自动寻路系统NavMesh,今天就说下他的简单用法,NavMesh就是将游戏场景中复杂的结构组织关系简化为带有一定信息的网格,进而在这些网格的基础上通过一系列的计算来实现自动寻路...

    在项目开发中有时候,会用到unity自带的自动寻路系统NavMesh,今天就说下他的简单用法,NavMesh就是将游戏场景中复杂的结构组织关系简化为带有一定信息的网格,进而在这些网格的基础上通过一系列的计算来实现自动寻路,在导航中,只需要给导航物体挂载到导航物体上,导航物体便会自行根据目标点来寻找符合条件的路线,并沿着该路线行进到目标点。

    一、实现物体通过自动寻路移动到指定地点

    1.首先就是编辑一个简易的场景:

    2.选中场景中的对象物体,将Static设置为Navigation Static复选框,unity就会通过选中的对象生成导航网格:

    3.选择菜单栏中的Window--->Navigation命令,弹出Navgation视图。然后选择Navgation视图中的Bake按钮生成导航网格

    4.就会生成相应的bake信息,其中蓝色区域就是可以进行移动的区域:

     

    5.创建一个可移动的物体,这里就用一个胶囊体代替,为其添加NavMesh Agent组件,下面讲解一下这个组件的具体信息:

    Base offset                与地面偏移高度
    speed                        移动速度
    Angular Speed             转角速度 ,转身速度    角速度: 最高转速(度/秒)。
    Acceleration                 加速度,启动时的 最大加速度。
    Stopping Distance         停止距离 ,,制动距离:制动距离。到目的地的距离小于这个值,代理减速。
    Auto Traverse OffMesh Link 自动遍历OffMesh链接:自动移动并关闭OffMeshLinks
    Auto Repath                 自动重新寻路:如果现有的部分已失效,获得新的路径。
    Height                         高度:代理的高度(用于调试图形)。
    Base offset                   基本偏移:碰撞几何体相对于实际几何体垂直的偏移。
    Obstacle Avoidance Type 障碍躲避类型 :躲避的质量水平。
    NavMesh Walkable          导航网格行走:指定代理可以遍历的导航网格层类型。这个参数很有用,在接下来的实例中可以用到。

    6.为胶囊体添加移动脚本,通过鼠标点击移动到指定地点,代码如下:

        public Camera camera;  //相机    
        private NavMeshAgent navMeshAgent;
    
        // Use this for initialization
        void Start()
        {
            navMeshAgent = GetComponent<NavMeshAgent>();
        }
    
        // Update is called once per frame
        void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                if (navMeshAgent != null)
                {
                    //获取从主相机发出的一条射线
                    Ray mRay = Camera.main.ScreenPointToRay(Input.mousePosition);
                    RaycastHit mHit;
                    if (Physics.Raycast(mRay, out mHit))
                    {
                        //当碰撞到Terrain使获取到当时的位置
                        if (mHit.collider.gameObject.tag == "Player")
                        {
                            navMeshAgent.destination = mHit.point;
                        }
                    }                              
                }
            }
        }

    具体效果:

    备注:如果想实现可以直接跳跃到指定的目标位置处,可以设置Drop和Jump Distance,然后重新Bake就可以了:

    二、实现不同物体,沿自己的专有道路移动到指定位置

    1.搭建自己想要的场景信息:

    2.像上面的方式一样,对所有路径进行bake处理,但是唯一不同的需要设置不同的Layer,这里我们设置三个不同的layer

    3.先为不同的路径设置对应的layer

    4.为不同的移动的物体设置对应的layer:

    5.然后添加移动代码:

        public GameObject TargetGo;
        public GameObject[] Solider;
    
        // Use this for initialization
        void Start()
        {
            for (int i = 0; i < Solider.Length; i++)
            {
                Solider[i].GetComponent<NavMeshAgent>().destination = TargetGo.transform.position;            
            }
        }

    6.移动效果

    想了解更多相关信息,可以关注下方公众号或者QQ群:879354767

    展开全文
  • Unity自动寻路的几种方法(三)

    千次阅读 2015-02-16 17:19:44
    使用Unity来开发手游,自动寻路可以有很多种实现方式。第一种比较传统的是使用A星寻路,它是一种比较传统的人工智能算法,在游戏开发中比较常用到。大部分的页游和端游都用到这种技术。在Unity游戏也可以用这种技术...
  • Unity3D】自动寻路

    千次阅读 2017-05-17 17:24:13
    因此自《【iTween】指定路径位移》(点击打开链接)之后,自动寻路的需求应运而生。不过,Unity3D自带的功能,就能完成这个看起来高大上的功能。下面举一个例子说明这个问题。 如下图,摆了4个cube当作墙,然后摆一...
  • Unity自动寻路之导航

    2018-12-30 17:12:19
    现在游戏中的自动寻路基本就是两种做法 A*算法 和Unity中的导航系统 自动寻路导航的步骤 1.对场景进行烘焙 2.为寻路物体添加NavMeshAgent组件 3.为寻路物体添加脚本 设置寻路物体的目标点触发寻路的方式 在...
  • Unity自动寻路功能的实现(二)

    千次阅读 2018-08-13 23:12:00
    方法二:自己写脚本,定义路点自动寻路 首先,新建一个地面,添加一个Cube作为玩家,改名Player,然后创建3个空物体,位置要不一样,然后改名为Point01,Point02,Point03,我设置的如下: 3个路点作为玩家要去...
  • 现在的大部分mmo游戏都有了自动寻路功能。点击场景上的一个位置,角色就会自动寻路过去。中间可能会有很多的障碍物,角色会自动绕过障碍物,最终达到终点。使用unity3d开发2d游戏,自动寻路可以有很多种实现方式。第...
  • 自动寻路步骤: ① 把场景中不动的物体勾选static ② 烘焙寻路网格 ③ 添加NavMeshAgent组件 ④ 给需要寻路的物体添加脚本 实现: ① 搭一个简易场景 放上enemy和player: 把场景设为静态 ...
  • 这个是设置自动寻路的速度的,可以把这个值设置成0,然后就会光显示路线,而不自动寻路了。 <2>也可以随便设置一个值,然后就会显示路线,而且还会自动寻路Steering->Stopping Distance
  • Unity3d NavMeshAgent自动寻路组件

    万次阅读 2017-10-23 19:24:55
    我们常见的有三种寻路方式 1.路点寻路 2.单元格寻路 3.网格寻路 简单介绍一下 1.路点寻路 如下图,物体从 point位置出发依次经过(point1 、point2、point3、point4、point5)进行移动 代码如下 using System....
  • 《【Unity3D】自动寻路》(点击打开链接)给我们带来很多方便,尤其是3D游戏的主角移动方面,但是这个东西同样也会带来很多问题。如下图所示。这是一个比较失败的自动寻路例子,由于蓝色的球并不是让玩家主控,只是...
  • Unity3D开发敌人自动攻击和自动寻路

    万次阅读 多人点赞 2016-05-24 11:11:30
    简介:当制作动作类攻击游戏时,会用到敌人的自动攻击及自动寻找攻击目标,如何实现自动攻击和自动寻路呢?下面简单的讲解我对这方面的理解。 当你已经导入了敌人的模型并制作好了敌人动画控制状态机,接下来...
  • unity-Navigation寻路-添加障碍物Obstacle

    千次阅读 2016-10-15 11:08:56
    在场景中添加障碍物,需要点Bake重新烘焙出新的 导航网格,不是运行... 官网传送门:https://docs.unity3d.com/Manual/nav-CreateNavMeshObstacle.html 效果图创建障碍物创建个Cube对象 Obstacle1 身上挂一个组件 Nav
  • 综述赛车游戏的敌人赛车自动寻路一般有两种方式,一种是路点寻路,另外一种就是使用Unity自带组件NavMeshAgent进行寻路了,我介绍的是后者,另外后者在水平面上的汽车寻路导航还不错,但是一旦有Y方向的爬坡、下坡等...
  • 在window-》Navigation打开Bake 1、Agent Radius(物体的半径)物体半径越小,生成网格面积越大。 2、Agent Height:物体的高度 3、Max Slope 斜坡斜度(最大60°),如果大于设定值就不会生成网格。...
  • 领导让做个动态寻路的效果,而不是简单的自动寻路。 意思是,首先Monster 检测hero的位置先自动寻路,如果hero位置不改变,说明刚才的寻路路径是正确的;如果hero位置改变,但是改变后的位置依然在旧的寻路路径上,...
  • unity中为我们提供了很实用的寻路功能,接下来我们就看看这个寻路功能怎么事现    一、在window中打开Navigation窗口准备烘焙地形 二、在inspector界面中将场景中的障碍物勾选为静态( navigation static) ...
  • unity3d多人寻路问题方案

    千次阅读 2017-03-19 10:59:51
    相信大家用unity3d自带navmeshagent寻路的时候,一定会碰到多人寻路相互挤压的问题。 这个我已经解决了,而且已经应用到我们的项目中,感觉还不错。 首先提下问题的原因:navmeshagent在寻路的时候,并不会把别人...
1 2 3 4 5 ... 20
收藏数 1,405
精华内容 562
关键字:

unity自动寻路