/* * author: lin hengrui ryan * date: 30/7/2024 * description: ai code for the different ai in the game */ using System.Collections; using UnityEngine; using UnityEngine.AI; using Random = System.Random; public class AI : MonoBehaviour { /// /// the types of ai that this game object can be /// public enum EntityType { Human, Car } /// /// to save resources when referring to the speed of this ai if its a human /// private static readonly int AnimatorSpeed = Animator.StringToHash("Speed"); /// /// to show the entity types in the inspector as a dropdown /// public EntityType entityType; /// /// set the layers the AI can be on /// public LayerMask walkableLayers; /// /// the destination coordinate of the AI /// public Vector3 destinationCoord; /// /// the range that the AI can set as their destination /// public int movingRange; /// /// the nav mash agent that is on this AI /// private NavMeshAgent _agent; /// /// the animator that is attached to this AI if applicable /// private Animator _animator; /// /// the current state that the AI is at this point in time /// private string _currentState; /// /// a bool to check if the destination point is set /// private bool _destinationPointSet; /// /// the state that the AI will be on the next update /// private string _nextState; /// /// to set initial values /// public void Awake() { _agent = GetComponent(); if (entityType == EntityType.Human) { _animator = GetComponent(); _currentState = "Strolling"; } _nextState = _currentState; ChangeState(); } /// /// to update the speed of the AI to the animator each frame and to update any state changes to the ai /// public void Update() { if (entityType == EntityType.Human) _animator.SetFloat(AnimatorSpeed, _agent.velocity.magnitude); _currentState = _nextState; } /// /// to change the scene when needed /// public void ChangeState() { StartCoroutine(_currentState); } /// /// to set a random x and y coordinate for the AI to go to /// private void SearchWalkPoint() { var rand = new Random(); float randomX = rand.Next(-movingRange * 100, movingRange * 100); float randomZ = rand.Next(-movingRange * 100, movingRange * 100); destinationCoord = new Vector3( transform.position.x + randomX / 100, transform.position.y, transform.position.z + randomZ / 100 ); if (Physics.Raycast(destinationCoord, -transform.up, 2f, walkableLayers)) _destinationPointSet = true; } /// /// a state that the AI wonders around using the SearchWalkPoint function to find a location for the AI to go to /// private IEnumerator Strolling() { SearchWalkPoint(); while (_currentState == "Strolling") { Debug.Log("strolling"); if (!_destinationPointSet) SearchWalkPoint(); else _agent.SetDestination(destinationCoord); if ((transform.position - destinationCoord).magnitude < 1f) _destinationPointSet = false; yield return new WaitForSeconds(1f); } ChangeState(); } }