2024-07-30 13:39:01 +08:00
|
|
|
/*
|
2024-08-10 02:25:46 +08:00
|
|
|
* author: ryan lin
|
2024-07-30 13:39:01 +08:00
|
|
|
* date: 30/7/2024
|
2024-08-10 02:25:46 +08:00
|
|
|
* description: 'standard' npc ai behaviour
|
2024-07-30 13:39:01 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
using System.Collections;
|
|
|
|
using UnityEngine;
|
|
|
|
using UnityEngine.AI;
|
2024-08-10 13:12:09 +08:00
|
|
|
using Random = System.Random;
|
2024-07-30 13:39:01 +08:00
|
|
|
|
2024-08-10 02:25:46 +08:00
|
|
|
/// <summary>
|
2024-08-11 05:40:22 +08:00
|
|
|
/// 'standard' npc ai behaviour
|
2024-08-10 02:25:46 +08:00
|
|
|
/// </summary>
|
2024-07-30 13:39:01 +08:00
|
|
|
public class AI : MonoBehaviour
|
|
|
|
{
|
2024-07-30 15:52:06 +08:00
|
|
|
/// <summary>
|
2024-08-05 17:56:43 +08:00
|
|
|
/// to save resources when referring to the speed of this AI if its human
|
2024-07-30 15:52:06 +08:00
|
|
|
/// </summary>
|
|
|
|
private static readonly int AnimatorSpeed = Animator.StringToHash("Speed");
|
2024-07-30 13:39:01 +08:00
|
|
|
|
2024-07-30 15:52:06 +08:00
|
|
|
/// <summary>
|
|
|
|
/// set the layers the AI can be on
|
|
|
|
/// </summary>
|
2024-07-30 13:39:01 +08:00
|
|
|
public LayerMask walkableLayers;
|
2024-07-30 15:52:06 +08:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// the destination coordinate of the AI
|
|
|
|
/// </summary>
|
|
|
|
public Vector3 destinationCoord;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// the range that the AI can set as their destination
|
|
|
|
/// </summary>
|
|
|
|
public int movingRange;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// the nav mash agent that is on this AI
|
|
|
|
/// </summary>
|
2024-07-30 13:39:01 +08:00
|
|
|
private NavMeshAgent _agent;
|
2024-07-30 15:52:06 +08:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// the animator that is attached to this AI if applicable
|
|
|
|
/// </summary>
|
2024-07-30 13:39:01 +08:00
|
|
|
private Animator _animator;
|
2024-07-30 15:52:06 +08:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// the current state that the AI is at this point in time
|
|
|
|
/// </summary>
|
2024-07-30 13:39:01 +08:00
|
|
|
private string _currentState;
|
|
|
|
|
2024-07-30 15:52:06 +08:00
|
|
|
/// <summary>
|
|
|
|
/// a bool to check if the destination point is set
|
|
|
|
/// </summary>
|
|
|
|
private bool _destinationPointSet;
|
2024-07-30 13:39:01 +08:00
|
|
|
|
2024-07-30 15:52:06 +08:00
|
|
|
/// <summary>
|
|
|
|
/// the state that the AI will be on the next update
|
|
|
|
/// </summary>
|
|
|
|
private string _nextState;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// to set initial values
|
|
|
|
/// </summary>
|
2024-07-30 13:39:01 +08:00
|
|
|
public void Awake()
|
|
|
|
{
|
2024-08-05 17:56:43 +08:00
|
|
|
_animator = GetComponent<Animator>();
|
|
|
|
_currentState = "Strolling";
|
|
|
|
|
|
|
|
|
2024-07-30 13:39:01 +08:00
|
|
|
_agent = GetComponent<NavMeshAgent>();
|
2024-08-05 17:56:43 +08:00
|
|
|
_animator = GetComponent<Animator>();
|
|
|
|
_currentState = "Strolling";
|
|
|
|
|
2024-07-30 15:52:06 +08:00
|
|
|
|
|
|
|
_nextState = _currentState;
|
|
|
|
ChangeState();
|
2024-07-30 13:39:01 +08:00
|
|
|
}
|
|
|
|
|
2024-07-30 15:52:06 +08:00
|
|
|
/// <summary>
|
2024-08-05 17:56:43 +08:00
|
|
|
/// to update the speed of the AI to the animator each frame and to update any state changes to the AI
|
2024-07-30 15:52:06 +08:00
|
|
|
/// </summary>
|
2024-07-30 13:39:01 +08:00
|
|
|
public void Update()
|
|
|
|
{
|
2024-08-05 17:56:43 +08:00
|
|
|
_animator.SetFloat(AnimatorSpeed, _agent.velocity.magnitude);
|
2024-07-30 15:52:06 +08:00
|
|
|
_currentState = _nextState;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// to change the scene when needed
|
|
|
|
/// </summary>
|
2024-08-05 17:56:43 +08:00
|
|
|
private void ChangeState()
|
2024-07-30 15:52:06 +08:00
|
|
|
{
|
|
|
|
StartCoroutine(_currentState);
|
2024-07-30 13:39:01 +08:00
|
|
|
}
|
|
|
|
|
2024-07-30 15:52:06 +08:00
|
|
|
/// <summary>
|
|
|
|
/// to set a random x and y coordinate for the AI to go to
|
|
|
|
/// </summary>
|
2024-07-30 13:39:01 +08:00
|
|
|
private void SearchWalkPoint()
|
|
|
|
{
|
2024-08-10 13:12:09 +08:00
|
|
|
var rand = new Random();
|
2024-07-30 15:52:06 +08:00
|
|
|
float randomX = rand.Next(-movingRange * 100, movingRange * 100);
|
|
|
|
float randomZ = rand.Next(-movingRange * 100, movingRange * 100);
|
|
|
|
destinationCoord = new Vector3(
|
|
|
|
transform.position.x + randomX / 100,
|
2024-07-30 13:39:01 +08:00
|
|
|
transform.position.y,
|
2024-07-30 15:52:06 +08:00
|
|
|
transform.position.z + randomZ / 100
|
2024-07-30 13:39:01 +08:00
|
|
|
);
|
2024-07-30 15:52:06 +08:00
|
|
|
if (Physics.Raycast(destinationCoord, -transform.up, 2f, walkableLayers)) _destinationPointSet = true;
|
2024-07-30 13:39:01 +08:00
|
|
|
}
|
|
|
|
|
2024-07-30 15:52:06 +08:00
|
|
|
/// <summary>
|
|
|
|
/// a state that the AI wonders around using the SearchWalkPoint function to find a location for the AI to go to
|
|
|
|
/// </summary>
|
|
|
|
private IEnumerator Strolling()
|
2024-07-30 13:39:01 +08:00
|
|
|
{
|
|
|
|
SearchWalkPoint();
|
2024-07-30 15:52:06 +08:00
|
|
|
|
2024-07-30 13:39:01 +08:00
|
|
|
while (_currentState == "Strolling")
|
|
|
|
{
|
2024-07-30 15:52:06 +08:00
|
|
|
if (!_destinationPointSet)
|
2024-07-30 13:39:01 +08:00
|
|
|
SearchWalkPoint();
|
|
|
|
else
|
2024-07-30 15:52:06 +08:00
|
|
|
_agent.SetDestination(destinationCoord);
|
2024-07-30 13:39:01 +08:00
|
|
|
|
2024-07-30 15:52:06 +08:00
|
|
|
if ((transform.position - destinationCoord).magnitude < 1f) _destinationPointSet = false;
|
2024-07-30 13:39:01 +08:00
|
|
|
|
2024-07-30 15:52:06 +08:00
|
|
|
yield return new WaitForSeconds(1f);
|
2024-07-30 13:39:01 +08:00
|
|
|
}
|
2024-07-30 15:52:06 +08:00
|
|
|
|
|
|
|
ChangeState();
|
2024-07-30 13:39:01 +08:00
|
|
|
}
|
2024-08-07 14:55:21 +08:00
|
|
|
}
|