您的位置:首页 > 移动开发 > Unity3D

UNITY自用笔记-3D寻路-网格寻路(旧版+新版)

2020-08-24 10:53 3227 查看

旧版

一、建立一个简单的NavMesh项目

1.新建:

Windows-AI-Navigation

2.简单的小实验-导航

此时我们需要让胶囊体“走到”小球的位置
1.选中plane,这里打钩,我们要使用静态的

2.点击bake,形成行走区域

3.脚本的实现

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

public class shishi : MonoBehaviour
{
public GameObject dest;
private NavMeshAgent agent;

void Start()
{
agent = GetComponent<NavMeshAgent>();
agent.SetDestination(dest.transform.position);
}

}

4.补充

此时我们就做出了个鬼畜的ai,他会直接穿墙而过到达目的地

这是因为 我们没有把三个障碍物 bake进来

二、Nav Mesh Agent组件参数及常见用法

1.参数

Steering(操控行为)

Speed:在NavMesh上移动的最大速度

Angular Speed:角速度

Acceleration: 物体从静止到最大速度的加速度

Stopping Distance:停止距离(常与remainingDistance一起使用)

Auto Braking:是否自动减速。(不勾选的话如果速度太快,物体会冲过去目标点以一定的惯性返回目的地)

Obstacle Avoidance(避障)

Quality(质量)(枚举)
None : 无
Low Quality:低质量
Medium Quality:中等质量
Good Quality: 高质量
High Quality: 高质量
Priority: 优先值,低优先值的会给高优先值的让路。

Path Finding(路径跟随)

Auto Traverse Off Mesh Linked:是否自动分离网格。(勾选时到达分离点时会从该分离点移动到另外一个分离点。)(一般不勾选,因为要配套爬墙或者跳跃的动画)

Auto Repath:是否自动重新规划路线。

Area Mask :网格遮罩。(枚举,规定物体可以通过的区域)

常用参数及其用法:

destination属性:可以设置目标点(SetDestination(target)方法相同效果)

nextPosition:获取或设置模拟navmesh代理的位置,可以手动的驱动角色进去移动(配合动画使用)

remainingDistance:物体当前位置与目标点的剩余距离。(设置了StopDistance后会出现一个问题,到时可以用这两个参数去调节)

UpdatePosition,UpdateRotation两个值都为bool值,可以通过更改他们俩,停止使用Agent组件来驱动物体移动和旋转。

isOnNavMesh: 判断物体是否在导航网格上。

isOnOffMeshLink: 判断物体是否在分离网格链接上。

2.常用API

三、unity navigation 参数

1.bake

2.Area


3.Off Mesh Links


地形之间可能有间隙,形成沟壑,或者是高台不能跳下,导航网格处于非连接的状态,角色无法直接跳跃,要绕一大圈才能到达目的地。off mesh links用于解决这种问题。

可以自动或者手动创建off mesh links,需要先设置bake选项卡中的Drop Height或者Jump Distance属性,前者控制跳跃高台最大高度,后者控制跳跃沟壑的最大距离。

举例:

选中需要创建Links的对象,在Object 选项卡内勾选Generate OffMeshLinks,再重新烘焙即可。需要注意,这里平台1设置了Links,而平台2没有设置。
此时,角色只能从平台1跳到平台2,如下图箭头所示:

手动添加Links,需要为地形对象添加off mesh link组件,可以创建两个空对象,分别用来控制跳跃的开始和结束点,如下所示:

4.Nav Mesh Obstacle

5.关于实现点击,控制人物行走参考

这篇文章

四、跳过障碍物和爬上斜坡

1.跨越障碍物

注意:
只有不超过我们设置跳跃的范围,他就为红色

2.爬上斜坡


我们可以设置角色爬坡的最大角度
让他决定爬不爬坡

五、设置优先路径

上面介绍了一个桥时的情况,那么拥有两座桥的时候呢?

拥有两座桥的时候play还是只会从第一座桥走,这个时候我们可以设置优先级来让小球只走第二座桥

首先设置走每座桥的代价

每座桥都调整一下路径

此时两座桥的颜色都不一样了

六、连接两个分离的地形off mesh links

此时虽然是蓝色的,但是却不可以到达

我们在想要跳跃的两个平台都勾选links

设置可跳跃距离


只能从上往下跳,高度一致时则可以双向,不一致时只能单向

七、off mesh links 组件

上一节我们已经可以完美实现 两个平台之间的跳跃

但是不够完美,因为他是不可控制的!

