123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.AI;
- [DefaultExecutionOrder(10)]
- [RequireComponent(typeof(InstantiatePrefab))]
- public class WanderingAI : MonoBehaviour
- {
- [Header("Only for Debugging (do not set from here)")]
- public Transform[] waypoints;
- public List<Transform> waypointsList;
- public float[] wanderTimer;
- public List<float>[] waitingTimer;
- [Header("Scattering around the target")]
- public float targetScattering = 5.0f; //Streuung
- [Header("Leave Settings")]
- public float leaveTimer = 120f;
- public Vector3 leavePosition;
- // Leave Settings
- private float offsetx = 0;
- private float offsetz = 0;
- private int inRow = 4; // incl 0 - 4
- private float[] timer;
- private float globalTimer;
- private Vector3[][] target;
- private int[][] humansPrio;
- private GameObject[][] humansGO;
- private NavMeshAgent[][] humansNMA;
- private Animator[][] humansA;
- private const string isWalking = "isWalking";
- // Use this for initialization
- void Start()
- {
- // Get initialized Variables from InstantiatePrefab
- humansGO = gameObject.GetComponent<InstantiatePrefab>().humanGameObject;
- humansNMA = gameObject.GetComponent<InstantiatePrefab>().humanNavMeshAgent;
- humansA = gameObject.GetComponent<InstantiatePrefab>().humanAnimator;
- wanderTimer = gameObject.GetComponent<InstantiatePrefab>().wanderTimer;
- waitingTimer = gameObject.GetComponent<InstantiatePrefab>().waitingTimer;
- waypoints = gameObject.GetComponent<InstantiatePrefab>().waypointsArray;
- waypointsList = new List<Transform>(waypoints);
- humansPrio = gameObject.GetComponent<InstantiatePrefab>().humanPriorities;
- // Set length of variables to humanGo.Length
- target = new Vector3[humansGO.Length][];
- timer = new float[humansGO.Length];
- // Initialize size and content
- for(int i = 0; i < humansGO.Length; i++)
- {
- target[i] = new Vector3[humansGO[i].Length];
- for(int j = 0; j < humansGO[i].Length; j++)
- {
- timer[i] = wanderTimer[i];
- }
- }
- globalTimer = 0;
- }
- //private void FixedUpdate()
- //{
- // for(int i = 0; i < humansGO.Length; ++i)
- // {
- // if (timer[i] >= wanderTimer[i])
- // {
- // if (waypoints.Length == 0) return;
- // int currentWP = Random.Range(0, waypointsList.Count);
- // target[i][0] = CheckTarget(waypointsList[currentWP].transform.position, targetScattering);
- // if(target[i][0].x != float.PositiveInfinity)
- // {
- // for (int j = 0; j < humansGO[i].Length; ++j)
- // {
- // target[i][j] = target[i][0];
- // if (humansNMA[i][j].isActiveAndEnabled)
- // humansNMA[i][j].SetDestination(target[i][j]);
- // humansA[i][j].SetBool(isWalking, humansNMA[i][j].velocity.magnitude > 0.01f);
- // }
- // timer[i] = 0;
- // // remove from list to ensure that all WP are visited at the frequency indicated; if list empty fill list with initial WPs
- // ReduceWaypoints(currentWP);
- // }
- // }
- // else
- // {
- // for (int j = 0; j < humansGO[i].Length; ++j)
- // {
- // humansA[i][j].SetBool(isWalking, humansNMA[i][j].velocity.magnitude > 0.01f);
- // // if humans are not walking, then set priority to 0 so that the other humans dont disturb them
- // if(humansNMA[i][j].velocity.magnitude <= 0.01f)
- // humansNMA[i][j].avoidancePriority = 0;
- // else
- // humansNMA[i][j].avoidancePriority = humansPrio[i][j];
- // }
- // }
- // timer[i] += Time.deltaTime;
- // }
- //}
- private void FixedUpdate()
- {
- for (int i = 0; i < humansGO.Length; ++i)
- {
- if (waypoints.Length == 0) return;
-
- for(int j = 0; j < humansGO[i].Length; ++j)
- {
- if(target[i][j] == Vector3.zero ||
- humansNMA[i][j].velocity.magnitude <= 0.01f ||
- humansNMA[i][j].remainingDistance <= humansNMA[i][j].stoppingDistance ||
- humansNMA[i][j].pathStatus == NavMeshPathStatus.PathComplete ||
- !humansNMA[i][j].hasPath)
- {
- int currentWP = Random.Range(0, waypointsList.Count);
- target[i][j] = CheckTarget(waypointsList[currentWP].transform.position, targetScattering);
- if (target[i][0].x != float.PositiveInfinity)
- {
- if (humansNMA[i][j].isActiveAndEnabled)
- humansNMA[i][j].SetDestination(target[i][j]);
- humansA[i][j].SetBool(isWalking, humansNMA[i][j].velocity.magnitude > 0.01f);
- }
- // remove from list to ensure that all WP are visited at the frequency indicated; if list empty fill list with initial WPs
- ReduceWaypoints(currentWP);
- }
- else
- {
- humansA[i][j].SetBool(isWalking, humansNMA[i][j].velocity.magnitude > 0.01f);
- // if humans are not walking, then set priority to 0 so that the other humans dont disturb them
- if (humansNMA[i][j].velocity.magnitude <= 0.01f)
- humansNMA[i][j].avoidancePriority = 0;
- else
- humansNMA[i][j].avoidancePriority = humansPrio[i][j];
- }
- }
- timer[i] += Time.deltaTime;
- }
- }
- public static Vector3 CheckTarget(Vector3 target, float dist)
- {
- Vector3 modifiedTarget = Random.insideUnitSphere * dist + target;
- // SamplePosition also checks the y axis. However, this is not relevant for me, so valid positions (x & z) are also discarded.
- // 0.0f is the only valid entry for y
- modifiedTarget = new Vector3(modifiedTarget.x, 0f, modifiedTarget.z);
-
- NavMeshHit navHit;
- NavMesh.SamplePosition(modifiedTarget, out navHit, 1.0f, -1);
- return navHit.position;
- }
- public void ReduceWaypoints(int index)
- {
- waypointsList.RemoveAt(index);
- if(waypointsList.Count <= 0)
- waypointsList = new List<Transform>(waypoints);
- }
- public void LeaveMarket(int i)
- {
- for (int j = 0; j < humansGO[i].Length; ++j)
- {
- target[i][j] = new Vector3(leavePosition.x + offsetx, 0, leavePosition.z + offsetz);
- // Calculate offset
- if (offsetz < inRow * 2)
- offsetz += 2;
- else
- {
- offsetz = 0;
- offsetx += 2;
- }
- }
- }
- private void LateUpdate()
- {
- for (int i = 0; i < humansGO.Length; ++i)
- {
- for (int j = 0; j < humansGO[i].Length; ++j)
- {
- humansA[i][j].speed = 0.5f + (humansNMA[i][j].velocity.magnitude / gameObject.GetComponent<InstantiatePrefab>().speedMinMax.y);
- }
- }
- }
- }
|