first commit
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user