IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 路点寻路(unity3D) -> 正文阅读

[游戏开发]路点寻路(unity3D)

路点寻路

第一步:现在场景上确认几个定点,并用Gizmos画出路线

首先在场景中确定几个空节点,放在一个父节点下面

将脚本绑在该父节点上

在这里插入图片描述

画出来的效果:

在这里插入图片描述

public class WayPoint : MonoBehaviour
{
    //用一个数组对点进行存储
    Transform[] points;

    public Transform[] Points
    {
        get
        {
            if(points == null)
            {
                points = new Transform[transform.childCount];
                for (int i = 0; i < points.Length; i++)
                {
                    points[i] = transform.GetChild(i);
                }
            }
            return points;
        }
    }
    
    // Start is called before the first frame update
    void Start()
    {
     
    }

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


    //和update类似,也是每帧调用一次
    //OnDrawGizmos是在代码编译完成时开始执行
    private void OnDrawGizmos()
    {
        //Gizmos.DrawCube(Vector3.zero, Vector3.one);
        //划线的颜色
        Gizmos.color = Color.red;
        
        for (int i = 0; i < Points.Length - 1; i++)
        {
            Gizmos.DrawLine(Points[i].position, Points[i + 1].position);
        }
    }
}

思考:

  1. 用数组对行动的点进行存储
  2. OnDrawGizmos() 在代码编译的时候执行,然后调用属性函数,获取到用于画线的点
  3. 每帧执行,每帧都在画线

第二步:物体的移动

主要用的api:

  1. transform.LookAt() 物体的朝向
  2. Vector3.MoveTowards(起点坐标,终点坐标,最大步长),当距离终点较远时,每步走最大的步长的长度,返回要移动的位置
  3. Vector3.Distance() 计算两个向量的间距
  4. Vector3.LerpVector3 a, Vector3 b, float t)插值
  5. Vector3.Cross() 法线
public class Patrol: MonoBehaviour
{
    //当前怪物所在的路径,以及路径信息
    public WayPoint way;
    //要移动到的路径点的下标
    int targetIndex;
    //移动速度
    public float moveSpeed;

    //旋转的速度
    public float rotateSpeed;

    //要旋转的目标的朝向
    Vector3 targetDir;

    // Start is called before the first frame update
    void Start()
    {
        transform.position = way.Points[0].position;
        transform.LookAt(way.Points[1]);
        targetIndex = 1;

        targetDir = way.Points[targetIndex].position - transform.position;
    }

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

        //transform.position += transform.forward * moveSpeed * Time.deltaTime;
        //maxDistanceDelta最大的步长
        //Vector3.MoveTowards(起点坐标,终点坐标,最大步长),当距离终点较远时,每步走最大的步长的长度,返回要移动的位置
        //当靠近或抵达终点时,只会返回终点的坐标,不会越过
        transform.position = Vector3.MoveTowards(transform.position, way.Points[targetIndex].position, moveSpeed * Time.deltaTime);
        //Rotate();
        if (Vector3.Distance(transform.position, way.Points[targetIndex].position) <= 0.1f)
        {
            targetIndex++;
            if (targetIndex >= way.Points.Length)
            {
                this.enabled = false;
                return; //用return的原因是,更改enabled状态后,下一帧不会执行,这一帧会执行完
            }
            targetDir = way.Points[targetIndex].position - transform.position;
           
           // transform.LookAt(way.Points[targetIndex]);
        }

        transform.forward = Vector3.Lerp(transform.forward, targetDir, rotateSpeed * Time.deltaTime);

    }
    
    void Rotate()
    {
        Vector3 dir = way.Points[targetIndex].position - transform.position;
        float angle = Vector3.Angle(transform.forward, dir);

        angle = Mathf.Min(angle, rotateSpeed);

        transform.Rotate(Vector3.Cross(transform.forward, dir)* angle);
    }
}


思路:

主要是关于人物的向目标点的移动和移动过程中的转向问题

移动的问题:

  1. 首先要知道路线,可以通过静态的绑定或者动态的查找,主要是获取绑定上面路线脚本的节点,通过脚本组件里面的属性获取到路线点

  2. 定义一个变量存储要到达的点在数组中的的下标,定义移动的速度

  3. 在start里面,首先设置物体的位置到第一个点,物体朝向第二个点,并且将下标加一

  4. 最重要的就是移动,有两种方法:

    第一种:最简单的,因为角度确定,移动是向前的,所以每帧去加上一个向前的向量即可

    第二种:利用Vector3.MoveTowardsAPI,可以避免因为速度过快,而超出去的情况

  5. 转向的校验:通过物体与目标点的向量的间距来判断是否转向,转向将下标加一,并且还要校验下标是否越界,如果越界,就关掉脚本的活性,并且跳出语句。

转向的问题:

  1. 转向的问题也有几种解决办法

    第一种:直接通过transform.LookAt()来更改物体的朝向

    第二种:写一个更改角度的函数,首先获取物体与目标点间的向量,然后计算出物体向前的向量与获取向量的夹角,设置一个旋转角度,根据旋转角度不停的旋转方向,直到夹角为0;

    注意:①这里在旋转的时候,不能绕着y轴旋转,而是绕着法向量进行旋转,因为角度有正有负

    ? ②可以优化的地方,在旋转之前,将两向量的夹角与设定的旋转的角度进行比较,选择较小的角进行旋转,可以避免旋转过的情况出现

    第三种:插值的方法,将forword的方向与目标点的方向,进行插值改变

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-10-08 12:05:58  更:2021-10-08 12:06:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 2:35:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码