112 lines
3.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
[SerializeField] private List<BezierWay> Ways;
public List<EnemyShip> EnemyPrefabs;
public bool Initialized { get; private set; }
public int MaxBudget = 1000;
public int RemainingBudget;
public event Action<EnemyShip> EnemySpawned;
[SerializeField] private float SpawnInterval = 5;
private float LastSpawnTime = 0;
public void Initialize()
{
if (Initialized) return;
if (!Validate())
{
Debug.LogError("Валидация настроек спавнера не прошла", this);
return;
}
RemainingBudget = MaxBudget;
EnemyShip.ShipReleased += EnemyShip_ShipReleased;
EnemyShip.ShipDefeated += EnemyShip_ShipReleased;
Initialized = true;
}
private void EnemyShip_ShipReleased(EnemyShip releasedShip)
{
RemainingBudget += releasedShip.SpawnCost;
}
private void OnDisable()
{
EnemyShip.ShipReleased -= EnemyShip_ShipReleased;
EnemyShip.ShipDefeated -= EnemyShip_ShipReleased;
}
public bool Validate()
{
if (EnemyPrefabs == null || EnemyPrefabs.Count == 0)
{
Debug.LogError("Не задан список врагов на спавнере", this);
return false;
}
foreach (var enemy in EnemyPrefabs)
{
if (!enemy.TryGetComponent<EnemyShip>(out _))
{
Debug.LogError($"Префаб врага {enemy.name} не содержит компонент AbstractEnemyShip");
return false;
}
}
return true;
}
private void Update()
{
if (!Initialized) return;
if (CanSpawn()) Spawn();
}
private bool CanSpawn()
{
return CanSpawnByTime() && HasClearWay() && CanSpawnByBudget();
bool CanSpawnByTime() => Time.time - LastSpawnTime > SpawnInterval;
bool HasClearWay() => Ways.Any(way => !way.Busy);
bool CanSpawnByBudget() => EnemyPrefabs.Any(enemyPrefab => enemyPrefab.SpawnCost<= RemainingBudget);
}
private BezierWay GetNotBusyWay() => Ways.FirstOrDefault(way => !way.Busy);
private EnemyShip GetRandomAccessibleSheep()
{
var accessible = EnemyPrefabs.Where(e => e.GetComponent<EnemyShip>().SpawnCost <= RemainingBudget).ToList();
if (accessible.Count == 0) return null;
var randomIndex = UnityEngine.Random.Range(0, accessible.Count);
return accessible[randomIndex];
}
private void Spawn()
{
var way = GetNotBusyWay();
var sheepPrefab = GetRandomAccessibleSheep();
var go = Instantiate(sheepPrefab.gameObject, way.FirstPoint.position, Quaternion.identity);
var sheep = go.GetComponent<EnemyShip>();
sheep.AssignToWay(way);
sheep.Initialize();
EnemySpawned?.Invoke(sheep);
RemainingBudget -= sheep.SpawnCost;
LastSpawnTime = Time.time;
}
}