我们可以设置一个空物体,命名为link,底下放两个圆柱作为“传送点”,设置两个圆柱的位置,为link提那家off mesh links 组件

把开始和结束跳跃的参数 分别用两个圆柱拖入

因为上述已经讲过这里不再赘述

值得一提的是:他可以从下往上跳!

八、鼠标点击移动

九、可移动的障碍物

设置障碍物,不只是notwalk

这个组件可以告诉系统这是个障碍物

简陋的物体移动代码

public float speed = 0.1f;
private float position_z_start;
public float position_z_max = 10f;

private bool direction = true;
// Start is called before the first frame update
void Start()
{
position_z_start = transform.position.z;
}

// Update is called once per frame
void Update()
{
if(direction==true)
{
transform.position += new Vector3(0, 0, speed);
if(transform.position.z>(position_z_start+position_z_max))
{
direction = false;
}
}
else
{
transform.position -= new Vector3(0, 0, speed);
if(transform.position.z<position_z_start)
{
direction = true;
}
}
}
}

把这个取消勾选则可以在移动的时候也可以描绘他

新版

一、建立一个简单的新版 nav mesh项目

0.将新版拖入到项目里
新版的下载地址:下载

1.创建大体场景
2.添加新的标签,并设置新标签的跳跃高度要高于旧的
3.创建一个胶囊体和一个圆柱体,全部添加以下组件
(shishi就是鼠标移动的那个脚本 我随便输入的)
4.创建一个空物体,添加组件,并且bake

二、新版与旧版的不同

1.Nav Mesh surface
作为烘焙的主要组件,新版的烘焙组件可以挂载场景的任何地方来定义
2.Nav Mesh modifer
修改,重新烘焙
3.Nav Meshmodifiervolume
体积烘焙,范围烘焙
4.Nav Mesh link
连接两个不同的地形

提示:

1.此时旧版本和新版本的烘焙都可以使用,但假如这个时候,旧版本与新版本设置的可跨越高度不同的时候时,会优先使用新版本的

2.一旦项目中有了新版本,最好只用新版本的Nav Mesh surface
3.可以选择烘焙范围

(烘焙全部,烘焙一定区域(自己可以调节),只烘焙子对象的东西)
有了这些参数,就可以控制物体在一定范围内执行,超出范围则不动

三、动态烘焙

新版可以动态bake mesh!!!

那么该如何创建动态烘焙呢?

先清除原有的
在创建新物体,并为她添加新的脚本

public NavMeshSurface navMeshSurface;
// Start is called before the first frame update
void Start()
{
navMeshSurface.BuildNavMesh();
}

// Update is called once per frame
void Update()
{

}
}

此时运行后就会动态烘焙了

动态烘焙作用十分的大:
但我们进行游戏时站在一块区域,就会浮现一座桥,动态烘焙就会动态加载这座桥!使我们可以走过去


并为桥也添加动态烘焙的脚本

public NavMeshSurface navMeshSurface;
// Start is called before the first frame update
void Start()
{
navMeshSurface.BuildNavMesh();
}

// Update is called once per frame
void Update()
{

}
}

四、修改组件NavMeshModifier

创建一个障碍物,设置高度,使play可以跳过去

此时为障碍物添加NavMeshModifier组件

并为障碍物添加不可行走的选项
此时虽然高度play可以跳过,但是我们修改过后play就过不去了

可以在程序中动态修改

举例应用:
红色区域为岩浆池,只有怪物能走过去,玩家走不过去
分别为怪物和玩家添加不同的代理(nav mesh agent)

并且创建空物体
最后告诉系统人不可以走在岩浆

五、修改组件NavMeshModifierVolume

跟上面不同的是他这个是根据范围来设置

我们可以创建空对象,并为他添加NavMeshModifierVolume组件

可修改这个体积的大小,并修改为notwalk

bake一下 就可以设置 不可行走的区域

六、用NavMeshLink连接两个分开的地形

连接两个地形,不仅是平行分开的 也可以是垂直的两个地形

1.创建地形

2.创建空对象,并为他添加组件(代理型也可调整)
3.拖动权柄,放在两个平台的边上

4.此时物体就会飘过去
但是我们呢想要做传送阵对的效果
直接在移动上加入这个脚本

七、与动画结合

行走:

在move脚本里


用了一个最简单的方式,判断是否有速度,具体其他的请参考api

爬墙:

1.建立场景

思路:烘焙是根据y的垂直方向进行烘焙的

所以我们建立6个面的nav mesh suface

此时我们可以加link 实现“跳到”墙壁上

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: