Unity3D AI导航手动设置连接线

NavMeshAgent

属性isOnOffMeshLink:表示是否处于连接线上
属性currentOffMeshLinkData:获取当前所在连接的数据,返回OffMeshLink类型的对象
方法stop():停止向导
方法resume():继续向导
方法CompleteOffMeshLink():完成当前连接线运动

OffMeshLinkData

属性startPos:起始位置
属性endPos:结束位置
属性linkType:表示连接的类型

步骤

  1. 判断物体是否在连接线上:nav.isOnOffMeshLink
  2. 停止向导:nav.stop()
  3. 开始计时:time2 += Time.deltaTime
  4. 判断物体所在连接线的类型:data.linkType
  5. 设置动画曲线变量,选择合适的运动曲线:public AnimationCurve curvel
  6. 用差值法手动位移物体:transform.position = Vector3.Lerp(起点位置, 终点位置, 计时器时间 / 规定时间)
  7. 判断连接线运动时间是否到达:if(time2 >= time1)
  8. 重置计时器为下一次运行准备:time2 = 0f
  9. 完成当前连接线运动:nav.CompleteOffMeshLink()
  10. 继续向导:nav.Resume()

代码

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

public class Nav1 : MonoBehaviour
{
    //创建一个动画曲线的变量
    public AnimationCurve curvel;

    private NavMeshAgent nav;
    private OffMeshLinkData data;
    private float time1, time2;

    // Start is called before the first frame update
    void Start()
    {
        nav = GetComponent<NavMeshAgent>();
        //设置连接线运动所用的时间
        time1 = 1; //1秒
        //计时器
        time2 = 0;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetButtonDown("Fire1"))
        {
            //获取鼠标射线对象
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            //射线碰到对象
            RaycastHit hit;
            //判断射线是否碰撞物体,射线长度限制为20
            if(Physics.Raycast(ray,out hit, 20)){
                //射线碰撞物体的位置点,设置为导航终点
                nav.SetDestination(hit.point);
            }
        }
        //判断物体是否在连接线上
        if (nav.isOnOffMeshLink)
        {
            //获取导航部件的连接线数据
            data = nav.currentOffMeshLinkData;
            //停止向导
            nav.Stop();
            //计时器开始计时
            time2 += Time.deltaTime;
            switch (data.linkType){
                //向下的连接线
                case OffMeshLinkType.LinkTypeDropDown:
                    //定义下落的起始点
                    Vector3 startDrop = data.startPos + Vector3.up*0.2f;
                    //定义下落的终点
                    Vector3 endDrop = data.endPos + Vector3.up * 0.2f;
                    //定义下落的中间断点
                    Vector3 midDrop = (startDrop + endDrop) / 2 + Vector3.up;
                    if (time2 <= time1 / 2)
                    {
                        //向前
                        transform.position = Vector3.Lerp(startDrop, midDrop, curvel.Evaluate(time2 * 2 / time1));
                    }
                    else
                    {
                        //向下
                        transform.position = Vector3.Lerp(midDrop, endDrop, curvel.Evaluate((time2 - time1 / 2) * 2 / time1));
                    }
                    break;
                //向上的连接线
                case OffMeshLinkType.LinkTypeManual:
                    //手动改变物体的位置,用向量取差值的方法
                    //startPos和endPos代表连接线,time2和time1的比值代表连接线上的一个位置,比值为0为startPos位置,比值为1为endPos位置
                    transform.position = Vector3.Lerp(data.startPos, data.endPos, time2 / time1);
                    break;
                //水平跳跃的连接线
                case OffMeshLinkType.LinkTypeJumpAcross:
                    //确认跳跃中间点的位置
                    Vector3 midJump = (data.startPos + data.endPos) / 2 + Vector3.up;
                    //重新定义起点位置
                    Vector3 startJump = data.startPos + Vector3.up*0.2f;
                    //重新定义终点位置
                    Vector3 endJump = data.endPos + Vector3.up*0.2f;
                    if (time2 <= time1 / 2)
                    {
                        //向上
                        transform.position = Vector3.Lerp(startJump, midJump, curvel.Evaluate(time2 * 2 / time1));
                    }
                    else
                    {
                        //向下
                        transform.position = Vector3.Lerp(midJump, endJump, curvel.Evaluate((time2 - time1 / 2) * 2 / time1));
                    }
                    break;
            }
            if (time2 >= time1)
            {
                //重置计时器
                time2 = 0f;
                //完成当前连接线运动
                nav.CompleteOffMeshLink();
                //继续向导
                nav.Resume();
            }
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值