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);
}
}