510 lines
22 KiB
Markdown
510 lines
22 KiB
Markdown
# Архитектура проекта "Mario-like platformer"
|
||
|
||
## Обзор
|
||
Это 2D-платформер на Unity, созданный по образу классических игр Mario. Проект реализован на C# с использованием Unity 2D и включает систему управления через клавиатуру или COM-порт (для аркадных автоматов).
|
||
|
||
---
|
||
|
||
## Основные технологии
|
||
- **Unity Engine** (версия для 2D)
|
||
- **Unity Input System** - новая система ввода
|
||
- **Unity Audio Mixer** - управление звуком
|
||
- **Visual Effect Graph** - визуальные эффекты
|
||
- **Addressables** - динамическая загрузка ресурсов
|
||
- **Universal Render Pipeline (URP)** - графический конвейер
|
||
|
||
---
|
||
|
||
## Структура проекта
|
||
|
||
### 📁 Assets/Scripts/
|
||
|
||
#### **1. Abstract/** - Базовые абстракции
|
||
- `Interfaces.cs` - интерфейсы проекта:
|
||
- `IRecallable` - для возвращаемых объектов
|
||
- `IPickable` - для подбираемых предметов
|
||
- `IDamageable` - для объектов, получающих урон
|
||
- `ILaunchable` - для запускаемых снарядов
|
||
- `IBouncy` - для отскакивающих объектов
|
||
- `Enums.cs` - перечисления (Direction2D и др.)
|
||
|
||
#### **2. Managers/** - Центральные менеджеры (паттерн Singleton)
|
||
Основные управляющие классы игры:
|
||
|
||
##### `GameManager.cs` - Главный менеджер игры
|
||
- **Singleton** с автоинициализацией через `[RuntimeInitializeOnLoadMethod]`
|
||
- Управляет всеми остальными менеджерами
|
||
- Хранит игровое состояние:
|
||
- Жизни игрока (Lives)
|
||
- Монеты (Coins)
|
||
- Текущий мир и уровень (World, Stage)
|
||
- Состояние паузы (IsPaused)
|
||
- Управляет спавном игрока
|
||
- Система событий:
|
||
- `PauseStateChanged` - изменение паузы
|
||
- `PlayerSpawned` - спавн игрока
|
||
- `CoinsChanged`, `LivesChanged`, `MaxLivesChanged` - изменение игровых параметров
|
||
- `GameOverEvent`, `GameWonEvent` - завершение игры
|
||
- Интегрирует логирование через `CompositeLogger`
|
||
|
||
##### `SettingsManager.cs` - Управление настройками
|
||
- Загрузка/сохранение настроек в JSON
|
||
- Работа с `GameSettings` ScriptableObject
|
||
- События: `OnSettingsLoaded`, `OnSettingsSaved`
|
||
- Применение настроек к игре
|
||
|
||
##### `AudioManager.cs` - Управление звуком
|
||
- Управление фоновой музыкой:
|
||
- Плавные переходы (fade in/out)
|
||
- Кроссфейд между треками
|
||
- Пул AudioSource для звуковых эффектов (SFX)
|
||
- Интеграция с AudioMixer
|
||
- Round-robin система для проигрывания SFX
|
||
|
||
##### `PaymentManager.cs` - Система оплаты
|
||
- Управление кредитами для аркадного автомата
|
||
- Интеграция с COM-портом для приема монет
|
||
- События: `OnCreditsChanged`, `OnCreditAdded`, `OnCreditRemoved`
|
||
- Поддержка бесплатной игры
|
||
- Опциональное сохранение кредитов между сессиями
|
||
|
||
##### `PrizeSystemManager.cs` - Система призов
|
||
- Управление выдачей призов
|
||
- Интеграция с внешним оборудованием через COM
|
||
|
||
##### `GlobalsManager.cs` - Глобальные настройки
|
||
- Загрузка глобальных префабов
|
||
- DontDestroyOnLoad объекты
|
||
|
||
#### **3. Behaviour/** - Игровое поведение
|
||
|
||
##### **Camera/**
|
||
- `CameraFollow.cs` - Следование камеры за игроком:
|
||
- Плавное следование с damping
|
||
- Offset в зависимости от направления взгляда игрока
|
||
- Автоматический поиск игрока на сцене через корутину `BindLoop()`
|
||
- Snap к игроку при первом обнаружении
|
||
- `CameraManager.cs` - Управление камерой на уровне
|
||
- `CameraControlTrigger.cs` - Триггеры для особого поведения камеры
|
||
- `CinemachineFindPlayer.cs` - Интеграция с Cinemachine
|
||
|
||
##### **Controllers/**
|
||
- `PlayerController.cs` - Управление игроком:
|
||
- Физика через Rigidbody2D
|
||
- Input System для управления (moveAction, jumpAction)
|
||
- Настройки движения: скорость, ускорение, торможение
|
||
- Прыжки с variable jump height
|
||
- Проверка приземления через GroundCheck
|
||
- Интеграция с системой здоровья (Health)
|
||
- Анимации через Animator
|
||
- Звуковые эффекты (шаги, урон, прыжки)
|
||
- Реализует интерфейс `IDamageable`
|
||
|
||
- `EnemyController.cs` - Управление врагами
|
||
- `MusicController.cs` - Контроллер музыки на сценах
|
||
|
||
##### **Checkpoints/**
|
||
- `Checkpoint.cs` - Чекпоинты на уровне
|
||
- `PlayerSpawn.cs` - Точки спавна игрока
|
||
- `CheckpointSystem.cs` - Система управления чекпоинтами
|
||
|
||
##### **Projectiles/** - Система снарядов
|
||
- `Projectile2D.cs` - Базовый снаряд
|
||
- `BasicProjectile.cs` - Простой снаряд
|
||
- `PhysicsProjectile.cs` - Снаряд с физикой
|
||
- `PickableProjectile.cs` - Подбираемый снаряд
|
||
- `EnemyBasicProjectile.cs` - Снаряды врагов
|
||
|
||
##### **ThrowProjectiles/** - Система стрельбы
|
||
- `FireScript2D.cs` - Базовая стрельба
|
||
- `PlayerFireScript.cs` - Стрельба игрока
|
||
- `EnemyFireScript.cs` - Стрельба врагов
|
||
|
||
##### **Другое**
|
||
- `Health.cs` - Компонент здоровья:
|
||
- Максимальное и текущее здоровье
|
||
- TakeDamage, Heal, ResetHealth
|
||
- Связь с владельцем через `IDamageable`
|
||
- `Parallax.cs` - Эффект параллакса для фона
|
||
- `LightDimmer.cs` - Управление освещением
|
||
|
||
#### **4. Entities/** - Игровые сущности
|
||
|
||
##### **Платформы:**
|
||
- `MovingPlatform.cs` - Движущиеся платформы
|
||
- `Oscillator.cs` - Осциллирующие платформы
|
||
- `ShiftingPlatform.cs` - Смещающиеся платформы
|
||
- `VanishingPlatform.cs` - Исчезающие платформы:
|
||
- Плавное исчезновение/появление (fade in/out)
|
||
- Корутины `Vanish()` и `Reappear()`
|
||
- Отключение CompositeCollider2D
|
||
- Работа с массивом SpriteRenderer для анимации прозрачности
|
||
|
||
##### **Props/** - Интерактивные объекты
|
||
- `Collectible.cs` - Собираемые предметы
|
||
- `CoinCollectible.cs` - Монеты
|
||
- `Trap.cs` - Ловушки
|
||
|
||
##### **Другое:**
|
||
- `JumpPad2D.cs` - Трамплины
|
||
- `Rotator.cs` - Вращающиеся объекты
|
||
- `LightActionsController.cs` - Управление светом
|
||
|
||
#### **5. Controls/** - Система управления
|
||
|
||
##### **Inputs/** - Абстракция ввода
|
||
- `In.cs` - Статический фасад для унифицированного доступа к вводу:
|
||
- Выбор источника ввода (клавиатура/COM)
|
||
- Автоматическая инициализация
|
||
- Единый интерфейс для игровой логики
|
||
|
||
- `InputSource.cs` - Базовый класс источника ввода
|
||
- `InputSourceType.cs` - Типы источников (Keyboard/COM)
|
||
- `KeyboardInput.cs` - Ввод с клавиатуры
|
||
- `COMInput.cs` - Ввод через COM-порт
|
||
|
||
##### **ComSystem/** - Работа с COM-портом
|
||
- `ComWrapper.cs` - Обертка для работы с COM
|
||
- `ComNativeWrapper.cs` - Нативные вызовы
|
||
- `PrizeSystem.cs` - Интеграция призовой системы
|
||
|
||
##### **Другое:**
|
||
- `PlayerAction.cs` - Действия игрока
|
||
- `ButtonPinMapping.cs` - Маппинг кнопок на пины
|
||
- `ComInputToInputSystemAdapter.cs` - Адаптер COM → Input System
|
||
|
||
#### **6. UI/** - Пользовательский интерфейс
|
||
- `MainMenu.cs` - Главное меню
|
||
- `PauseMenu.cs` - Меню паузы
|
||
- `GameEndUIController.cs` - UI завершения игры
|
||
- `LoseBannerController.cs` - Баннер поражения (с таймером продолжения)
|
||
- `SettingsUI.cs` - UI настроек
|
||
- `SettingsUIList.cs` - Список настроек:
|
||
- Слайдеры громкости (музыка/SFX)
|
||
- Тогглы оплаты (бесплатная игра, призы)
|
||
- Настройки жизней игрока
|
||
- `LevelSelectModal.cs` - Модальное окно выбора уровня
|
||
- `LevelButton.cs` - Кнопка уровня
|
||
- `TopPanelTextController.cs` - Верхняя панель с информацией
|
||
- `UICreditsTextController.cs` - Отображение кредитов
|
||
- `QRCodeUIController.cs` - Отображение QR-кодов
|
||
- `UIPointer.cs` - Указатель в меню
|
||
- `ScrollSelectionFollower.cs` - Следование скролла за выбранным элементом
|
||
- `ModalFocusTrap.cs` - Захват фокуса в модальных окнах
|
||
- `FullscreenToggle.cs` - Переключение полноэкранного режима
|
||
|
||
#### **7. ScriptableObjects/** - Ресурсы конфигурации
|
||
- `GameSettings.cs` - Настройки игры:
|
||
- Общие: полноэкранный режим, громкость
|
||
- Оплата: бесплатная игра, призы, телефон
|
||
- Игрок: стартовые жизни, прирост жизней
|
||
- Методы: `SetDefaultValues()`, `ValidateSettings()`, `ApplySettings()`
|
||
|
||
- `SFXAsset.cs` - Набор звуковых эффектов
|
||
- `EnemySFXAsset.cs` - Звуки врагов
|
||
- `EnemyControllerConfiguration.cs` - Конфигурация врагов
|
||
- `EnemyFireConfiguration.cs` - Конфигурация стрельбы врагов
|
||
|
||
#### **8. Animations/** - Анимационные события
|
||
- `PlayerAnimationEvents.cs` - События анимаций игрока
|
||
- `EnemyAnimationEvents.cs` - События анимаций врагов
|
||
|
||
#### **9. Audio/** - Звуковая система
|
||
- `SoundEffect.cs` - Базовый звуковой эффект
|
||
- `LevelPlayerSFX.cs` - SFX для уровня
|
||
|
||
#### **10. FX/** - Визуальные эффекты
|
||
- `PlayerRunVFX.cs` - Эффекты бега игрока
|
||
- `CheckPointFX.cs` - Эффекты чекпоинтов
|
||
|
||
#### **11. Utilities/** - Вспомогательные утилиты
|
||
- `FileLogger.cs` - Логирование в файл
|
||
- `CompositeLogger.cs` - Комбинированное логирование
|
||
- `LoggerInitializer.cs` - Инициализация логгера
|
||
- `DebugSettings.cs` - Настройки отладки
|
||
- `QRCodeUtils.cs` - Утилиты для QR-кодов
|
||
- `PhoneNumberUtils.cs` - Валидация телефонных номеров (мультистрановая)
|
||
- `AutoCursorHider.cs` - Автоматическое скрытие курсора
|
||
- `ReadOnlyInInspectorAttribute.cs` - Атрибут только для чтения в Inspector
|
||
- `AdvancedLoggingExample.cs` - Пример продвинутого логирования
|
||
|
||
#### **12. Editor/** - Редакторские скрипты
|
||
- `MusicController_Inspector.cs` - Кастомный инспектор для MusicController
|
||
|
||
#### **13. Settings/_sega/** - Альтернативная система настроек (для SEGA автоматов)
|
||
- `SettingsScreen.cs` - Экран настроек
|
||
- `SettingsManager.cs` - Менеджер настроек
|
||
- `SettingsCombination.cs` - Комбинации настроек
|
||
- `SettingOption.cs` - Отдельная настройка
|
||
- `GameSettings.cs` - Настройки игры
|
||
|
||
---
|
||
|
||
## Архитектурные паттерны
|
||
|
||
### 1. **Singleton Pattern**
|
||
Все менеджеры реализованы как синглтоны с автоинициализацией:
|
||
```csharp
|
||
public static GameManager Instance { get; private set; }
|
||
|
||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||
private static void Initialize()
|
||
{
|
||
if (Instance != null) return;
|
||
GameObject go = new GameObject(nameof(GameManager));
|
||
Instance = go.AddComponent<GameManager>();
|
||
DontDestroyOnLoad(go);
|
||
}
|
||
```
|
||
|
||
### 2. **Event-Driven Architecture**
|
||
Все менеджеры используют события для коммуникации:
|
||
```csharp
|
||
public event Action<bool> PauseStateChanged;
|
||
public event Action<GameObject> PlayerSpawned;
|
||
public UnityEvent<int> OnCreditsChanged;
|
||
```
|
||
|
||
### 3. **Dependency Injection через Inspector**
|
||
Компоненты конфигурируются через Inspector с использованием SerializeField:
|
||
```csharp
|
||
[SerializeField] private InputActionReference moveAction;
|
||
[SerializeField] private float moveSpeed = 8f;
|
||
```
|
||
|
||
### 4. **Component-Based Architecture**
|
||
Игровые объекты состоят из переиспользуемых компонентов:
|
||
- `Health` - здоровье
|
||
- `PlayerController` - управление
|
||
- `Animator` - анимация
|
||
|
||
### 5. **Interface Segregation**
|
||
Четко определенные интерфейсы для разных типов поведения:
|
||
- `IDamageable` - может получать урон
|
||
- `IPickable` - можно подобрать
|
||
- `ILaunchable` - можно запустить
|
||
|
||
### 6. **Facade Pattern**
|
||
`In.cs` предоставляет единый интерфейс для работы с разными источниками ввода.
|
||
|
||
### 7. **Object Pool**
|
||
AudioManager использует пул AudioSource для эффективного проигрывания SFX.
|
||
|
||
### 8. **ScriptableObject Configuration**
|
||
Конфигурация через ScriptableObjects для удобного редактирования:
|
||
- `GameSettings`
|
||
- `SFXAsset`
|
||
- `EnemyControllerConfiguration`
|
||
|
||
---
|
||
|
||
## Потоки данных
|
||
|
||
### 1. **Инициализация игры**
|
||
```
|
||
Runtime Initialize → GameManager.Awake()
|
||
├── Инициализация Logger
|
||
├── Загрузка Globals
|
||
├── Инициализация SettingsManager
|
||
├── Инициализация AudioManager
|
||
└── Инициализация PaymentManager
|
||
```
|
||
|
||
### 2. **Игровой цикл**
|
||
```
|
||
Player Input → InputSystem/COMInput
|
||
↓
|
||
PlayerController.Update/FixedUpdate
|
||
↓
|
||
Physics (Rigidbody2D)
|
||
↓
|
||
Animator
|
||
↓
|
||
Camera Follow
|
||
```
|
||
|
||
### 3. **Система урона**
|
||
```
|
||
Trap/Enemy → IDamageable.TakeDamage()
|
||
↓
|
||
Health.TakeDamage()
|
||
↓
|
||
Health <= 0? → IDamageable.Die()
|
||
↓
|
||
GameManager.GameOverEvent
|
||
```
|
||
|
||
### 4. **Система настроек**
|
||
```
|
||
SettingsUI → GameSettings (ScriptableObject)
|
||
↓
|
||
SettingsManager.SaveSettings()
|
||
↓
|
||
JSON File (persistentDataPath)
|
||
↓
|
||
SettingsManager.LoadSettings()
|
||
↓
|
||
GameSettings.ApplySettings()
|
||
```
|
||
|
||
---
|
||
|
||
## Ключевые особенности
|
||
|
||
### 1. **Поддержка аркадных автоматов**
|
||
- Ввод через COM-порт
|
||
- Система приема монет
|
||
- Выдача призов
|
||
- Бесплатная игра (настраиваемо)
|
||
|
||
### 2. **Гибкая система управления**
|
||
- Unity Input System
|
||
- Поддержка клавиатуры и аркадных кнопок
|
||
- Легко расширяемая через `InputSource`
|
||
|
||
### 3. **Продвинутое логирование**
|
||
- Составное логирование (консоль + файл)
|
||
- Категории логов
|
||
- Уровни важности
|
||
|
||
### 4. **Система сохранения**
|
||
- JSON сериализация настроек
|
||
- Сохранение в `persistentDataPath`
|
||
- Валидация при загрузке
|
||
|
||
### 5. **Аудио система**
|
||
- Плавные переходы музыки
|
||
- Эффективный пул для SFX
|
||
- Интеграция с AudioMixer
|
||
|
||
### 6. **UI навигация**
|
||
- Поддержка навигации без мыши (для автоматов)
|
||
- Визуальный указатель выбора
|
||
- Автоскролл к выбранному элементу
|
||
- Модальные окна с фокусом
|
||
|
||
---
|
||
|
||
## Пространства имен
|
||
|
||
Проект использует следующие пространства имен:
|
||
- `RR.Game2D.Core` - основной функционал игры
|
||
- `RR.Game2D.Core.Managers` - менеджеры
|
||
- `RR.Game2D.Behaviour` - поведение объектов
|
||
- `RR.Game2D.Entities` - игровые сущности
|
||
- `RR.Common.Managers` - общие менеджеры
|
||
- `RR.Common.Controls` - система управления
|
||
- `RR.Common.UI` - пользовательский интерфейс
|
||
- `RR.Common.Interfaces` - интерфейсы
|
||
- `RR.Common.Utility` - утилиты
|
||
- `RR.Common.Audio` - звуковая система
|
||
- `RR.Common.Behaviour.ScriptableObjects` - ScriptableObjects
|
||
|
||
---
|
||
|
||
## Зависимости и интеграции
|
||
|
||
### Unity пакеты:
|
||
- Input System
|
||
- Universal Render Pipeline (URP)
|
||
- Visual Effect Graph
|
||
- Addressables
|
||
- Cinemachine (опционально)
|
||
- TextMeshPro
|
||
|
||
### Внешние зависимости:
|
||
- System.IO.Ports (для COM-порта)
|
||
- System.Text.Json (для сохранения настроек)
|
||
|
||
---
|
||
|
||
## Принципы разработки
|
||
|
||
1. **Модульность** - каждый компонент независим и переиспользуем
|
||
2. **Расширяемость** - легко добавлять новые функции через интерфейсы
|
||
3. **Конфигурируемость** - большинство параметров настраивается в Inspector
|
||
4. **Отказоустойчивость** - валидация, проверки на null, fallback значения
|
||
5. **Производительность** - пулы объектов, кэширование компонентов
|
||
6. **Читаемость** - четкие названия, комментарии, XML документация
|
||
7. **Отладка** - продвинутая система логирования
|
||
|
||
---
|
||
|
||
## Структура сцен
|
||
|
||
### Persistent Scene (DontDestroyOnLoad):
|
||
- GameManager
|
||
- SettingsManager
|
||
- AudioManager
|
||
- PaymentManager
|
||
- Globals
|
||
|
||
### Level Scene:
|
||
- Player
|
||
- Enemies
|
||
- Platforms
|
||
- Collectibles
|
||
- UI Canvas
|
||
- Camera
|
||
- Lighting
|
||
|
||
---
|
||
|
||
## Порядок выполнения (Execution Order)
|
||
|
||
1. **-1000**: GameManager (через `[DefaultExecutionOrder(-1000)]`)
|
||
2. **Default**: Остальные компоненты
|
||
3. **Late Update**: Camera Follow
|
||
|
||
---
|
||
|
||
## Рекомендации по расширению
|
||
|
||
### Добавление нового врага:
|
||
1. Создать префаб с компонентами Rigidbody2D, Collider2D, Animator
|
||
2. Добавить компонент `Health` и реализовать `IDamageable`
|
||
3. Добавить `EnemyController` или создать новый контроллер
|
||
4. Создать `EnemySFXAsset` и `EnemyControllerConfiguration`
|
||
|
||
### Добавление новой платформы:
|
||
1. Наследоваться от MonoBehaviour
|
||
2. Использовать Rigidbody2D для физики
|
||
3. Реагировать на `OnCollisionEnter2D`/`OnCollisionExit2D`
|
||
4. Использовать корутины для анимаций
|
||
|
||
### Добавление нового источника ввода:
|
||
1. Создать класс, наследующий `InputSource`
|
||
2. Реализовать методы `Initialize()`, `GetAxis()`, `GetButton()` и т.д.
|
||
3. Добавить новый тип в `InputSourceType`
|
||
4. Обновить switch в `In.Initialize()`
|
||
|
||
### Добавление новой настройки:
|
||
1. Добавить поле в `GameSettings`
|
||
2. Обновить UI в `SettingsUIList`
|
||
3. Добавить валидацию в `GameSettings.ValidateSettings()`
|
||
4. Реализовать применение в `GameSettings.ApplySettings()`
|
||
|
||
---
|
||
|
||
## Известные особенности
|
||
|
||
1. **Двойная система настроек**: Есть основная система настроек и альтернативная в папке `_sega` для специфичных аркадных автоматов.
|
||
|
||
2. **Временные файлы**: Файлы с суффиксом `_Temp` являются временными решениями или устаревшими версиями.
|
||
|
||
3. **COM-интеграция**: Работа с COM-портом требует правильной настройки прав доступа в Windows и корректного маппинга пинов.
|
||
|
||
4. **Логирование**: Логи пишутся в файл `game.log` в корневой папке проекта (рядом с Assets).
|
||
|
||
5. **Ресурсы**: Префабы загружаются из папки Resources по заданным путям (настраиваемо в Inspector).
|
||
|
||
---
|
||
|
||
## Автор
|
||
Проект разработан с использованием пространства имен `RR` (предположительно инициалы разработчика или компании).
|
||
|
||
---
|
||
|
||
*Документ создан автоматически на основе анализа структуры проекта.*
|
||
|