Danil Iarosh cefb2fd345 Build initial vertical platformer foundation
Подробные изменения:
- Добавлены сцены Bootstrap, MainMenu и Game с текущей вертикальной 9:16 структурой проекта.
- Добавлены runtime-скрипты gameplay-архитектуры: DI через Extenject, спавнер платформ, прогрессия этапов, one-way платформы, игрок, камера и оборудование JumpPad.
- Добавлены ScriptableObject-этапы сложности, weighted-настройки платформ, оборудования, противников и collectibles.
- Добавлены UI Toolkit ресурсы главного меню, preview-материалы, шрифты, спрайты, анимации и игровые prefab-ассеты.
- Перенесена и оформлена новая COM-система для работы с аппаратными портами и StreamingAssets.
- Обновлены проектные гайды, AGENTS.md, правила Git/Git LFS, .gitignore, Unity Packages и ProjectSettings.
- Удалён локальный skill start-required-mcp-servers из репозитория.
2026-05-11 07:41:14 +03:00

139 lines
4.2 KiB
C#

using System.Collections.Generic;
using UnityEngine;
namespace DanroJump.Gameplay
{
public sealed class PlatformController : MonoBehaviour, IPlatformRuntime, IPlatformLifecycle
{
[SerializeField] private List<PlatformSpawnPoint> collectibleSpawnPoints = new();
[SerializeField] private List<PlatformSpawnPoint> equipmentSpawnPoints = new();
[SerializeField] private List<PlatformSpawnPoint> enemySpawnPoints = new();
public Transform Transform => transform;
public IReadOnlyList<PlatformSpawnPoint> CollectibleSpawnPoints => collectibleSpawnPoints;
public IReadOnlyList<PlatformSpawnPoint> EquipmentSpawnPoints => equipmentSpawnPoints;
public IReadOnlyList<PlatformSpawnPoint> EnemySpawnPoints => enemySpawnPoints;
public int SpawnIndex { get; private set; }
public bool IsStartPlatform { get; private set; }
public float WorldY { get; private set; }
private void Awake()
{
CollectSpawnPoints();
}
private void OnValidate()
{
CollectSpawnPoints();
}
public void Initialize(PlatformSpawnContext context)
{
ApplyContext(context);
NotifyChildrenInitialize(context);
}
public void Recycle(PlatformSpawnContext context)
{
ApplyContext(context);
NotifyChildrenRecycle(context);
}
public void ResetPlatform()
{
NotifyChildrenReset();
}
private void ApplyContext(PlatformSpawnContext context)
{
SpawnIndex = context.SpawnIndex;
IsStartPlatform = context.IsStartPlatform;
WorldY = context.WorldY;
}
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<PlatformSpawnPoint> 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<PlatformSpawnPoint> collectibleBuffer = new();
private readonly List<MonoBehaviour> lifecycleBuffer = new();
}
}