A星寻路
Navigation
1.渲染可寻路路径
Navigation对需要渲染路径的模型勾选Navigation Static
点击Bake 进行烘焙
2.对需要进行寻路的物体添加Nav Mesh Agent 组件
3.脚本
需要引入using UnityEngine.AI;
障碍物寻路
需要将场景中的障碍物也勾选上navmesh Static 然后进行重新烘焙
Bake参数
Agent Radius:烘培路径可行与不可行的间隔
Agent Height:可行的高度
Max Slope:可行的最大坡度
Step Height:最大台阶高度
OffMeshLinks:
- Drop Height:可行的最大跳下高度
- Jump Distance:最大的跳跃距离
Nav Mesh agent
Bse Offest:组件的数值偏移
Speed:移动速度
Agular Speed:角速度
Acceleration:加速度
Stopping Distance:距离目标点多远停止
Radius:寻路的碰撞半径
Height:寻路的碰撞高度
Quality:寻路的精细度
Priority:寻路权重(0-99),值越小优先级越高,优先级地的寻路组件需要让着优先级高的走
Auto Traverse Off Mesh Link:是否支持Off 功能
Auto Repath:自动重新规划路径
Area Mask:可行路径区域
API
变量名.CalculatePath(Vector3 targetPosition,NavMeshPath path) 判断当前位置到目标位置的距离 计算到目标点的路径
path.corners是当前路径中的拐点集合
动态障碍
Nav Mesh Obstacle组件
注意勾选Carve
路点寻路
路点管理组件
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PathsManager : MonoBehaviour { List<EnemyGroup> enemyGroups = new List<EnemyGroup>(); //敌人分组列表 public Transform[] nodes; //路点组 本组件挂载在路点物体上 private void Awake() { enemyGroups.Add(new EnemyGroup("Red", 5, 2, 5)); //添加一波Red敌人 ,5个 间隔2秒 下一组敌人到来时间 enemyGroups.Add(new EnemyGroup("Green", 3, 1, 3)); enemyGroups.Add(new EnemyGroup("Blue", 12, 1, 5)); nodes = new Transform[transform.childCount]; //获取本物体下方的所有的子物体 for (int i = 0; i < transform.childCount; i++) { nodes[i] = transform.GetChild(i); //给每个路点赋值 } } private void Start() { StartCoroutine(StartCreateEnemy()); //开启协程 } IEnumerator StartCreateEnemy() { for (int i = 0; i < enemyGroups.Count; i++) //获取敌人一共有多少组 { //i每一次循环控制一组一组敌人 for (int j = 0; j < enemyGroups[i].num; j++) //每一组敌人个数遍历 { //j每次循环控制当前组的敌人 CreateMonster(enemyGroups[i].prefabName); //生成敌人 yield return new WaitForSeconds(enemyGroups[i].interval); //间隔几秒生成下一个 } yield return new WaitForSeconds(enemyGroups[i].nextTime); //间隔下一组敌人到来时间 } } void CreateMonster(string prefabName) { GameObject prefab = Resources.Load<GameObject>(prefabName); //根据传过来的敌人名,加载资源 //克隆生成敌人 GameObject monster = Instantiate(prefab, nodes[0].position, Quaternion.LookRotation(nodes[1].position - nodes[0].position)); //设置路点 monster.GetComponent<e>().SetPath(nodes); } //怪物组 public struct EnemyGroup { public string prefabName; //预制体名 public int num; //敌人数量 public float interval; //每个敌人生成间隔时间 public float nextTime; //下一组敌人间隔 public EnemyGroup(string prefabName, int num, float interval, float nextTime) { this.prefabName = prefabName; this.num = num; this.nextTime = nextTime; this.interval = interval; } } }
敌人组件
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Enemy : MonoBehaviour { public float moveSpeed = 2f; public Queue<Transform> paths = new Queue<Transform>(); private Transform target; void Update () { if (Vector3.Distance(transform.position, target.position) <= moveSpeed * Time.deltaTime) //判断距离目标点的距离是否小于下一次移动距离 { transform.position = target.position; //到达目标距离 if (paths.Count <= 0) //判断路点数组是否还有数据 { //走到头了 Destroy(gameObject); //如果没有说明到达终点,删除自己 return; } //要切换下一个路点 target = paths.Dequeue(); //如果还有数据,则弹出下个目标点 transform.LookAt(target); //看向目标 } else { transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime); //向目标移动 } } //给怪物设置路点 public void SetPath(Transform[] nodes) { //将数组中的路点存储到队列中 paths.Clear(); //先清空数组 for (int i = 0; i < nodes.Length; i++) { paths.Enqueue(nodes[i]); //把路点一个一个存入数组 } target = paths.Dequeue(); //弹出第一个路点 transform.LookAt(target); //朝向路点 } }
单波敌人逻辑
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MonsterManger : MonoBehaviour { public float interval = 2f; //每个怪物生成间隔 public int monsterNum = 10; //怪物生成数量 private float timer = 0f; //计时器 public Transform[] nodes; //路点组 private void Awake() { nodes = new Transform[transform.childCount]; //实例路点组对象,给出数组长度 for (int i = 0; i < transform.childCount; i++) //把每个路点赋值给路点数组 { nodes[i] = transform.GetChild(i); } } // Update is called once per frame void Update () { timer += Time.deltaTime; //计算时间 if (timer >= interval && monsterNum > 0) //如果计时器大于怪物生成间隔,且怪物总数大于0,则生成怪物 { //生成怪物 CreateMonster(); } } void CreateMonster() { GameObject prefab = Resources.Load<GameObject>("Cube"); //加载怪物资源 //克隆生成怪物 GameObject monster = Instantiate(prefab, nodes[0].position, Quaternion.LookRotation(nodes[1].position - nodes[0].position)); //把路点数组信息传给怪物 monster.GetComponent<Enemy>().SetPath(nodes); timer = 0; //重新计时 monsterNum--; //怪物总数减1 } }