赞
踩
1.选中要地面 或者 地图上的静态障碍物:树\房子\石头等
2.在U3D右边Inspector面板右上角Static旁边的倒三角 ,选中 Navigation static 勾, 表示地面导航层 ,把当前选中物体设置为导航层
3.菜单栏Window ->Navigation ,Inspector面板 右下角 Bake烘焙,生成导航路径数据
4.然后要移动的角色身上添加 NavMeshAgent组件,就可以导航移动角色
NavMeshAgent 组件面板属性
agent.updateRotation = false; //不允许NavMesh来旋转角色
agent.updatePosition = true; //允许NavMesh来移动角色agent.velocity.magnitude 这个也是速度, GetComponent<Animator>().SetFloat("Speed", agent.velocity.magnitude);
speed 移动速度
Angular Speed 转角速度 ,转身速度 角速度: 最高转速(度/秒)。
Acceleration 加速度,启动时的 最大加速度。
Stopping Distance 停止距离 ,,制动距离:制动距离。到目的地的距离小于这个值,代理减速。
Auto Traverse OffMesh Link 自动遍历OffMesh链接:自动移动并关闭OffMeshLinks
Auto Repath 自动重新寻路:如果现有的部分已失效,获得新的路径。
Height 高度:代理的高度(用于调试图形)。
Base offset 基本偏移:碰撞几何体相对于实际几何体垂直的偏移。
Obstacle Avoidance Type 障碍躲避类型 :躲避的质量水平。
NavMesh Walkable 导航网格行走:指定代理可以遍历的导航网格层类型。这个参数很有用,在接下来的实例中可以用到。
1.启用组件,即使角色在站立状态,也会轻微为角色添加移动,非常小的,但是会影响刚体的速度的属性.最好开始移动时 启用NavMeshAgent,移动结束关闭NavMeshAgent.
2. 使用了NavMeshAgent就不能用 transform.position = newPos;因为上面说了NavMeshAgent不停的为角色坐标赋值,用 WarpPoint(newPos)代替或者移动赋值前先NavMeshAgent.enabled = false。
3.在使用Rigidbody.AddForce施加外力时,首先关闭NavMeshAgent,重置刚体速度Rigidbody.velocity = Vector3.zero,然后在下一帧内对刚体加力,不能在同一帧进行!!!
remainingDistance //寻路剩余距离,角色和目标点的距离,(有时候为0,需要与Vector3.Distance()效验)
stoppingDistance //停止距离
SetDestination(Point);//设置要移动的目标点
destination //设置要移动的目标点
Stop(); //停止移动,寻路停止
Resume //Stop之后用Resume来恢复
path.corners;//储存路径,路径坐标点数组
ResetPath(); //重置路径
pathStatus //路径状况 ,当前路况的状态(完整,局部或者无效)。
PathComplete 在目的地的路径终止。The path terminates at the destination.
PathPartial 路径中不能到达目的地。The path cannot reach the destination.
PathInvalid 路径无效。The path is invalid.
velocity.magnitude //移动速度
//移动到B角色面前,用角色和B角色的包围盒的最近点,这样就不用修改 stoppingDistance停止距离
agent.stoppingDistance = 敌人包围盒半径的长度;
agent.destination = target.collider.ClosestPointOnBounds(transform.position);
- /// <summary>
- /// 是否在移动中
- /// </summary>
- /// <returns></returns>
- public bool IsMoving
- {
- get
- {
- if (agent != null && agent.enabled)
- {
- remainingDistance = Vector3.Distance(Transform.position, agent.destination);
- return agent.pathPending || remainingDistance > agent.stoppingDistance || agent.velocity != Vector3.zero;
- }
-
- return false;
- }
- }
/// 是否移动结束
bool EventMoveEnd() {
return state == "MOVING" && !IsMoving();
}
- /// <summary>
- /// 绘制移动路线
- /// </summary>
- void OnDrawGizmos()
- {
- var agent = GetComponent<UnityEngine.AI.NavMeshAgent>();
- var path = agent.path;
- Color c = Color.white;
- switch (path.status)
- {
- case UnityEngine.AI.NavMeshPathStatus.PathComplete: c = Color.white; break;
- case UnityEngine.AI.NavMeshPathStatus.PathInvalid: c = Color.red; break;
- case UnityEngine.AI.NavMeshPathStatus.PathPartial: c = Color.yellow; break;
- }
- for (int i = 1; i < path.corners.Length; ++i)
- Debug.DrawLine(path.corners[i-1], path.corners[i], c);
- }
状态切换
//取消移动
agent.ResetPath();
return "IDLE";
//角色死亡
agent.ResetPath();
//移动到点
agent.stoppingDistance = 0.1f;
agent.destination = pos;
return "MOVING";
// 移动到敌人包围盒前
agent.stoppingDistance = target.agent.radius;
agent.destination = target.collider.ClosestPointOnBounds(transform.position);
return "MOVING";
- using System;
- using UnityEngine;
- using UnityEngine.AI;
- using Debug = UnityEngine.Debug;
-
- public class MoveNavMeshAgent : MonoBehaviour
- {
- public NavMeshAgent agent;
- [SerializeField]
- bool _isMoveing = false;
- [SerializeField]
- float remainingDistance;
- [SerializeField]
- Vector3 curr_destination;
- [SerializeField]
- Vector3 last_destination;
- private Transform Transform;
-
- void Awake()
- {
- agent = gameObject.GetComponent<NavMeshAgent>();
- if(!agent)Debug.LogError(gameObject.name + " no NavMeshAgent compent");
- Transform = gameObject.transform;
- agent.updateRotation = true; //允许NavMesh来旋转角色
- agent.updatePosition = true; //允许NavMesh来移动角色
- agent.enabled = false;
- }
-
-
- /// <summary>
- ///使用了NavMeshAgent就不能用 transform.position = newPos;用 WarpPoint(newPos)代替或者移动赋值前先NavMeshAgent.enabled = false
- /// </summary>
- /// <param name="destination"></param>
- public void WarpPoint(Vector3 destination)
- {
- if (agent.enabled == false)
- {
- agent.enabled = true;
- }
- agent.Warp(destination);
- agent.enabled = false;
- }
-
- /// <summary>
- /// 是否在移动中
- /// </summary>
- /// <returns></returns>
- public bool IsMoving
- {
- get
- {
- if (agent != null && agent.enabled)
- {
- remainingDistance = Vector3.Distance(Transform.position, agent.destination);
- _isMoveing = agent.pathPending || remainingDistance > agent.stoppingDistance || agent.velocity != Vector3.zero;
- }
- else
- {
- _isMoveing = false;
- }
- return _isMoveing;
- }
- }
-
- /// <summary>
- /// 是否移动结束
- /// </summary>
- /// <returns></returns>
- public bool IsMoveEnd
- {
- get
- {
- return !IsMoving;
- }
- }
-
- //停止移动
- public void StopMove()
- {
- if (agent.enabled == true) //停止NavMeshAgent ,停止移动
- {
- agent.ResetPath();
- agent.Stop();
- agent.enabled = false;
- }
- }
-
- /// <summary>
- /// 移动到点
- /// </summary>
- public void MovePoint(Vector3 destination, float stoppingDistance = 0.17f)
- {
- curr_destination = destination;
- if (agent.enabled && curr_destination == last_destination && IsMoving && Math.Round(stoppingDistance, 2) == Math.Round(agent.stoppingDistance, 2))//与上一次目的地相同,就跳过
- {
- return;
- }
- if (agent.enabled == false)
- {
- agent.enabled = true;
- }
- agent.stoppingDistance = stoppingDistance;
- agent.destination = destination;
- last_destination = curr_destination;
- }
-
- /// <summary>
- /// 移动到距离敌人包围盒最近的点,如果是远程英雄的话 stoppingDistance 就是攻击距离,
- /// </summary>
- /// <param name="stoppingDistance"></param>
- /// <param name="enemyCollider"></param>
- public void MoveToEnemy(Collider enemyCollider, float stoppingDistance = 0.17f)
- {
- Vector3 destination = enemyCollider.ClosestPointOnBounds(Transform.position);
- MovePoint(destination, stoppingDistance);
- }
-
- /// <summary>
- /// 绘制移动路线
- /// </summary>
- void OnDrawGizmos()
- {
- if (agent != null && agent.enabled == true)
- {
- var path = agent.path;
- // color depends on status
- Color c = Color.white;
- switch (path.status)
- {
- case UnityEngine.AI.NavMeshPathStatus.PathComplete:
- c = Color.white;
- break;
-
- case UnityEngine.AI.NavMeshPathStatus.PathInvalid:
- c = Color.red;
- break;
-
- case UnityEngine.AI.NavMeshPathStatus.PathPartial:
- c = Color.yellow;
- break;
- }
- // draw the path
- for (int i = 1; i < path.corners.Length; ++i)
- Debug.DrawLine(path.corners[i - 1], path.corners[i], c);
- }
-
- }
-
- public void FixedUpdate()
- {
- #if UNITY_EDITOR
- var ShowState_Debug = IsMoving;
- #endif
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。