【Unity3D导航组件】(二)Unity3D 实现人物上楼梯、走斜坡、攀爬、跳跃
推荐阅读
一、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:该物体可以行进的网格层掩码。
- 点赞
- 收藏
- 关注作者
评论(0)