第39天A星寻路和路点寻路

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
    }



}
原文地址:https://www.cnblogs.com/yifengs/p/14247557.html