using UnityEngine; namespace DanroJump.Gameplay { /// /// Базовый класс оборудования платформы с trigger-контактом игрока. /// [RequireComponent(typeof(Collider2D))] public abstract class PlatformEquipmentBase : MonoBehaviour, IPlatformEquipment, IPlayerContactHandler { private readonly System.Collections.Generic.List landingHandlerBuffer = new(); private Collider2D equipmentCollider; /// /// Платформа, на которую установлено оборудование. /// protected IPlatformRuntime Platform { get; private set; } /// /// В редакторе переводит коллайдер оборудования в trigger. /// protected virtual void Reset() { equipmentCollider = GetComponent(); if (equipmentCollider != null) { equipmentCollider.isTrigger = true; } } /// /// Сбрасывает состояние при включении, чтобы объект можно было переиспользовать. /// private void OnEnable() { ResetEquipment(); } /// /// Передает контакт с игроком в конкретную реализацию оборудования. /// private void OnTriggerEnter2D(Collider2D other) { if (PlayerContactUtility.TryGetAlivePlayer(other, out var player)) { HandlePlayerContact(player, this); } } /// /// Повторно проверяет игрока внутри trigger, чтобы pickup не терялся при спавне/движении в уже пересеченной зоне. /// private void OnTriggerStay2D(Collider2D other) { if (PlayerContactUtility.TryGetAlivePlayer(other, out var player)) { HandlePlayerContact(player, this); } } /// /// Привязывает оборудование к платформе. /// public virtual void Install(IPlatformRuntime platform) { Platform = platform; } /// /// Точка расширения для сброса внутреннего состояния оборудования. /// public virtual void ResetEquipment() { } /// /// Уведомляет родительскую платформу о landing-событии, если оборудование само обработало посадку игрока. /// protected void NotifyPlatformLandingHandlers(JumpPlayerController player) { if (player == null) { return; } equipmentCollider ??= GetComponent(); var context = new PlatformLandingContext( equipmentCollider, null, player.GroundCheckPosition, Vector2.up, false); GetComponentsInParent(false, landingHandlerBuffer); foreach (var landingHandler in landingHandlerBuffer) { landingHandler.TryHandleLanding(player, context); } landingHandlerBuffer.Clear(); } /// /// Обрабатывает контакт игрока с оборудованием. /// public abstract void HandlePlayerContact(JumpPlayerController player, Component source); } }