Untitled
unknown
csharp
9 months ago
5.3 kB
9
Indexable
using System.Runtime.CompilerServices;
using NUnit.Framework;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.TestTools;
public class AIBehaviour : MonoBehaviour
{
private NavMeshAgent agent;
public Transform target;
public Transform[] patrolPoints;
public Transform[] coverPoints;
private int currentPatrolIndex = 0;
public float patrolWaitTime = 1f;
private bool IsPatrolling = false;
public float chaseRange = 10f;
public float sightRange = 45f;
public float stalkRange = 45f;
public Transform playerCamera;
private delegate void State();
private float FieldOfView = 45f;
private bool IsConcealed = false;
private enum AIState { Patrolling, Chasing, Stalking }
private AIState currentState;
private float distanceToPlayer;
void Start()
{
agent = GetComponent<NavMeshAgent>();
currentState = AIState.Patrolling;
MoveToNextPatrolPoint();
}
void Update()
{
distanceToPlayer = Vector3.Distance(transform.position, target.position);
switch (currentState)
{
case AIState.Patrolling:
PatrolState();
break;
case AIState.Chasing:
ChaseState();
break;
case AIState.Stalking:
if (distanceToPlayer <= stalkRange)
{
Debug.Log("Stalking...");
}
else
{
PatrolState();
}
StalkState();
break;
}
if (currentState == AIState.Stalking)
{
CheckIfSeen();
}
CheckStateTransitions();
}
private void PatrolState()
{
if (!agent.pathPending && agent.remainingDistance < 0.5f)
{
StartCoroutine(PatrolWait());
}
}
private System.Collections.IEnumerator PatrolWait()
{
IsPatrolling = false;
yield return new WaitForSeconds(patrolWaitTime);
MoveToNextPatrolPoint();
IsPatrolling = true;
}
private void MoveToNextPatrolPoint()
{
if (patrolPoints.Length == 0)
{
Debug.Log("No Patrol Points Detected, standing still...");
return;
}
agent.SetDestination(patrolPoints[currentPatrolIndex].position);
currentPatrolIndex = (currentPatrolIndex + 1) %patrolPoints.Length;
}
private void StalkState()
{
if (CanSeePlayer())
{
Vector3 coverPoint = FindNearestCover();
MoveToCover(coverPoint);
}
else
{
if (!IsConcealed)
{
IsConcealed = true;
Vector3 coverPoint = FindNearestCover();
MoveToCover(coverPoint);
}
}
}
private bool CanSeePlayer()
{
Vector3 directionToPlayer = target.position - transform.position;
float angle = Vector3.Angle(transform.forward, directionToPlayer);
if (angle < FieldOfView)
{
RaycastHit hit;
if (Physics.Raycast(transform.position, directionToPlayer.normalized, out hit))
{
if (hit.collider.CompareTag("Player"))
{
return true;
}
}
}
return false;
}
private Vector3 FindNearestCover()
{
Vector3 nearestCover = coverPoints[0].position;
float closestDistance = Vector3.Distance(transform.position, nearestCover);
foreach (Transform cover in coverPoints)
{
float distance = Vector3.Distance(transform.position, cover.position);
if (distance < closestDistance)
{
nearestCover = cover.position;
closestDistance = distance;
}
}
return nearestCover;
}
private void MoveToCover(Vector3 coverPosition)
{
agent.SetDestination(coverPosition);
}
private void CheckStateTransitions()
{
if (currentState == AIState.Patrolling && distanceToPlayer < sightRange)
{
currentState = AIState.Chasing;
}
else if (currentState == AIState.Chasing && distanceToPlayer > chaseRange)
{
currentState = AIState.Patrolling;
}
else if (currentState == AIState.Chasing && distanceToPlayer < 10f )
{
currentState = AIState.Stalking;
}
}
private void CheckIfSeen()
{
RaycastHit hit;
Vector3 directionToAI = transform.position - playerCamera.position;
if (Physics.Raycast(playerCamera.position, directionToAI, out hit))
{
if (hit.transform == transform)
{
currentState = AIState.Chasing;
Debug.Log("Player looked at enemy, Chase mode activated");
}
}
}
private void ChaseState()
{
if (distanceToPlayer < chaseRange)
{
agent.SetDestination(target.position);
}
else
{
currentState = AIState.Stalking;
}
}
}
Editor is loading...
Leave a Comment