当前位置:   article > 正文

NavMeshAgent 寻路导航组件_navmeshagent 如何关闭插件内部移动

navmeshagent 如何关闭插件内部移动

NavMesh地面的烘焙方法


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);

 

 

 

判断是否正在移动中

  1. /// <summary>
  2. /// 是否在移动中
  3. /// </summary>
  4. /// <returns></returns>
  5. public bool IsMoving
  6. {
  7. get
  8. {
  9. if (agent != null && agent.enabled)
  10. {
  11. remainingDistance = Vector3.Distance(Transform.position, agent.destination);
  12. return agent.pathPending || remainingDistance > agent.stoppingDistance || agent.velocity != Vector3.zero;
  13. }
  14. return false;
  15. }
  16. }


    /// 是否移动结束
    bool EventMoveEnd() {
        return state == "MOVING" && !IsMoving();

  }

 

绘制移动路线

  1. /// <summary>
  2. /// 绘制移动路线
  3. /// </summary>
  4. void OnDrawGizmos()
  5. {
  6.     var agent = GetComponent<UnityEngine.AI.NavMeshAgent>();
  7.     var path = agent.path;
  8.     Color c = Color.white;
  9.     switch (path.status)
  10. {
  11.         case UnityEngine.AI.NavMeshPathStatus.PathComplete: c = Color.white; break;
  12.         case UnityEngine.AI.NavMeshPathStatus.PathInvalid: c = Color.red; break;
  13.         case UnityEngine.AI.NavMeshPathStatus.PathPartial: c = Color.yellow; break;
  14.     }
  15.     for (int i = 1; i < path.corners.Length; ++i)
  16.         Debug.DrawLine(path.corners[i-1], path.corners[i], c);
  17. }

   

状态切换

            //取消移动
            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";  

  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.AI;
  4. using Debug = UnityEngine.Debug;
  5. public class MoveNavMeshAgent : MonoBehaviour
  6. {
  7. public NavMeshAgent agent;
  8. [SerializeField]
  9. bool _isMoveing = false;
  10. [SerializeField]
  11. float remainingDistance;
  12. [SerializeField]
  13. Vector3 curr_destination;
  14. [SerializeField]
  15. Vector3 last_destination;
  16. private Transform Transform;
  17. void Awake()
  18. {
  19. agent = gameObject.GetComponent<NavMeshAgent>();
  20. if(!agent)Debug.LogError(gameObject.name + " no NavMeshAgent compent");
  21. Transform = gameObject.transform;
  22. agent.updateRotation = true; //允许NavMesh来旋转角色
  23. agent.updatePosition = true; //允许NavMesh来移动角色
  24. agent.enabled = false;
  25. }
  26. /// <summary>
  27. ///使用了NavMeshAgent就不能用 transform.position = newPos;用 WarpPoint(newPos)代替或者移动赋值前先NavMeshAgent.enabled = false
  28. /// </summary>
  29. /// <param name="destination"></param>
  30. public void WarpPoint(Vector3 destination)
  31. {
  32. if (agent.enabled == false)
  33. {
  34. agent.enabled = true;
  35. }
  36. agent.Warp(destination);
  37. agent.enabled = false;
  38. }
  39. /// <summary>
  40. /// 是否在移动中
  41. /// </summary>
  42. /// <returns></returns>
  43. public bool IsMoving
  44. {
  45. get
  46. {
  47. if (agent != null && agent.enabled)
  48. {
  49. remainingDistance = Vector3.Distance(Transform.position, agent.destination);
  50. _isMoveing = agent.pathPending || remainingDistance > agent.stoppingDistance || agent.velocity != Vector3.zero;
  51. }
  52. else
  53. {
  54. _isMoveing = false;
  55. }
  56. return _isMoveing;
  57. }
  58. }
  59. /// <summary>
  60. /// 是否移动结束
  61. /// </summary>
  62. /// <returns></returns>
  63. public bool IsMoveEnd
  64. {
  65. get
  66. {
  67. return !IsMoving;
  68. }
  69. }
  70. //停止移动
  71. public void StopMove()
  72. {
  73. if (agent.enabled == true) //停止NavMeshAgent ,停止移动
  74. {
  75. agent.ResetPath();
  76. agent.Stop();
  77. agent.enabled = false;
  78. }
  79. }
  80. /// <summary>
  81. /// 移动到点
  82. /// </summary>
  83. public void MovePoint(Vector3 destination, float stoppingDistance = 0.17f)
  84. {
  85. curr_destination = destination;
  86. if (agent.enabled && curr_destination == last_destination && IsMoving && Math.Round(stoppingDistance, 2) == Math.Round(agent.stoppingDistance, 2))//与上一次目的地相同,就跳过
  87. {
  88. return;
  89. }
  90. if (agent.enabled == false)
  91. {
  92. agent.enabled = true;
  93. }
  94. agent.stoppingDistance = stoppingDistance;
  95. agent.destination = destination;
  96. last_destination = curr_destination;
  97. }
  98. /// <summary>
  99. /// 移动到距离敌人包围盒最近的点,如果是远程英雄的话 stoppingDistance 就是攻击距离,
  100. /// </summary>
  101. /// <param name="stoppingDistance"></param>
  102. /// <param name="enemyCollider"></param>
  103. public void MoveToEnemy(Collider enemyCollider, float stoppingDistance = 0.17f)
  104. {
  105. Vector3 destination = enemyCollider.ClosestPointOnBounds(Transform.position);
  106. MovePoint(destination, stoppingDistance);
  107. }
  108. /// <summary>
  109. /// 绘制移动路线
  110. /// </summary>
  111. void OnDrawGizmos()
  112. {
  113. if (agent != null && agent.enabled == true)
  114. {
  115. var path = agent.path;
  116. // color depends on status
  117. Color c = Color.white;
  118. switch (path.status)
  119. {
  120. case UnityEngine.AI.NavMeshPathStatus.PathComplete:
  121. c = Color.white;
  122. break;
  123. case UnityEngine.AI.NavMeshPathStatus.PathInvalid:
  124. c = Color.red;
  125. break;
  126. case UnityEngine.AI.NavMeshPathStatus.PathPartial:
  127. c = Color.yellow;
  128. break;
  129. }
  130. // draw the path
  131. for (int i = 1; i < path.corners.Length; ++i)
  132. Debug.DrawLine(path.corners[i - 1], path.corners[i], c);
  133. }
  134. }
  135. public void FixedUpdate()
  136. {
  137. #if UNITY_EDITOR
  138. var ShowState_Debug = IsMoving;
  139. #endif
  140. }
  141. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/390831
推荐阅读
相关标签
  

闽ICP备14008679号