系列文章目录
Navemesh寻路系列文章
文章目录
目录
系列文章目录
文章目录
前言
一、NavMeshPath是什么?
二、使用步骤
1.引入库
2.读入数据
总结
前言
navemesh已经大量使用到游戏中,但大部分寻路都是使用SetDestination函数,给予一个目标点移动,第一人称直接操控移动的文章很少。
为了解决这个问题,特此出了这篇文章。
这篇博客主要使用NavMeshPath,通过得到移动数组,最终实现正确移动。
一、NavMeshPath是什么?
由导航系统计算的路径。
路径以路标列表的形式表示,存储在 corners 数组中。这些路标不是由用户脚本直接设置的,但 NavMesh.CalculatePath 函数和 NavMeshAgent.path 属性会返回分配有正确路标的 NavMeshPath。
corners | 路径的角点。(只读) |
status | 路径状态。(只读) |
二、使用步骤
1.引入库
代码如下:
using UnityEngine;
using UnityEngine.AI;
2.读入数据
代码如下(示例):
NavMeshAgent.CalculatePath(_pos, m_NavMeshPath);
该处可以获取到navemesh的寻路路径。
然后使用位移实现点到点之间的移动,目前的写法可以适用于上下坡等不平整地图。
完整代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
/// <summary>
/// 人物平滑移动器
/// </summary>
public class AgentMove : MonoBehaviour
{
public float speed = 0.5f;
// Start is called before the first frame update
void Start()
{
NavMeshAgent = transform.gameObject.GetComponent<NavMeshAgent>();
m_NavMeshPath = new NavMeshPath();
}
private NavMeshAgent NavMeshAgent;
private NavMeshPath m_NavMeshPath;
/// <summary>
/// 前一个路径点索引
/// </summary>
private int m_previousIndex = 0;
/// <summary>
/// 后一个路径点索引
/// </summary>
private int m_currentIndex = 1;
private bool isUpdate = false;
void GetNav(Vector3 _pos)
{
isUpdate = true;
Debug.LogError(transform.position + " " + _pos);
transform.LookAt(_pos);
//计算NavMeshPath
NavMeshAgent.CalculatePath(_pos, m_NavMeshPath);
//初始化路径点索引
m_previousIndex = 0;
m_currentIndex = 1;
//if (m_NavMeshPath.corners.Length>1)
//transform.position = m_NavMeshPath.corners[m_CurrentPathPointIndex];
//Debug.Log(m_NavMeshPath.corners[m_CurrentPathPointIndex]+" "+ m_NavMeshPath.corners.Length);
}
/// <summary>
/// 移动到目标点(NavMeshPath.corners第0个路径点是当前游戏物体所在位置,以此类推)
/// </summary>
public void RunToTarget()
{
isUpdate = m_currentIndex <= m_NavMeshPath.corners.Length - 1;
//防止数组越界
if (!isUpdate) return;
var _pos = transform.position;
_pos.y = m_NavMeshPath.corners[m_currentIndex].y;
//如果游戏物体坐标与当前路径点坐标距离小于0.1即可认为已抵达,可以向下一个路径点导航
if ((_pos - m_NavMeshPath.corners[m_currentIndex]).magnitude <= 0.1f)
{
//递增路径点索引
m_previousIndex++;
m_currentIndex++;
//防止数组越界
if (m_currentIndex > m_NavMeshPath.corners.Length - 1)
{
//Debug.LogError(m_NavMeshPath.corners[m_CurrentPathPointIndex]);
//处理动画切换,请无视
return;
}
//处理人物转向,请无视
}
//匀速运动。计算出前一个路径点到当前路径点方向,然后移动
transform.Translate(
((-m_NavMeshPath.corners[m_previousIndex] +
m_NavMeshPath.corners[m_currentIndex]).normalized) *
(/*Time.deltaTime **/ speed/* *2f*/), Space.World);
Debug.Log(transform.position + " " + m_NavMeshPath.corners[m_currentIndex]);
}
public void Update()
{
var _fx = 1;
if (Input.GetKey(KeyCode.W))
{
GetNav(transform.position + Vector3.forward * _fx);
}
if (Input.GetKey(KeyCode.A))
{
GetNav(transform.position - Vector3.right * _fx);
}
if (Input.GetKey(KeyCode.S))
{
GetNav(transform.position - Vector3.forward * _fx);
}
if (Input.GetKey(KeyCode.D))
{
GetNav(transform.position + Vector3.right * _fx);
}
if (Input.GetKeyUp(KeyCode.W) || Input.GetKeyUp(KeyCode.A) || Input.GetKeyUp(KeyCode.S) || Input.GetKeyUp(KeyCode.D))
{
isUpdate = false;
}
//开始导航
if(isUpdate)RunToTarget();
}
}
实现效果截图:
使用WASD即可控制移动。 文章来源:https://www.toymoban.com/news/detail-436713.html
总结
以上就是今天要讲的内容,本文仅仅简单介绍了NavMeshPath的使用,而NavMeshPath提供了大量能使我们快速便捷地处理数据的函数和方法。(吐槽下~官方总结)文章来源地址https://www.toymoban.com/news/detail-436713.html
到了这里,关于Unity使用NaveMesh实现第一人称视角移动的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!