using System.Collections.Generic; using UnityEngine; namespace DanroJump.Gameplay { /// /// Runtime-контроллер платформы: хранит точки спавна контента и рассылает lifecycle-события. /// public sealed class PlatformController : MonoBehaviour, IPlatformRuntime, IPlatformLifecycle { [SerializeField] private List collectibleSpawnPoints = new(); [SerializeField] private List equipmentSpawnPoints = new(); [SerializeField] private List enemySpawnPoints = new(); /// /// Transform платформы для систем генерации и контента. /// public Transform Transform => transform; /// /// Точки, где на платформе можно размещать collectible-предметы. /// public IReadOnlyList CollectibleSpawnPoints => collectibleSpawnPoints; /// /// Точки, где на платформе можно размещать специальное оборудование. /// public IReadOnlyList EquipmentSpawnPoints => equipmentSpawnPoints; /// /// Точки, где на платформе можно размещать противников. /// public IReadOnlyList EnemySpawnPoints => enemySpawnPoints; /// /// Порядковый номер спавна платформы в текущей генерации. /// public int SpawnIndex { get; private set; } /// /// Показывает, является ли платформа стартовой. /// public bool IsStartPlatform { get; private set; } /// /// Y-координата платформы в момент последней генерации или recycle. /// public float WorldY { get; private set; } /// /// Собирает точки спавна при загрузке платформы. /// private void Awake() { CollectSpawnPoints(); } /// /// Обновляет списки точек спавна при изменениях prefab в редакторе. /// private void OnValidate() { CollectSpawnPoints(); } /// /// Инициализирует платформу после первого создания. /// public void Initialize(PlatformSpawnContext context) { ApplyContext(context); NotifyChildrenInitialize(context); } /// /// Переиспользует платформу с новым контекстом генерации. /// public void Recycle(PlatformSpawnContext context) { ApplyContext(context); NotifyChildrenRecycle(context); } /// /// Сбрасывает дочерние lifecycle-компоненты платформы. /// public void ResetPlatform() { NotifyChildrenReset(); } /// /// Запоминает данные текущего спавна платформы. /// private void ApplyContext(PlatformSpawnContext context) { SpawnIndex = context.SpawnIndex; IsStartPlatform = context.IsStartPlatform; WorldY = context.WorldY; } /// /// Собирает дочерние PlatformSpawnPoint по категориям контента. /// private void CollectSpawnPoints() { collectibleSpawnPoints.Clear(); equipmentSpawnPoints.Clear(); enemySpawnPoints.Clear(); GetComponentsInChildren(true, collectibleBuffer); foreach (var spawnPoint in collectibleBuffer) { if (spawnPoint == null) { continue; } GetSpawnPointList(spawnPoint.Kind).Add(spawnPoint); } collectibleBuffer.Clear(); } /// /// Возвращает список точек спавна нужной категории. /// private List GetSpawnPointList(PlatformContentKind kind) { switch (kind) { case PlatformContentKind.Collectible: return collectibleSpawnPoints; case PlatformContentKind.Equipment: return equipmentSpawnPoints; case PlatformContentKind.Enemy: return enemySpawnPoints; default: return collectibleSpawnPoints; } } /// /// Сообщает дочерним компонентам о первом создании платформы. /// private void NotifyChildrenInitialize(PlatformSpawnContext context) { GetComponentsInChildren(true, lifecycleBuffer); foreach (var behaviour in lifecycleBuffer) { if (behaviour is IPlatformLifecycle lifecycle && !ReferenceEquals(lifecycle, this)) { lifecycle.Initialize(context); } } lifecycleBuffer.Clear(); } /// /// Сообщает дочерним компонентам о рецикле платформы. /// private void NotifyChildrenRecycle(PlatformSpawnContext context) { GetComponentsInChildren(true, lifecycleBuffer); foreach (var behaviour in lifecycleBuffer) { if (behaviour is IPlatformLifecycle lifecycle && !ReferenceEquals(lifecycle, this)) { lifecycle.Recycle(context); } } lifecycleBuffer.Clear(); } /// /// Сообщает дочерним компонентам о сбросе платформы. /// private void NotifyChildrenReset() { GetComponentsInChildren(true, lifecycleBuffer); foreach (var behaviour in lifecycleBuffer) { if (behaviour is IPlatformLifecycle lifecycle && !ReferenceEquals(lifecycle, this)) { lifecycle.ResetPlatform(); } } lifecycleBuffer.Clear(); } private readonly List collectibleBuffer = new(); private readonly List lifecycleBuffer = new(); } }