using System.Collections.Generic; using Base; using Prefab; using Unity.VisualScripting; using UnityEngine; namespace AI { public abstract class JobBase { public Entity.Entity entity; protected int timeoutTicks = 300; public bool Running => timeoutTicks > 0; protected abstract void UpdateJob(); public virtual void StartJob(Entity.Entity target) { entity = target; } public bool Update() { if (!Running) return false; UpdateJob(); timeoutTicks--; return true; } public virtual void StopJob() { timeoutTicks = 0; } } public class WanderJob : JobBase { public override void StartJob(Entity.Entity target) { base.StartJob(target); Vector3 move = new(Random.Range(-10, 10), Random.Range(-10, 10)); var targetPosition = entity.transform.position + move; entity.SetTarget(targetPosition); entity.IsChase = false; } protected override void UpdateJob() { entity.TryMove(); } override public void StopJob() { base.StopJob(); entity.IsChase = true; } } public class IdleJob : JobBase { override public void StartJob(Entity.Entity target) { base.StartJob(target); timeoutTicks = 500; } protected override void UpdateJob() { } } public class MoveJob : JobBase { protected override void UpdateJob() { entity.TryMove(); } } public class TrackPlayerJob : JobBase { private EntityPrefab currentTarget; // 当前追踪的目标玩家 private List players; // 玩家实体列表 public override void StartJob(Entity.Entity target) { base.StartJob(target); UpdateTarget(); } protected override void UpdateJob() { if (currentTarget == null || currentTarget.entity.IsDead) { // 如果当前目标无效,则重新查找最近的玩家 UpdateTarget(); } if (currentTarget != null) { var targetPosition = new Vector3(currentTarget.Position.x, currentTarget.Position.y, 0); entity.SetTarget(targetPosition); entity.TryMove(); } } private void UpdateTarget() { players = Managers.EntityManage.Instance.FindEntitiesByFaction("Player"); if (players == null || players.Count == 0) { currentTarget = null; StopJob(); return; } currentTarget = GetNearestPlayer(players); } private EntityPrefab GetNearestPlayer(List players) { EntityPrefab nearestPlayer = null; float minDistance = float.MaxValue; foreach (var player in players) { if (player.entity.IsDead) continue; // 跳过无效玩家 float distance = Vector3.Distance( new Vector3(player.Position.x, player.Position.y, 0), new Vector3(entity.Position.x, entity.Position.y, 0) ); if (distance < minDistance) { minDistance = distance; nearestPlayer = player; } } return nearestPlayer; } } public class AttackPlayerJob : JobBase { private EntityPrefab player; protected override void UpdateJob() { if (player == null || !IsPlayerInRange()) { StopJob(); // 如果玩家不在范围内,停止攻击工作 return; } entity.TryAttack(); } private bool IsPlayerInRange() { float distance = Vector3.Distance( new Vector3(player.Position.x, player.Position.y, 0), new Vector3(entity.Position.x, entity.Position.y, 0) ); return distance <= entity.attributes.attackRange; } public override void StartJob(Entity.Entity target) { base.StartJob(target); // 查找最近的玩家作为目标 List players = Managers.EntityManage.Instance.FindEntitiesByFaction("Player"); player = GetNearestPlayer(players); } private EntityPrefab GetNearestPlayer(List players) { EntityPrefab nearestPlayer = null; float minDistance = float.MaxValue; foreach (var player in players) { if (!IsPlayerValid(player)) continue; float distance = Vector3.Distance( new Vector3(player.Position.x, player.Position.y, 0), new Vector3(entity.Position.x, entity.Position.y, 0) ); if (distance < minDistance) { minDistance = distance; nearestPlayer = player; } } return nearestPlayer; } private bool IsPlayerValid(EntityPrefab player) { return player != null && !player.entity.IsDead; } } public class RangedAttackJob : JobBase { private EntityPrefab player; protected override void UpdateJob() { if (player == null || !IsPlayerValid(player)) { StopJob(); // 如果当前目标无效,停止工作 return; } float distance = Vector3.Distance( new Vector3(player.Position.x, player.Position.y, 0), new Vector3(entity.Position.x, entity.Position.y, 0) ); if (distance <= entity.attributes.attackRange) { // 如果在攻击范围内,进行攻击 entity.TryAttack(); } else if (distance > entity.attributes.attackRange && distance < MaxTrackDistance) { // 如果距离过远,靠近目标 MoveTowardsPlayer(); } else if (distance < entity.attributes.attackRange) { // 如果距离过近,远离目标 MoveAwayFromPlayer(); } } private void MoveTowardsPlayer() { Vector3 targetPosition = new Vector3(player.Position.x, player.Position.y, 0); entity.SetTarget(targetPosition); entity.TryMove(); } private void MoveAwayFromPlayer() { Vector3 direction = entity.Position - player.Position; direction.Normalize(); Vector3 targetPosition = entity.Position + direction * RetreatDistance; entity.SetTarget(targetPosition); entity.TryMove(); } public override void StartJob(Entity.Entity target) { base.StartJob(target); // 查找最近的玩家作为目标 List players = Managers.EntityManage.Instance.FindEntitiesByFaction("Player"); player = GetNearestPlayer(players); } private EntityPrefab GetNearestPlayer(List players) { EntityPrefab nearestPlayer = null; float minDistance = float.MaxValue; foreach (var player in players) { if (!IsPlayerValid(player)) continue; float distance = Vector3.Distance( new Vector3(player.Position.x, player.Position.y, 0), new Vector3(entity.Position.x, entity.Position.y, 0) ); if (distance < minDistance) { minDistance = distance; nearestPlayer = player; } } return nearestPlayer; } private bool IsPlayerValid(EntityPrefab player) { return player != null && !player.entity.IsDead; } private const float MaxTrackDistance = 20f; // 最大追踪距离 private const float RetreatDistance = 3f; // 后退距离 } }