自动寻路Navmesh之入门

现在的大部分mmo游戏都有了自动寻路功能。点击场景上的一个位置,角色就会自动寻路过去。中间可能会有很多的障碍物,角色会自动绕过障碍物,最终达到终点。使用Unity来开发手游,自动寻路可以有很多种实现方式。第一种比较传统的是使用A星寻路,它是一种比较传统的人工智能算法,在游戏开发中比较常用到。大部分的页游和端游都用到这种技术。在Unity游戏也可以用这种技术,Asset Store上面已经有相关的组件了,感兴趣的同学可以自己去了解。我在后面有机会再来详细介绍了。今天我们来学习Unity官方内置的寻路插件-Navmesh。由于内容比较多,我们将分几次来系统学习。今天先通过学习一个最简单的例子来入门。

(转载请注明原文地址http://blog.csdn.net/janeky/article/details/17457533

  • 实例
我们要实现一个功能:点击场景中的一个位置,角色可以自动寻路过去。角色会绕过各种复杂的障碍,找到一条理论上”最短路径“。
  • 步骤
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,实现点击目标,自动寻路功能
[csharp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. //Author:ken@iamcoding.com  
  5. public class PlayerController : MonoBehaviour  
  6. {  
  7.     private NavMeshAgent agent;  
  8.   
  9.   
  10.     void Start()  
  11.     {  
  12.         //获取组件  
  13.         agent = GetComponent<NavMeshAgent>();  
  14.     }  
  15.   
  16.   
  17.     void Update()  
  18.     {  
  19.         //鼠标左键点击  
  20.         if (Input.GetMouseButtonDown(0))  
  21.         {  
  22.             //摄像机到点击位置的的射线  
  23.             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);  
  24.             RaycastHit hit;  
  25.             if (Physics.Raycast(ray, out hit))  
  26.             {  
  27.                 //判断点击的是否地形  
  28.                 if (!hit.collider.name.Equals("Terrain"))  
  29.                 {  
  30.                     return;  
  31.                 }  
  32.                 //点击位置坐标  
  33.                 Vector3 point = hit.point;  
  34.                 //转向  
  35.                 transform.LookAt(new Vector3(point.x, transform.position.y, point.z));  
  36.                 //设置寻路的目标点  
  37.                 agent.SetDestination(point);  
  38.             }  
  39.         }  
  40.   
  41.   
  42.         //播放动画,判断是否到达了目的地,播放空闲或者跑步动画  
  43.         if (agent.remainingDistance == 0)  
  44.         {  
  45.             animation.Play("idle");  
  46.         }  
  47.         else  
  48.         {  
  49.             animation.Play("run");  
  50.         }  
  51.           
  52.     }  
  53. }  
完成了,可以看看效果:


  • 相关知识
1.角色身上的Nav Mesh Agent 组件

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

2.障碍物一定要有Mesh Render,用于烘焙寻路网格。
  • 总结
这个实例可以很简单的让我们学会如何最基本的使用自动寻路组件Nav。但是,这个组件还提供了更加强大的功能,比如,起始点和目标点中间出现阻断了,
怎么办?在下面的文章中,我们将会继续探寻其他强大的功能。

  • 源码

http://pan.baidu.com/s/1hqC6v4o

  • 参考资料

1.http://www.xuanyusong.com/

2.http://liweizhaolili.blog.163.com/

3.http://game.ceeger.com/Components/class-NavMeshAgent.html

好的,下面是详细的介绍和脚本写法: 1. 创建巡逻路径 首先,需要创建一个巡逻路径,可以使用Unity中的导航网格系统来创建。在导航网格中,我们可以指定AI可以移动的区域。使用以下脚本来创建一个导航网格: ``` using UnityEngine; using UnityEngine.AI; public class NavMeshController : MonoBehaviour { public NavMesh navMesh; public GameObject[] patrolPoints; private int currentPoint = 0; private NavMeshAgent agent; void Start() { agent = GetComponent<NavMeshAgent>(); } void Update() { if (!agent.pathPending && agent.remainingDistance < 0.5f) { GoToNextPoint(); } } void GoToNextPoint() { if (patrolPoints.Length == 0) { return; } agent.destination = patrolPoints[currentPoint].transform.position; currentPoint = (currentPoint + 1) % patrolPoints.Length; } } ``` 这个脚本使用了NavMeshAgent类来控制AI的移动。在Start()方法中,我们获取了NavMeshAgent组件,并在Update()方法中检测AI是否到达了目标点。如果AI到达了目标点,就会选择下一个巡逻点。 2. 添加视角限制 为了实现视角限制,可以使用Unity中的摄像机控制脚本,将摄像机的视角限制在一个特定的范围内。使用以下脚本来控制摄像机: ``` using UnityEngine; public class CameraController : MonoBehaviour { public Transform target; public float distance = 10.0f; public float height = 5.0f; public float smoothDampTime = 0.2f; private Vector3 smoothDampVelocity; void LateUpdate() { Vector3 targetPosition = target.position + Vector3.up * height - target.forward * distance; transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref smoothDampVelocity, smoothDampTime); transform.LookAt(target.position); } } ``` 这个脚本使用了SmoothDamp方法来平滑地移动摄像机。在LateUpdate()方法中,我们计算了摄像机的位置和朝向,并使用SmoothDamp方法来将摄像机移动到目标位置。 3. 实现攻击行为 使用以下脚本来实现AI的攻击行为: ``` using UnityEngine; public class Attack : MonoBehaviour { public float attackRange = 1.5f; public float attackCooldown = 2.0f; public int attackDamage = 10; private float lastAttackTime = 0.0f; void OnTriggerStay(Collider other) { if (Time.time - lastAttackTime > attackCooldown && other.tag == "Enemy") { Vector3 direction = other.transform.position - transform.position; float distance = direction.magnitude; direction /= distance; if (distance < attackRange) { other.GetComponent<Health>().TakeDamage(attackDamage); lastAttackTime = Time.time; } } } } ``` 这个脚本使用了OnTriggerStay方法来检测AI是否与其他对象碰撞。如果AI与其他对象碰撞,并且已经过了攻击冷却时间,就会进行攻击行为。 4. 设置AI的行为 最后,需要编写代码来控制AI的行为。使用以下脚本来控制AI的行为: ``` using UnityEngine; public class AIController : MonoBehaviour { public NavMeshController navMeshController; public CameraController cameraController; public Attack attack; void Start() { navMeshController.enabled = true; cameraController.enabled = true; attack.enabled = true; } void Update() { // Do nothing } } ``` 这个脚本将NavMeshController、CameraController和Attack组件添加到AI对象上,并在Start()方法中启用这些组件。在Update()方法中,我们不需要做任何事情,因为NavMeshController和Attack组件已经在各自的脚本中实现了自动巡逻和攻击行为。 总之,要实现一个有自动巡逻、视角限制并且会攻击别人的AI,需要使用Unity中的多个功能和工具,包括导航网格系统、摄像机控制脚本、碰撞检测和协程。以上是一个简单的示例脚本,你可以根据自己的需求进行修改和扩展。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值