Files
PIM_7/Assets/_Scripts/EnemyAI.cs
T

165 lines
4.2 KiB
C#
Raw Normal View History

2026-06-04 15:09:10 +03:00
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(CharacterController))]
public class EnemyAI : MonoBehaviour
{
public CaptureZone[] zones;
public float moveSpeed = 3.5f;
public float retargetInterval = 2f;
public float stoppingDistance = 0.7f;
public float randomFactor = 4f;
private CharacterController characterController;
private NavMeshAgent navMeshAgent;
private CaptureZone targetZone;
private Vector3 targetOffset;
private float retargetTimer;
private Vector3 verticalVelocity;
private void Awake()
{
characterController = GetComponent<CharacterController>();
navMeshAgent = GetComponent<NavMeshAgent>();
if (navMeshAgent != null)
{
navMeshAgent.speed = moveSpeed;
navMeshAgent.stoppingDistance = stoppingDistance;
}
}
private void Start()
{
ChooseTarget();
}
private void Update()
{
retargetTimer -= Time.deltaTime;
if (targetZone == null || targetZone.GetOwner() == CaptureZone.Owner.Enemy || retargetTimer <= 0f)
{
ChooseTarget();
}
MoveToTarget();
}
private void ChooseTarget()
{
retargetTimer = retargetInterval + Random.Range(0f, 0.75f);
targetZone = null;
CaptureZone bestPlayerZone = FindBestZone(CaptureZone.Owner.Player);
if (bestPlayerZone != null)
{
SetTarget(bestPlayerZone);
return;
}
CaptureZone bestNeutralZone = FindBestZone(CaptureZone.Owner.Neutral);
if (bestNeutralZone != null)
{
SetTarget(bestNeutralZone);
}
}
private CaptureZone FindBestZone(CaptureZone.Owner owner)
{
if (zones == null || zones.Length == 0)
{
return null;
}
CaptureZone best = null;
float bestScore = float.MaxValue;
for (int i = 0; i < zones.Length; i++)
{
CaptureZone zone = zones[i];
if (zone == null || zone.GetOwner() != owner)
{
continue;
}
float distance = Vector3.Distance(transform.position, zone.transform.position);
float score = distance + Random.Range(0f, randomFactor);
if (score < bestScore)
{
bestScore = score;
best = zone;
}
}
return best;
}
private void SetTarget(CaptureZone zone)
{
targetZone = zone;
Vector2 randomCircle = Random.insideUnitCircle * 1.5f;
targetOffset = new Vector3(randomCircle.x, 0f, randomCircle.y);
if (CanUseNavMeshAgent())
{
navMeshAgent.SetDestination(GetTargetPosition());
}
}
private void MoveToTarget()
{
if (targetZone == null)
{
return;
}
Vector3 targetPosition = GetTargetPosition();
if (CanUseNavMeshAgent())
{
if (!navMeshAgent.hasPath || Vector3.Distance(navMeshAgent.destination, targetPosition) > 0.5f)
{
navMeshAgent.SetDestination(targetPosition);
}
return;
}
Vector3 direction = targetPosition - transform.position;
direction.y = 0f;
if (direction.magnitude <= stoppingDistance)
{
return;
}
Vector3 horizontalMove = direction.normalized * moveSpeed;
if (characterController.isGrounded && verticalVelocity.y < 0f)
{
verticalVelocity.y = -1f;
}
verticalVelocity.y += Physics.gravity.y * Time.deltaTime;
characterController.Move((horizontalMove + verticalVelocity) * Time.deltaTime);
if (horizontalMove.sqrMagnitude > 0.001f)
{
transform.rotation = Quaternion.LookRotation(horizontalMove.normalized, Vector3.up);
}
}
private Vector3 GetTargetPosition()
{
return targetZone.transform.position + targetOffset;
}
private bool CanUseNavMeshAgent()
{
return navMeshAgent != null &&
navMeshAgent.enabled &&
navMeshAgent.isActiveAndEnabled &&
navMeshAgent.isOnNavMesh;
}
}