WanderingAITest.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. using UnityEngine;
  2. using UnityEngine.AI;
  3. public class WanderingAITest : MonoBehaviour
  4. {
  5. public Transform[] waypoints;
  6. public float[] wanderTimer;
  7. public float targetScattering = 5.0f; //Streuung
  8. private float[] timer;
  9. private int[] prevWP;
  10. private Vector3[][] target;
  11. private GameObject[][] humansGO;
  12. private NavMeshAgent[][] humansNMA;
  13. private Animator[][] humansA;
  14. // Use this for initialization
  15. void Start()
  16. {
  17. humansGO = gameObject.GetComponent<InstantiatePrefab>().humanObjs;
  18. humansNMA = new NavMeshAgent[humansGO.Length][];
  19. humansA = new Animator[humansGO.Length][];
  20. target = new Vector3[humansGO.Length][];
  21. timer = new float[humansGO.Length];
  22. wanderTimer = gameObject.GetComponent<InstantiatePrefab>().wanderTimer;
  23. prevWP = new int[humansGO.Length];
  24. // waypoints are set in InstantiatePrefab
  25. for(int i = 0; i < humansGO.Length; i++)
  26. {
  27. humansNMA[i] = new NavMeshAgent[humansGO[i].Length];
  28. humansA[i] = new Animator[humansGO[i].Length];
  29. target[i] = new Vector3[humansGO[i].Length];
  30. prevWP[i] = -1;
  31. for(int j = 0; j < humansGO[i].Length; j++)
  32. {
  33. humansNMA[i][j] = humansGO[i][j].GetComponent<NavMeshAgent>();
  34. humansA[i][j] = humansGO[i][j].GetComponent<Animator>();
  35. humansA[i][j].SetBool("isWalking", false);
  36. humansA[i][j].SetBool("isIdle", true);
  37. timer[i] = wanderTimer[i];
  38. }
  39. }
  40. }
  41. private void FixedUpdate()
  42. {
  43. for(int i = 0; i < humansGO.Length; i++)
  44. {
  45. timer[i] += Time.deltaTime;
  46. if (timer[i] >= wanderTimer[i])
  47. {
  48. if (waypoints.Length == 0) return;
  49. int currentWP = Random.Range(0, waypoints.Length);
  50. // Until previous and current WP are no longer the same, otherwise double waiting time for same WP
  51. while(prevWP[i] == currentWP)
  52. currentWP = Random.Range(0, waypoints.Length);
  53. prevWP[i] = currentWP;
  54. target[i][0] = checkTarget(waypoints[currentWP].transform.position, targetScattering);
  55. if(target[i][0].x != float.PositiveInfinity)
  56. {
  57. for (int j = 0; j < humansGO[i].Length; j++)
  58. {
  59. target[i][j] = target[i][0];
  60. if (humansNMA[i][j].isActiveAndEnabled)
  61. humansNMA[i][j].SetDestination(target[i][j]);
  62. humansA[i][j].SetBool("isWalking", true);
  63. humansA[i][j].SetBool("isIdle", false);
  64. }
  65. timer[i] = 0;
  66. }
  67. else
  68. {
  69. timer[i] = wanderTimer[i];
  70. }
  71. }
  72. else
  73. {
  74. for (int j = 0; j < humansGO[i].Length; j++)
  75. {
  76. if (humansNMA[i][j].remainingDistance < humansNMA[i][j].stoppingDistance)
  77. {
  78. humansA[i][j].SetBool("isWalking", false);
  79. humansA[i][j].SetBool("isIdle", true);
  80. }
  81. else
  82. {
  83. humansA[i][j].SetBool("isWalking", true);
  84. humansA[i][j].SetBool("isIdle", false);
  85. }
  86. }
  87. }
  88. }
  89. }
  90. public static Vector3 checkTarget(Vector3 target, float dist)
  91. {
  92. Vector3 modifiedTarget = Random.insideUnitSphere * dist + target;
  93. // SamplePosition also checks the y axis. However, this is not relevant for me, so valid positions (x & z) are also discarded.
  94. // -3.6f is the only valid entry for y
  95. modifiedTarget = new Vector3(modifiedTarget.x, -3.6f, modifiedTarget.z);
  96. NavMeshHit navHit;
  97. NavMesh.SamplePosition(modifiedTarget, out navHit, 1.0f, -1);
  98. return navHit.position;
  99. }
  100. }