NavMeshAgent
属性isOnOffMeshLink:表示是否处于连接线上
属性currentOffMeshLinkData:获取当前所在连接的数据,返回OffMeshLink类型的对象
方法stop():停止向导
方法resume():继续向导
方法CompleteOffMeshLink():完成当前连接线运动
OffMeshLinkData
属性startPos:起始位置
属性endPos:结束位置
属性linkType:表示连接的类型
步骤
- 判断物体是否在连接线上:
nav.isOnOffMeshLink
- 停止向导:
nav.stop()
- 开始计时:
time2 += Time.deltaTime
- 判断物体所在连接线的类型:
data.linkType
- 设置动画曲线变量,选择合适的运动曲线:
public AnimationCurve curvel
- 用差值法手动位移物体:
transform.position = Vector3.Lerp(起点位置, 终点位置, 计时器时间 / 规定时间)
- 判断连接线运动时间是否到达:
if(time2 >= time1)
- 重置计时器为下一次运行准备:
time2 = 0f
- 完成当前连接线运动:
nav.CompleteOffMeshLink()
- 继续向导:
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();
}
}
}
}