Unity NavMesh Agent未移动。

huangapple go评论192阅读模式
英文:

Unity NavMesh Agent Not Moving

问题

以下是代码的中文翻译部分:

  1. // EnemyLocomotionManager.cs
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEngine.AI;
  6. public class EnemyLocomotionManager : MonoBehaviour
  7. {
  8. private BoxCollider boxCollider;
  9. private Rigidbody[] RDrigidbodies;
  10. private Collider[] colliders;
  11. public float moveSpeed = 10f;
  12. public Rigidbody enemyRb;
  13. NavMeshAgent navMeshAgent;
  14. EnemyAnimatorManager enemyAnimatorManager;
  15. EnemyManager enemyManager;
  16. public CharacterStats currentTarget;
  17. [SerializeField] LayerMask detectionLayer;
  18. public float rotationSpeed = 25;
  19. public float distanceFromTarget;
  20. public float stoppingDistance = 0.5f;
  21. private void Awake()
  22. {
  23. RDrigidbodies = GetComponentsInChildren<Rigidbody>();
  24. colliders = GetComponentsInChildren<Collider>();
  25. boxCollider = GetComponent<BoxCollider>();
  26. enemyRb = GetComponent<Rigidbody>();
  27. enemyManager = GetComponent<EnemyManager>();
  28. enemyAnimatorManager = GetComponent<EnemyAnimatorManager>();
  29. navMeshAgent = GetComponentInChildren<NavMeshAgent>();
  30. // 禁用Ragdoll
  31. SetCollidersEnabled(false);
  32. SetRigidBodiesKinematic(false);
  33. boxCollider.enabled = true;
  34. }
  35. private void Start()
  36. {
  37. navMeshAgent.enabled = false;
  38. enemyRb.isKinematic = false;
  39. }
  40. public void HandleDetection()
  41. {
  42. Collider[] colliders = Physics.OverlapSphere(transform.position, enemyManager.detectionRadius, detectionLayer);
  43. for (int i = 0; i < colliders.Length; i++)
  44. {
  45. CharacterStats characterStats = colliders[i].transform.GetComponent<CharacterStats>();
  46. if (characterStats != null)
  47. {
  48. Debug.Log("已检测到目标");
  49. // 检查团队ID
  50. // 指向具有该脚本的对象的方向
  51. Vector3 targetDirection = characterStats.transform.position - transform.position;
  52. // 返回当前方向与目标方向之间的角度
  53. float viewableAngle = Vector3.Angle(targetDirection, transform.forward);
  54. // 检查是否在视野范围内
  55. // if (viewableAngle > enemyManager.minimumDetectionAngle && viewableAngle < enemyManager.maximumDetectionAngle)
  56. // {
  57. currentTarget = characterStats;
  58. // }
  59. }
  60. }
  61. }
  62. public void HandleMoveToTarget()
  63. {
  64. Debug.Log("处理移动到目标"); // 添加日志以指示正在执行此函数
  65. Vector3 targetDirection = currentTarget.transform.position - transform.position;
  66. float viewableAngle = Vector3.Angle(targetDirection, transform.forward);
  67. distanceFromTarget = Vector3.Distance(currentTarget.transform.position, transform.position);
  68. // 记录值以查看发生了什么
  69. Debug.Log($"可见角度:{viewableAngle},距离目标:{distanceFromTarget}");
  70. if (enemyManager.isPerformingAction)
  71. {
  72. Debug.Log("正在执行动作,停止移动");
  73. enemyAnimatorManager.anim.SetFloat("Vertical", 0, 0.1f, Time.deltaTime);
  74. navMeshAgent.enabled = false;
  75. }
  76. else
  77. {
  78. if (distanceFromTarget > stoppingDistance)
  79. {
  80. Debug.Log("朝向目标移动");
  81. enemyAnimatorManager.anim.SetFloat("Vertical", 1, 0.1f, Time.deltaTime);
  82. }
  83. else if (distanceFromTarget <= stoppingDistance)
  84. {
  85. Debug.Log("已达到停止距离");
  86. enemyAnimatorManager.anim.SetFloat("Vertical", 0, 0.1f, Time.deltaTime);
  87. }
  88. }
  89. HandleRotateToTarget(); // 在HandleRotateToTarget内添加一个日志以检查是否正在执行
  90. navMeshAgent.transform.localPosition = Vector3.zero;
  91. navMeshAgent.transform.localRotation = Quaternion.identity;
  92. }
  93. private void HandleRotateToTarget()
  94. {
  95. // 手动旋转
  96. if (enemyManager.isPerformingAction)
  97. {
  98. Vector3 direction = currentTarget.transform.position - transform.position;
  99. direction.y = 0;
  100. direction.Normalize();
  101. if (direction == Vector3.zero)
  102. {
  103. direction = transform.forward;
  104. }
  105. Quaternion targetRotation = Quaternion.LookRotation(direction);
  106. transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed / Time.deltaTime);
  107. }
  108. // 使用路径查找旋转
  109. else
  110. {
  111. // 此功能
  112. // 导航网格代理
  113. Vector3 relativeDirection = transform.InverseTransformDirection(navMeshAgent.desiredVelocity);
  114. Vector3 targetVelocity = enemyRb.velocity;
  115. navMeshAgent.enabled = true;
  116. navMeshAgent.SetDestination(currentTarget.transform.position);
  117. Debug.Log("设置目标位置");
  118. enemyRb.velocity = targetVelocity;
  119. transform.rotation = Quaternion.Slerp(transform.rotation, navMeshAgent.transform.rotation, rotationSpeed / Time.deltaTime);
  120. }
  121. }
  122. private void SetCollidersEnabled(bool enabled)
  123. {
  124. foreach (Collider col in colliders)
  125. {
  126. col.enabled = enabled;
  127. }
  128. }
  129. private void SetRigidBodiesKinematic(bool kinematic)
  130. {
  131. foreach (Rigidbody rb in RDrigidbodies)
  132. {
  133. rb.isKinematic = kinematic;
  134. }
  135. }
  136. private void ActivateRagdoll()
  137. {
  138. boxCollider.enabled = false;
  139. enemyRb.isKinematic = true;
  140. enemyAnimatorManager.anim.enabled = false;
  141. SetCollidersEnabled(true);
  142. SetRigidBodiesKinematic(false);
  143. }
  144. }
  1. // EnemyManager.cs
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. public class EnemyManager : MonoBehaviour
  6. {
  7. EnemyLocomotionManager enemyLocomotionManager;
  8. public bool isPerformingAction;
  9. public float detectionRadius = 20;
  10. public float maximumDetectionAngle = 50;
  11. public float minimumDetectionAngle = -50;
  12. void Awake()
  13. {
  14. enemyLocomotionManager = GetComponent<EnemyLocomotionManager>();
  15. }
  16. private void FixedUpdate()
  17. {
  18. HandleCurrentAction();
  19. }
  20. void HandleCurrentAction()
  21. {
  22. if (enemyLocomotionManager.currentTarget == null)
  23. {
  24. enemyLocomotionManager.HandleDetection();
  25. }
  26. else
  27. {
  28. enemyLocomotionManager.HandleMoveToTarget();
  29. }
  30. }
  31. }
  1. // EnemyAnimatorManager.cs
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. public class EnemyAnimatorManager : AnimatorManager
  6. {
  7. EnemyLocomotionManager enemyLocomotionManager;
  8. private void Awake()
  9. {
  10. enemyLocomotionManager = GetComponentInParent<EnemyLocomotionManager>();
  11. anim = GetComponent<Animator>();
  12. }
  13. void OnAnimatorMove()
  14. {
  15. float delta = Time.deltaTime;
  16. enemyLocomotionManager.enemyRb.drag = 0;
  17. Vector3 deltaPosition = anim.deltaPosition;
  18. deltaPosition.y = 0;
  19. Vector3 velocity = deltaPosition / delta;
  20. enemyLocomotionManager.enemyRb.velocity = velocity;
  21. <details>
  22. <summary>英文:</summary>
  23. Currently, I am trying to set up a simple script where an enemy will move towards and rotate towards the player. The rotation &amp; running animations play just fine, but the enemy that is supposed to move is stuck in place.
  24. I have tried Debugging it with logs as well as baking the navmesh, the issue could have somthing to do with velocity but I&#39;m just not sure. Thanks for reading this.
  25. Here is the Code as well as the inspector:
  26. [
  27. image](https://i.stack.imgur.com/EIZp3.png)

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

public class EnemyLocomotionManager : MonoBehaviour
{
private BoxCollider boxCollider;
private Rigidbody[] RDrigidbodies;
private Collider[] colliders;

  1. public float moveSpeed = 10f;

public Rigidbody enemyRb;
NavMeshAgent navMeshAgent;
EnemyAnimatorManager enemyAnimatorManager;
EnemyManager enemyManager;
public CharacterStats currentTarget;
[SerializeField] LayerMask detectionLayer;

  1. public float rotationSpeed = 25;
  2. public float distanceFromTarget;
  3. public float stoppingDistance = 0.5f;
  4. private void Awake()
  5. {
  6. RDrigidbodies = GetComponentsInChildren&lt;Rigidbody&gt;();
  7. colliders = GetComponentsInChildren&lt;Collider&gt;();
  8. boxCollider= GetComponent&lt;BoxCollider&gt;();
  9. enemyRb = GetComponent&lt;Rigidbody&gt;();
  10. enemyManager = GetComponent&lt;EnemyManager&gt;();
  11. enemyAnimatorManager= GetComponent&lt;EnemyAnimatorManager&gt;();
  12. navMeshAgent = GetComponentInChildren&lt;NavMeshAgent&gt;();
  13. //DisableRagdoll
  14. SetCollidersEnabled(false);
  15. SetRigidBodiesKinematic(false);
  16. boxCollider.enabled = true ;
  17. }
  18. private void Start()
  19. {
  20. navMeshAgent.enabled = false;
  21. enemyRb.isKinematic= false;
  22. }
  23. public void HandleDetection()
  24. {
  25. Collider[] colliders = Physics.OverlapSphere(transform.position, enemyManager.detectionRadius, detectionLayer);
  26. for (int i = 0; i &lt; colliders.Length; i++)
  27. {
  28. CharacterStats characterStats = colliders[i].transform.GetComponent&lt;CharacterStats&gt;();
  29. if(characterStats != null )
  30. {
  31. Debug.Log(&quot;HaSDetectedDertc&quot;);
  32. //Check for team ID
  33. //Direction towards the object that has that script
  34. Vector3 targetDirection = characterStats.transform.position - transform.position;
  35. //returns the angle between current direction &amp; target direction
  36. float viewableAngle = Vector3.Angle(targetDirection, transform.forward);
  37. //check if its in our FOV
  38. // if( viewableAngle &gt; enemyManager.minimumDetectionAngle &amp;&amp; viewableAngle&lt; enemyManager.maximumDetectionAngle)
  39. // {
  40. currentTarget = characterStats;
  41. // }
  42. }
  43. }
  44. }
  45. public void HandleMoveToTarget()
  46. {
  47. Debug.Log(&quot;Handling Move To Target&quot;); // Add a log to indicate this function is being executed
  48. Vector3 targetDirection = currentTarget.transform.position - transform.position;
  49. float viewableAngle = Vector3.Angle(targetDirection, transform.forward);
  50. distanceFromTarget = Vector3.Distance(currentTarget.transform.position, transform.position);
  51. // Log values to see what&#39;s happening
  52. Debug.Log($&quot;Viewable Angle: {viewableAngle}, Distance From Target: {distanceFromTarget}&quot;);
  53. if (enemyManager.isPerformingAction)
  54. {
  55. Debug.Log(&quot;Performing Action, Stopping Movement&quot;);
  56. enemyAnimatorManager.anim.SetFloat(&quot;Vertical&quot;, 0, 0.1f, Time.deltaTime);
  57. navMeshAgent.enabled = false;
  58. }
  59. else
  60. {
  61. if (distanceFromTarget &gt; stoppingDistance)
  62. {
  63. Debug.Log(&quot;Moving Towards Target&quot;);
  64. enemyAnimatorManager.anim.SetFloat(&quot;Vertical&quot;, 1, 0.1f, Time.deltaTime);
  65. }
  66. else if (distanceFromTarget &lt;= stoppingDistance)
  67. {
  68. Debug.Log(&quot;Reached Stopping Distance&quot;);
  69. enemyAnimatorManager.anim.SetFloat(&quot;Vertical&quot;, 0, 0.1f, Time.deltaTime);
  70. }
  71. }
  72. HandleRotateToTarget(); // Add a log inside HandleRotateToTarget to check if it&#39;s being executed
  73. navMeshAgent.transform.localPosition = Vector3.zero;
  74. navMeshAgent.transform.localRotation = Quaternion.identity;
  75. }
  76. private void HandleRotateToTarget()
  77. {
  78. //Rotate manually
  79. if(enemyManager.isPerformingAction)
  80. {
  81. Vector3 direction = currentTarget.transform.position - transform.position;
  82. direction.y = 0;
  83. direction.Normalize();
  84. if(direction == Vector3.zero)
  85. {
  86. direction = transform.forward;
  87. }
  88. Quaternion targetRotation = Quaternion.LookRotation(direction);
  89. transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed/Time.deltaTime);
  90. }
  91. //rotate with pathfinding
  92. else
  93. {
  94. //this function
  95. //navmesh agents
  96. Vector3 relativeDirection = transform.InverseTransformDirection(navMeshAgent.desiredVelocity);
  97. Vector3 targetVelocity = enemyRb.velocity;
  98. navMeshAgent.enabled = true;
  99. navMeshAgent.SetDestination(currentTarget.transform.position);
  100. Debug.Log(&quot;Set Destination&quot;);
  101. enemyRb.velocity = targetVelocity;
  102. transform.rotation = Quaternion.Slerp(transform.rotation, navMeshAgent.transform.rotation, rotationSpeed / Time.deltaTime);
  103. }
  104. }
  105. private void SetCollidersEnabled(bool enabled)
  106. {
  107. foreach(Collider col in colliders)
  108. {
  109. col.enabled = enabled;
  110. }
  111. }
  112. private void SetRigidBodiesKinematic(bool kinematic)
  113. {
  114. foreach(Rigidbody rb in RDrigidbodies)
  115. {
  116. rb.isKinematic= kinematic;
  117. }
  118. }
  119. private void ActivateRagdoll()
  120. {
  121. boxCollider.enabled = false;
  122. enemyRb.isKinematic = true;
  123. enemyAnimatorManager.anim.enabled = false;
  124. SetCollidersEnabled(true);
  125. SetRigidBodiesKinematic(false);
  126. }

}

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

public class EnemyManager : MonoBehaviour
{
EnemyLocomotionManager enemyLocomotionManager;
public bool isPerformingAction;
public float detectionRadius = 20;
public float maximumDetectionAngle = 50;
public float minimumDetectionAngle = -50;

  1. // Start is called before the first frame update
  2. void Awake()
  3. {
  4. enemyLocomotionManager= GetComponent&lt;EnemyLocomotionManager&gt;();
  5. }
  6. private void FixedUpdate()
  7. {
  8. HandleCurrentAction();
  9. }
  10. // Update is called once per frame
  11. void HandleCurrentAction()
  12. {
  13. if (enemyLocomotionManager.currentTarget == null)
  14. {
  15. enemyLocomotionManager.HandleDetection();
  16. }
  17. else
  18. {
  19. enemyLocomotionManager.HandleMoveToTarget();
  20. }
  21. }

}

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

public class EnemyAnimatorManager : AnimatorManager
{
EnemyLocomotionManager enemyLocomotionManager;
private void Awake()
{
enemyLocomotionManager = GetComponentInParent<EnemyLocomotionManager>();
anim= GetComponent<Animator>();
}
void OnAnimatorMove()
{
float delta = Time.deltaTime;
enemyLocomotionManager.enemyRb.drag = 0;
Vector3 deltaPosition = anim.deltaPosition;
deltaPosition.y = 0;
Vector3 velocity = deltaPosition / delta;
enemyLocomotionManager.enemyRb.velocity = velocity;
}
}

  1. </details>
  2. # 答案1
  3. **得分**: 0
  4. 记住,在 OnAnimatorMove() 正常工作的前提下,Unity 编辑器中的 Animator 组件的 Apply Root Motion 复选框应该被勾选。
  5. <details>
  6. <summary>英文:</summary>
  7. Remember that for the OnAnimatorMove() to work correctly, the Animator component&#39;s Apply Root Motion checkbox should be checked in the Unity editor.
  8. </details>

huangapple
  • 本文由 发表于 2023年8月11日 03:29:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76878794.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定