Введение
CollectorBots — это стратегическая игра в реальном времени (RTS), разработанная на движке Unity. Игрок управляет базой с роботами-рабочими, которые собирают ресурсы, строят новые базы и расширяют свою территорию.
Цель игры
Основная цель — развить свою колонию роботов, собирая ресурсы (камень, дерево, железо) и строя дополнительные базы. Каждая база может производить новых рабочих, которые автоматически выполняют задачи по сбору и доставке ресурсов.
Жанр и целевая аудитория
- Жанр: RTS (Real-Time Strategy) с элементами автоматизации.
- Целевая аудитория: игроки, любящие стратегии, управление ресурсами и постепенное расширение без жёстких временных ограничений.
Геймплей
Игрок начинает с одной базовой структуры, которая уже имеет трёх рабочих. Рабочие автоматически сканируют окружающую территорию в поисках ресурсов, собирают их и доставляют на базу. Игрок может:
- Управлять базой: строить новых рабочих, устанавливать флаги для указания зон сбора.
- Наблюдать за ресурсами: отслеживать количество собранных ресурсов через UI.
- Строить новые базы: используя накопленные ресурсы, можно построить вторичную базу, которая также будет производить рабочих и расширять возможности сбора.
Игра не имеет явных противников или сценария победы — это бесконечный симулятор с акцентом на оптимизацию и расширение.
Технологический стек
- Unity 2021.3+ — основной движок.
- C# — язык программирования всех скриптов.
- DOTween — библиотека для плавных анимаций и твинов.
- TextMesh Pro — современная система отображения текста в UI.
- NavMesh — система навигации для перемещения рабочих по сцене.
- Unity Input System — новая система обработки ввода (вместо старого Input Manager).
- ScriptableObjects — для хранения конфигураций (стоимость построек, веса ресурсов и т.д.).
Структура проекта
Проект организован в соответствии с чистой архитектурой, разделяющей код на слои:
- Infrastructure — базовые сервисы (события, пулы объектов, управление ресурсами).
- Gameplay — игровая логика (рабочие, базы, ресурсы, задачи).
- Common — утилиты и расширения, используемые во всех модулях.
Все скрипты находятся в папке Assets/Scripts/. Ресурсы (префабы, модели, текстуры) хранятся в Assets/Resources/.
Документация
Эта документация создана с использованием mdBook и расположена в папке src/. Конфигурация mdBook находится в файле book.toml в корне проекта.
Документация охватывает:
- Архитектуру проекта
- Описание скриптов и кода
- Игровые механики
- Системы и сервисы
- Пользовательский интерфейс
- Конфигурацию и настройки
- Ресурсы (Assets)
- Тестирование и отладку
- Производительность и оптимизацию
- Сборку и развёртывание
Как пользоваться документацией
Навигация осуществляется через оглавление (см. SUMMARY.md). Каждая глава содержит подробное описание соответствующей части проекта, включая диаграммы Mermaid, примеры кода на C# и ссылки на реальные файлы проекта.
Если вы впервые знакомитесь с проектом, рекомендуется начать с Архитектуры проекта, чтобы понять общую структуру, а затем перейти к Игровым механикам для понимания основного геймплея.
Архитектура проекта
CollectorBots построен с использованием компонентно-ориентированной архитектуры Unity, дополненной слоистой структурой кода и рядом паттернов проектирования для повышения гибкости и поддерживаемости.
Высокоуровневая диаграмма
graph TD
A[Unity Engine] --> B[Bootstrap]
B --> C[Infrastructure Layer]
C --> D[Gameplay Layer]
C --> E[Common Utilities]
subgraph Infrastructure
C1[Event Aggregator]
C2[Object Pool]
C3[Asset Provider]
C4[Static Data Provider]
C5[Input Reader]
C6[UI Presenters]
end
subgraph Gameplay
D1[Base Structure]
D2[Worker]
D3[Resource Spawner]
D4[Task Management]
D5[World]
end
C1 --> D1
C1 --> D2
C3 --> D1
C4 --> D1
C5 --> D6
D1 --> D2
D2 --> D4
D3 --> D2
Используемые паттерны проектирования
Observer (Наблюдатель)
Реализован через собственную систему событий IntelligentEventAggregator. Позволяет объектам подписываться на события без жёсткой связности.
Пример:
// Подписка на событие
_eventAggregator.Subscribe<ResourceCollectedEvent>(OnResourceCollected);
// Публикация события
_eventAggregator.Publish(new ResourceCollectedEvent(resourceType, amount));
Factory (Фабрика)
Используется для создания объектов через IPrefabFactory и его параметризованные варианты. ObjectPool реализует паттерн пула объектов для повторного использования префабов.
Пример:
var worker = _workerFactory.Create(position, rotation);
MVC (Model‑View‑Controller)
В UI применяется вариант MVP (Model‑View‑Presenter):
- Model — игровые данные (ресурсы, задачи).
- View — Unity UI компоненты (StorageView, ResourceManagementView).
- Presenter — посредник между Model и View, подписывается на события и обновляет UI.
Component-Based (Компонентный)
Стандартный для Unity подход: каждый игровой объект состоит из компонентов (MonoBehaviour), которые добавляют функциональность.
Service Locator (Локатор служб)
Доступ к IEventAggregator и другим сервисам осуществляется через статический класс ServiceLocator (или внедрение зависимостей через конструкторы).
Структура папок проекта
Assets/
├── Scripts/ # Все C# скрипты
│ ├── Common/ # Общие утилиты и расширения
│ │ ├── Extensions/ # Методы расширения
│ │ │ ├── AreaExtensions.cs
│ │ │ ├── AssetProviderExtensions.cs
│ │ │ ├── CoroutineExtensions.cs
│ │ │ ├── DelegateExtensions.cs
│ │ │ ├── EnumerableExtensions.cs
│ │ │ ├── FactoryExtensions.cs
│ │ │ ├── RectangleExtensions.cs
│ │ │ └── TransformExtensions.cs
│ │ └── Utilities/ # Вспомогательные классы
│ │ ├── GizmosAreaDrawer.cs
│ │ ├── PriorityQueue.cs
│ │ ├── ThrowIf.cs
│ │ ├── Utils.cs
│ │ └── WeakReferenceComparer.cs
│ ├── Gameplay/ # Игровая логика
│ │ ├── Common/ # Общие игровые сущности
│ │ │ ├── Area.cs
│ │ │ ├── AreaRaycaster.cs
│ │ │ ├── Rectangle.cs
│ │ │ ├── ResourceSpendRequest.cs
│ │ │ └── Structure.cs
│ │ ├── Features/ # Основные фичи
│ │ │ ├── BaseStructure/
│ │ │ ├── BuilderManagement/
│ │ │ ├── ResourceSpawner/
│ │ │ ├── TaskManagement/
│ │ │ ├── TransportationManagement/
│ │ │ ├── WorkerMovement/
│ │ │ ├── World/
│ │ │ ├── GrabPoint.cs
│ │ │ ├── Flag.cs
│ │ │ └── Worker.cs
│ │ └── StaticData/ ScriptableObject конфигурации
│ │ ├── BaseStructureConfig.cs
│ │ ├── BuilderConfig.cs
│ │ ├── ResourceSpawnerConfig.cs
│ │ └── ResourceWeight.cs
│ └── Infrastructure/ # Инфраструктурные сервисы
│ ├── Bootstrap.cs # Точка входа
│ ├── Events/ # Система событий
│ ├── Factories/ # Фабрики и пулы
│ ├── AssetManagement/ # Управление ресурсами
│ ├── Input/ # Ввод пользователя
│ └── UI/ # UI презентеры
├── Resources/ # Ресурсы, загружаемые во время выполнения
│ ├── Prefabs/ # Все префабы
│ ├── Configs/ # ScriptableObject ассеты
│ ├── Animations/ # Animation Controller и клипы
│ ├── Models/ # 3D модели (.fbx)
│ ├── Materials/ # Материалы
│ ├── Textures/ # Текстуры
│ └── Fonts/ # Шрифты TextMesh Pro
├── Scenes/ # Единственная сцена
│ └── SampleScene.unity
└── Plugins/ # Сторонние библиотеки (DOTween)
Ключевые сцены
В проекте используется одна сцена — SampleScene. Она содержит:
- World — игровой мир с Terrain (Ground).
- Bootstrap — объект, инициализирующий все системы.
- UI Canvas — интерфейс пользователя.
- NavMesh — данные навигации для рабочих.
Сцена предварительно настроена с освещением, камерой и навигационной сеткой. Добавление новых сцен не требуется, так как весь геймплей происходит в рамках одной сцены.
Основные Prefab-ы
Infrastructure
- Bootstrap.prefab — точка входа, содержит
Bootstrapкомпонент, который создаёт и регистрирует все сервисы.
Universe
- World.prefab — контейнер для всего игрового мира, включает
Worldкомпонент для управления глобальными объектами.
Structures
- Base.prefab — главная база, имеет
BaseStructureкомпонент, аниматор, зоны ожидания и доставки. - SecondaryBase.prefab — вторичная база, аналогична главной, но с нулевым начальным количеством рабочих.
- Flag.prefab — флаг, который игрок может размещать для указания зоны сбора.
Workers
- Worker.prefab — робот-рабочий, включает
Workerкомпонент, аниматор, NavMeshAgent, скрипты движения и задач.
Resource
- IronResource.prefab, StoneResource.prefab, WoodResource.prefab — ресурсы разных типов (маленькие).
- MediumIronResource.prefab и т.д. — ресурсы среднего размера (для разнообразия).
Grounds
- Ground.prefab — террейн (земля), имеет коллайдер и навигационные данные.
UI
- ResourceManagementView.prefab — панель управления задачами (готовые, назначенные, завершённые).
- StorageView.prefab — отображение количества ресурсов (камень, дерево, железо).
- BaseStructurePanelGroup.prefab — панель управления выбранной базой (постройка рабочих, установка флага).
- Input.prefab — объект с
InputReaderдля обработки ввода.
Взаимодействие слоёв
- Infrastructure Layer предоставляет сервисы (события, пулы, ресурсы) через интерфейсы.
- Gameplay Layer использует эти сервисы для реализации игровой логики.
- UI Layer подписывается на события и отображает состояние игры.
- Common Utilities используются всеми слоями для повторяющихся операций.
Такое разделение позволяет легко заменять реализации (например, перейти с Resources.Load на Addressables) и добавлять новые фичи без переписывания существующего кода.
Скрипты и код
В этом разделе описаны все C# скрипты проекта, их назначение и взаимосвязи.
Полный список скриптов
Common/Extensions
| Файл | Назначение |
|---|---|
AreaExtensions.cs | Расширения для работы с областью (Area): проверка пересечения, случайная точка внутри. |
AssetProviderExtensions.cs | Упрощённые методы загрузки ресурсов через IAssetProvider (LoadPrefab, LoadConfig). |
CoroutineExtensions.cs | Расширения для MonoBehaviour для запуска корутин с автоматической отменой при уничтожении объекта. |
DelegateExtensions.cs | Утилиты для безопасного вызова делегатов (InvokeSafe). |
EnumerableExtensions.cs | Методы для IEnumerable<T> (например, RandomElement). |
FactoryExtensions.cs | Расширения для фабрик, создающие объекты с параметрами по умолчанию. |
RectangleExtensions.cs | Операции с прямоугольниками (Rectangle): пересечение, объединение, случайная точка. |
TransformExtensions.cs | Полезные методы для Transform: поиск детей по имени, сброс трансформации. |
Common/Utilities
| Файл | Назначение |
|---|---|
GizmosAreaDrawer.cs | Визуализация областей (Area) в редакторе Unity через Gizmos. |
PriorityQueue.cs | Обобщённая очередь с приоритетом на основе двоичной кучи. Используется для планирования задач. |
ThrowIf.cs | Утилита для проверки предусловий с выбрасыванием исключений (ThrowIf.Null, ThrowIf.OutOfRange). |
Utils.cs | Разнообразные статические helper‑методы (математика, преобразования, логика). |
WeakReferenceComparer.cs | Компаратор для WeakReference, позволяющий использовать weak‑ссылки в коллекциях. |
Gameplay/Common
| Файл | Назначение |
|---|---|
Area.cs | Представляет прямоугольную область на плоскости XZ с методами для проверки принадлежности точки. |
AreaRaycaster.cs | Лучший в области для поиска объектов определённого типа (например, ресурсов). |
Rectangle.cs | Структура прямоугольника с координатами левого нижнего и правого верхнего углов. |
ResourceSpendRequest.cs | Запрос на трату ресурсов, содержит тип ресурса и количество. |
Structure.cs | Базовый класс для всех строений (баз, флагов). Содержит общие свойства и методы. |
Gameplay/Features
| Файл | Назначение |
|---|---|
BaseStructure.cs | Основной компонент базы: управление рабочими, сканирование ресурсов, постройка новых рабочих. |
BuilderManagement/ | Логика строительства (стоимость, время, отмена). |
ResourceSpawner.cs | Система спавна ресурсов в заданной области с весами и интервалами. |
TaskManagement/ | Управление задачами рабочих (сбор, доставка, ожидание). |
TransportationManagement/ | Логика транспортировки ресурсов от точки сбора до базы. |
WorkerMovement/ | Движение рабочего по NavMesh с использованием WorkerMover. |
World.cs | Контейнер для глобальных игровых объектов, обеспечивает доступ к земле, ресурсам, базам. |
GrabPoint.cs | Точка захвата ресурса на рабочем (привязка ресурса к определённой кости). |
Flag.cs | Компонент флага, который игрок может размещать для указания зоны сбора. |
Worker.cs | Главный компонент рабочего: состояние, анимации, обработка задач, перемещение. |
Gameplay/StaticData
| Файл | Назначение |
|---|---|
BaseStructureConfig.cs | ScriptableObject с настройками базы: радиус сканирования, интервалы, начальное количество рабочих. |
BuilderConfig.cs | Конфигурация строительства: стоимость и время постройки базы и рабочего. |
ResourceSpawnerConfig.cs | Настройки спавна ресурсов: веса типов, область спавна, интервал. |
ResourceWeight.cs | Структура веса ресурса (тип и вес) для взвешенного случайного выбора. |
DataLoader.cs | Загрузчик данных для конкретного типа ScriptableObject. |
DataLoaderGeneric.cs | Обобщённый загрузчик данных. |
IStaticDataProvider.cs | Интерфейс провайдера статических данных. |
StaticDataProvider.cs | Реализация провайдера, загружающая конфиги из папки Resources/Configs/. |
Infrastructure
| Файл | Назначение |
|---|---|
Bootstrap.cs | Точка входа: создаёт и регистрирует все сервисы (EventAggregator, AssetProvider, InputReader). |
ICoroutineRunner.cs | Интерфейс для запуска корутин, абстрагирующий зависимость от MonoBehaviour. |
IInstantiator.cs | Интерфейс для инстанцирования объектов (обычно через Object.Instantiate). |
ObjectInstantiator.cs | Реализация IInstantiator с использованием Unity‑метода. |
SubscriptionInstaller.cs | Вспомогательный класс для массовой подписки на события. |
Infrastructure/Events
| Файл | Назначение |
|---|---|
IntelligentEventAggregator.cs | Основная реализация системы событий с поддержкой фильтров и условий подписки. |
MultipleSubscribeProvider.cs | Провайдер для подписки на несколько событий одновременно. |
ObservableList.cs | Реактивный список, уведомляющий об изменениях через события. |
SubscribeProvider.cs | Базовый провайдер подписки на одно событие. |
FakeSource.cs | Тестовый источник событий для отладки. |
| Conditions/ | Условия подписки (AlwaysTrue, Named, Sequence, SourceProperty, SourceType). |
| Contracts/ | Интерфейсы событийной системы (IEvent, IEventAggregator, IEventFilter и т.д.). |
| Data/ | Вспомогательные классы (EventTypeRegistry, SourceInfo, SubscriptionInfo). |
Infrastructure/Factories
| Файл | Назначение |
|---|---|
ObjectPool.cs | Пул объектов для повторного использования префабов. |
Factory.cs | Базовая фабрика без параметров. |
SingleParameterFactory.cs | Фабрика с одним параметром. |
TwoParametersFactory.cs | Фабрика с двумя параметрами. |
ThreeParametersFactory.cs | Фабрика с тремя параметрами. |
| Contracts/ | Интерфейсы фабрик (IFactory, ISingleParameterFactory и т.д.). |
| Data/ | События пула (ObjectPoolEvent, PoolObjectCreatedEvent). |
Infrastructure/AssetManagement
| Файл | Назначение |
|---|---|
IAssetProvider.cs | Интерфейс для загрузки ресурсов (префабов, конфигов). |
AssetProvider.cs | Реализация, использующая Resources.Load с кэшированием. |
Infrastructure/Input
| Файл | Назначение |
|---|---|
IInputReader.cs | Интерфейс чтения ввода (клики, перемещение камеры). |
InputReader.cs | Реализация на основе Unity Input System. |
Infrastructure/UI
| Файл | Назначение |
|---|---|
| Contracts/ | IPresenter — базовый интерфейс презентера. |
| Storage/ | ResourceStoragePresenter, StorageView — презентер и вид для отображения ресурсов. |
| Structures/ | BaseStructurePresenter, SelectedStructurePanelPresenter — управление UI базы. |
| TaskManagement/ | ResourceTaskManagementPresenter — презентер для задач сбора ресурсов. |
Классификация по категориям
Менеджеры (управляющие системы)
Bootstrap— инициализация.World— управление игровым миром.ResourceSpawner— спавн ресурсов.TaskManagement— диспетчеризация задач.BuilderManagement— управление строительством.
Модели данных
Area,Rectangle— геометрические примитивы.ResourceSpendRequest— DTO для траты ресурсов.ResourceWeight— вес ресурса.Structure— абстракция строения.
UI (Пользовательский интерфейс)
- Все презентеры в
Infrastructure/UI/. StorageView,ResourceManagementView— Unity UI компоненты.
Утилиты
- Все классы в
Common/UtilitiesиCommon/Extensions. ThrowIf,PriorityQueue,Utils.
Сервисы
IntelligentEventAggregator— система событий.AssetProvider— загрузка ресурсов.StaticDataProvider— доступ к конфигурациям.InputReader— обработка ввода.
Жизненный цикл ключевых объектов
sequenceDiagram
participant B as Bootstrap
participant E as EventAggregator
participant W as World
participant BS as BaseStructure
participant R as ResourceSpawner
participant Wo as Worker
participant T as TaskManagement
B->>E: Создание и регистрация
B->>W: Создание мира
B->>R: Запуск спавна ресурсов
B->>BS: Инициализация базы
BS->>Wo: Создание начальных рабочих
loop Каждый кадр
R->>R: Проверка интервала спавна
R->>W: Создание ресурса
BS->>BS: Сканирование области
BS->>T: Назначение задач
T->>Wo: Выдача задачи рабочему
Wo->>Wo: Движение к ресурсу
Wo->>Wo: Сбор ресурса
Wo->>BS: Доставка ресурса
BS->>E: Публикация ResourceCollectedEvent
end
Система обработки ввода
Ввод обрабатывается через Unity Input System. Класс InputReader реализует интерфейс IInputReader и предоставляет события:
OnClick— при клике левой кнопкой мыши.OnRightClick— при клике правой кнопкой.OnDrag— при перемещении мыши с зажатой кнопкой.OnZoom— при прокрутке колёсика.
Пример использования:
public class SomeController : MonoBehaviour
{
[SerializeField] private IInputReader _inputReader;
private void OnEnable()
{
_inputReader.OnClick += HandleClick;
}
private void OnDisable()
{
_inputReader.OnClick -= HandleClick;
}
private void HandleClick(Vector2 screenPosition)
{
// Конвертируем screenPosition в мировые координаты
// и выполняем действие
}
}
Система событий
События реализованы через IntelligentEventAggregator, который поддерживает:
- Типизированные события (наследники
IEvent). - Фильтры (
IEventFilter) для выборочной доставки. - Условия подписки (
ISubscribeCondition) для динамического управления подписками. - Weak‑ссылки на подписчиков, чтобы избежать утечек памяти.
Пример события:
public class ResourceCollectedEvent : IEvent
{
public ResourceType Type { get; }
public int Amount { get; }
public ResourceCollectedEvent(ResourceType type, int amount)
{
Type = type;
Amount = amount;
}
}
Подписка и публикация:
// Подписка
_eventAggregator.Subscribe<ResourceCollectedEvent>(OnResourceCollected);
// Публикация
_eventAggregator.Publish(new ResourceCollectedEvent(ResourceType.Stone, 1));
// Обработчик
private void OnResourceCollected(ResourceCollectedEvent evt)
{
Debug.Log($"Собран ресурс {evt.Type} в количестве {evt.Amount}");
}
Корутины и асинхронные операции
Для работы с корутинами используется интерфейс ICoroutineRunner, который позволяет запускать корутины вне MonoBehaviour.
Пример:
public class SomeService
{
private readonly ICoroutineRunner _coroutineRunner;
public SomeService(ICoroutineRunner coroutineRunner)
{
_coroutineRunner = coroutineRunner;
}
public void StartCounting()
{
_coroutineRunner.StartCoroutine(CountCoroutine());
}
private IEnumerator CountCoroutine()
{
for (int i = 0; i < 10; i++)
{
Debug.Log(i);
yield return new WaitForSeconds(1);
}
}
}
Расширение CoroutineExtensions добавляет метод StartCoroutineSafe, который автоматически останавливает корутину при уничтожении объекта.
Рекомендации по добавлению нового кода
- Соблюдайте слоистую архитектуру: инфраструктурный код — в
Infrastructure/, игровая логика — вGameplay/, общие утилиты — вCommon/. - Используйте события для связи между системами, а не прямые вызовы.
- Проверяйте предусловия с помощью
ThrowIf. - Документируйте публичные методы XML‑комментариями.
- Следите за длиной файлов — не более 200 строк (правило проекта).
Игровые механики
В этом разделе подробно описаны основные механики игры CollectorBots: как работают рабочие, базы, ресурсы и строительство.
Механика рабочих
Рабочие (роботы) — это ключевые юниты, которые выполняют все физические действия в игре: собирают ресурсы, доставляют их на базу, перемещаются по карте.
Движение
- NavMesh: каждый рабочий имеет компонент
NavMeshAgent, который позволяет ему перемещаться по поверхности Ground, обходя препятствия. - WorkerMover: высокоуровневый скрипт, управляющий движением. Он принимает целевую позицию и заставляет агента двигаться к ней.
- Состояния движения: рабочий может находиться в состоянии
Idle(ожидание),MovingToResource(движение к ресурсу),MovingToBase(движение к базе),Returning(возврат в зону ожидания).
Сбор ресурсов
- Поиск ресурса: база периодически сканирует область вокруг себя и находит ближайший ресурс.
- Назначение задачи: база создаёт задачу сбора и назначает её свободному рабочему.
- Движение к ресурсу: рабочий перемещается к позиции ресурса.
- Анимация захвата: при достижении ресурса проигрывается анимация
Armature_Grab_WithEvent, в момент которой ресурс визуально прикрепляется к точке захвата (GrabPoint) рабочего. - Изъятие ресурса: ресурс удаляется из мира (или деактивируется), а его тип и количество запоминаются в состоянии рабочего.
Доставка ресурсов
- После захвата ресурса рабочий переходит в состояние доставки.
- Он движется к зоне доставки базы (определённой в
BaseStructure). - При входе в зону доставки проигрывается анимация
Armature_Bring_WithEvent, ресурс визуально отделяется от рабочего. - Ресурс добавляется в хранилище базы, и публикуется событие
ResourceCollectedEvent. - Рабочий возвращается в зону ожидания и ждёт следующую задачу.
Состояния и анимации
- Idle: анимация покоя (рабочий стоит или слегка покачивается).
- Walking: анимация ходьбы, когда
NavMeshAgentдвижется. - Grab: анимация захвата ресурса (триггерится событием
OnGrab). - Bring: анимация доставки ресурса (триггерится событием
OnBring).
Анимации управляются через WorkerAnimator.controller и скрипт AnimationStateMonitor.
Механика баз
База (BaseStructure) — это центральная структура, которая управляет рабочими, сканирует ресурсы и накапливает собранные материалы.
Сканирование ресурсов
- Радиус сканирования: задаётся в
BaseStructureConfig(по умолчанию 278.4 единиц). - Интервал сканирования: также из конфига (1 секунда).
- Механизм: каждый интервал база ищет в своей области все ресурсы (
IronResource,StoneResource,WoodResource) с помощьюAreaRaycaster. - Приоритет: ресурсы сортируются по расстоянию до базы, ближайшие назначаются первыми.
Управление рабочими
- Начальное количество: у стартовой базы — 3 рабочих, у вторичной — 0.
- Постройка новых рабочих: игрок может нажать кнопку «Построить рабочего» в UI, если есть достаточно ресурсов (стоимость задаётся в
BuilderConfig). - Процесс постройки: занимает время (10 секунд), после чего в зоне появления базы инстанцируется префаб
Worker.prefab. - Управление задачами: база содержит очередь задач (
PriorityQueue) и назначает их свободным рабочим.
Зоны базы
Каждая база имеет три зоны (определяются в конфиге):
- Зона ожидания (
WaitingArea) — где рабочие стоят в бездействии. - Зона доставки (
DeliveryArea) — куда рабочие приносят ресурсы. - Зона появления (
SpawnArea) — где появляются новые рабочие после постройки.
Зоны задаются как Area (прямоугольник) и визуализируются в редакторе через GizmosAreaDrawer.
События базы
BaseStructureBuilt— когда база построена (для вторичных баз).WorkerBuilt— когда завершена постройка рабочего.WorkerSpawned— когда рабочий появился в мире.
Механика ресурсов
Ресурсы — это объекты, которые рабочие собирают и доставляют на базу. В игре три типа ресурсов: камень, дерево, железо.
Типы ресурсов
- StoneResource — серые камни, вес 100 (чаще всего спавнятся).
- WoodResource — коричневые брёвна, вес 95.
- IronResource — серебристые слитки, вес 90.
Каждый тип имеет свой префаб и иконку в UI.
Спавн ресурсов
Управляется ResourceSpawner на основе ResourceSpawnerConfig:
- Область спавна: прямоугольник от (-72.5, 105) до (72.5, -112.5) в мировых координатах.
- Интервал спавна: 4 секунды.
- Взвешенный случайный выбор: вероятность появления каждого типа пропорциональна его весу.
- Максимальное количество ресурсов: ограничено, чтобы не перегружать сцену.
Ресурс спавнится как префаб (маленький или средний вариант) в случайной точке внутри области.
Сбор ресурсов
Когда рабочий собирает ресурс, происходит следующее:
- Ресурс деактивируется (или уничтожается).
- Его тип и количество (всегда 1) записываются в инвентарь рабочего.
- После доставки ресурс добавляется в хранилище базы.
Хранение ресурсов
Каждая база имеет собственное хранилище (ResourceStorage), которое отслеживает количество каждого типа ресурсов. Хранилище обновляет UI через событие ResourceStorageChangedEvent.
Механика строительства
Игрок может строить новые базы и рабочих, тратя накопленные ресурсы.
Стоимость и время
Настройки хранятся в DefaultBuilderConfig:
База:
- Камень: 2
- Дерево: 1
- Железо: 2
- Время постройки: 20 секунд
Рабочий:
- Камень: 1
- Дерево: 2
- Железо: 0
- Время постройки: 10 секунд
Процесс строительства
- Игрок выбирает базу (кликает на неё).
- В UI появляется панель управления (
BaseStructurePanelGroup). - При нажатии кнопки «Построить базу» проверяется, хватает ли ресурсов.
- Если ресурсов достаточно, они списываются, и начинается таймер.
- По истечении времени в указанном месте (обычно рядом с главной базой) появляется новая база (
SecondaryBase.prefab).
Отмена строительства
На данный момент отмена не реализована — после начала постройки ресурсы уже списаны, и процесс нельзя прервать.
Взаимодействие механик
graph LR
A[Ресурс спавнится] --> B[База сканирует]
B --> C[Назначает задачу]
C --> D[Рабочий движется к ресурсу]
D --> E[Собирает ресурс]
E --> F[Доставляет на базу]
F --> G[Ресурс добавляется в хранилище]
G --> H[Игрок тратит ресурсы на строительство]
H --> I[Появляется новый рабочий/база]
I --> B
Ссылки на скрипты
- Рабочие:
Assets/Scripts/Gameplay/Features/Worker.cs,WorkerMovement/,GrabPoint.cs - Базы:
Assets/Scripts/Gameplay/Features/BaseStructure.cs,BaseStructureConfig.cs - Ресурсы:
Assets/Scripts/Gameplay/Features/ResourceSpawner.cs,ResourceSpawnerConfig.cs - Строительство:
Assets/Scripts/Gameplay/Features/BuilderManagement/,BuilderConfig.cs - Задачи:
Assets/Scripts/Gameplay/Features/TaskManagement/
Балансировка
Текущие значения (веса ресурсов, интервалы, стоимости) подобраны для умеренного темпа игры. При желании их можно легко изменить через ScriptableObject ассеты в Assets/Resources/Configs/.
Системы и сервисы
В этом разделе описаны инфраструктурные системы проекта, которые обеспечивают работу игровой логики. Эти системы реализованы как сервисы, доступные через интерфейсы, что позволяет легко заменять их реализации.
Bootstrap — точка входа
Bootstrap — это MonoBehaviour, который создаётся на сцене из префаба Infrastructure/Bootstrap.prefab. Его задача — инициализировать все ключевые сервисы и передать управление игровому миру.
Что делает Bootstrap:
- Создаёт экземпляры сервисов:
IntelligentEventAggregator— система событий.AssetProvider— загрузчик ресурсов.StaticDataProvider— загрузчик конфигураций.InputReader— обработчик ввода.ObjectPoolдля рабочих и ресурсов (если требуется).
- Регистрирует сервисы в статическом
ServiceLocator(или передаёт их через конструкторы зависимостей). - Создаёт мир — инстанцирует префаб
World.prefab. - Запускает начальные процессы — например, спавн ресурсов.
Код инициализации (упрощённый):
public class Bootstrap : MonoBehaviour
{
private void Awake()
{
var eventAggregator = new IntelligentEventAggregator();
var assetProvider = new AssetProvider();
var staticDataProvider = new StaticDataProvider(assetProvider);
var inputReader = Instantiate(inputPrefab).GetComponent<IInputReader>();
ServiceLocator.Register(eventAggregator);
ServiceLocator.Register(assetProvider);
// ... и т.д.
var world = assetProvider.LoadPrefab<World>("Prefabs/Universe/World");
Instantiate(world);
}
}
IntelligentEventAggregator — система событий
Это собственная реализация паттерна «Наблюдатель» с расширенными возможностями.
Основные возможности:
- Типизированные события — каждое событие реализует интерфейс
IEvent. - Фильтрация — можно подписаться только на события, удовлетворяющие условию (
IEventFilter). - Условия подписки (
ISubscribeCondition) — например, подписка только на события от определённого источника. - Weak‑ссылки — подписчики хранятся как
WeakReference, что предотвращает утечки памяти при забытой отписке. - Множественная подписка — через
MultipleSubscribeProviderможно подписаться на несколько типов событий одной лямбдой.
Пример использования:
// Подписка с условием
_eventAggregator.Subscribe<ResourceCollectedEvent>(
handler: evt => Debug.Log($"Ресурс {evt.Type} собран"),
condition: SubscribeCondition.Builder()
.SourceType<BaseStructure>()
.Build()
);
// Публикация
_eventAggregator.Publish(new ResourceCollectedEvent(ResourceType.Stone, 1));
Внутреннее устройство:
EventTypeRegistry— регистрирует типы событий для быстрого поиска.SubscriptionInfo— хранит информацию о подписке (обработчик, условие, источник).WeakReferenceComparer— сравнивает weak‑ссылки для корректной работы коллекций.
ObjectPool — пул объектов
Пул объектов используется для повторного использования префабов, чтобы избежать частого инстанцирования и уничтожения (например, для ресурсов и рабочих).
Особенности:
- Предварительное создание — можно заранее создать N экземпляров.
- Автоматическое расширение — если в пуле нет свободных объектов, создаётся новый.
- События пула —
PoolObjectCreatedEvent,PoolObjectGettedEvent,PoolObjectReleasedEvent. - Интерфейс
IObjectPool— позволяет абстрагироваться от конкретной реализации.
Пример:
var pool = new ObjectPool(workerPrefab, preloadCount: 5);
var worker = pool.Get(); // Взять объект из пула (или создать новый)
// ... использование
pool.Release(worker); // Вернуть в пул
AssetProvider — управление ресурсами с кэшированием
AssetProvider реализует интерфейс IAssetProvider и отвечает за загрузку ресурсов (префабов, ScriptableObject, текстур) из папки Resources.
Кэширование:
Загруженные ресурсы сохраняются в словаре, чтобы при повторном запросе не вызывать Resources.Load.
Методы:
T LoadPrefab<T>(string path)— загружает префаб по пути относительноResources.T LoadConfig<T>(string path)— загружает ScriptableObject.void Unload(string path)— выгружает ресурс из кэша (если больше не нужен).
Пример:
var provider = new AssetProvider();
var workerPrefab = provider.LoadPrefab<GameObject>("Prefabs/Workers/Worker");
var config = provider.LoadConfig<BuilderConfig>("Configs/DefaultBuilderConfig");
StaticDataProvider — статические данные
StaticDataProvider загружает все конфигурации (ScriptableObject) из папки Resources/Configs/ и предоставляет к ним доступ через типизированные методы.
Реализация:
Использует AssetProvider для загрузки, но также может кэшировать их в словаре по типу.
Интерфейс:
public interface IStaticDataProvider
{
T GetConfig<T>() where T : ScriptableObject;
}
Использование:
var config = staticDataProvider.GetConfig<BuilderConfig>();
var cost = config.BaseCost; // например, стоимость постройки базы
InputReader — ввод пользователя
InputReader — это обёртка над Unity Input System, которая преобразует низкоуровневые события ввода в удобные для игры события.
Поддерживаемые действия:
- Click — левый клик мыши (выбор объекта, размещение флага).
- RightClick — правый клик (отмена, контекстное меню — не используется).
- Drag — перемещение мыши с зажатой левой кнопкой (перетаскивание камеры).
- Zoom — прокрутка колёсика (приближение/отдаление камеры).
Реализация:
Использует InputActionAsset с предопределёнными action‑ами. События передаются через C# события (event Action<Vector2> OnClick).
Пример подписки:
_inputReader.OnClick += HandleClick;
private void HandleClick(Vector2 screenPosition)
{
var ray = Camera.main.ScreenPointToRay(screenPosition);
if (Physics.Raycast(ray, out var hit))
{
var structure = hit.collider.GetComponent<Structure>();
if (structure != null)
SelectStructure(structure);
}
}
Отсутствующие системы
Система сохранения
Не реализована. В текущей версии нет сохранения прогресса (количества ресурсов, построенных баз, рабочих). Для добавления можно использовать:
PlayerPrefsдля простых данных.- Сериализацию в JSON/XML для сложных структур.
- Unity
SaveSystem(пакетUnityEngine.Save).
Локализация
Не реализована. Все тексты в UI на английском (или русском, в зависимости от ассетов). Для поддержки нескольких языков можно интегрировать I2 Localization или Unity Localization Package.
Аналитика и достижения
Не реализованы. Нет отслеживания статистики (сколько ресурсов собрано, сколько рабочих построено) и системы достижений. Можно добавить через Unity Analytics или сторонние SDK.
Мультиплеер
Не реализован. Игра полностью однопользовательская. Добавление сетевого режима потребовало бы значительной переработки архитектуры (авторитетная серверная логика, синхронизация состояний).
Взаимодействие систем
graph TD
A[Bootstrap] --> B[EventAggregator]
A --> C[AssetProvider]
A --> D[StaticDataProvider]
A --> E[InputReader]
A --> F[ObjectPool]
B --> G[Gameplay Systems]
C --> G
D --> G
E --> G
F --> G
G --> H[UI Presenters]
G --> I[World]
H --> J[Unity UI]
I --> K[Game Objects]
Расширение систем
При необходимости добавить новую систему (например, систему звуков) рекомендуется:
- Создать интерфейс (
IAudioService) в папкеInfrastructure/. - Реализовать его в отдельном классе (
AudioService). - Зарегистрировать экземпляр в
Bootstrapи передавать через зависимости (или использовать Service Locator). - Использовать события для интеграции с игровой логикой (например, публиковать
SoundPlayEventпри сборе ресурса).
Пользовательский интерфейс
Пользовательский интерфейс (UI) в CollectorBots построен на основе Unity UI (uGUI) с использованием TextMesh Pro для текста. Архитектура UI следует паттерну MVP (Model‑View‑Presenter), где Presenter выступает посредником между игровыми данными и визуальными элементами.
Структура Canvas и иерархия UI
В сцене присутствует один главный Canvas, который содержит все UI‑элементы. Иерархия выглядит следующим образом:
Canvas (Render Mode: Screen Space - Overlay)
├── EventSystem
├── ResourceManagementView (префаб)
├── StorageView (префаб)
├── BaseStructurePanelGroup (префаб)
└── Input (префаб)
Каждый из этих префабов инстанцируется при инициализации (через Bootstrap или соответствующий презентер).
ResourceManagementView — управление задачами
ResourceManagementView отображает текущие задачи рабочих в трёх категориях:
- Готовые задачи (Ready) — ресурсы, которые можно собрать (ожидают назначения рабочего).
- Назначенные задачи (Assigned) — задачи, которые уже назначены на конкретного рабочего.
- Завершённые задачи (Completed) — задачи, которые были успешно выполнены (ресурс доставлен на базу).
Визуальное представление
Каждая категория представлена вертикальной панелью с заголовком и списком задач. Задача отображается как иконка ресурса + текст (например, “Stone x1”).
Презентер
ResourceTaskManagementPresenter подписывается на события:
TaskAssigned— добавляет задачу в список «Назначенные».TaskCompleted— перемещает задачу в «Завершённые».ResourceSpawned— добавляет задачу в «Готовые».
При изменении списка презентер обновляет View, вызывая методы AddReadyTask, MoveToAssigned и т.д.
StorageView — отображение ресурсов
StorageView показывает текущее количество ресурсов в хранилище выбранной базы.
Элементы интерфейса
Для каждого типа ресурса (камень, дерево, железо) есть отдельная строка, содержащая:
- Иконка ресурса (спрайт из
Assets/Resources/Textures/Icons/). - Название (текст на английском: “Stone”, “Wood”, “Iron”).
- Количество (число, обновляемое в реальном времени).
Презентер
ResourceStoragePresenter подписывается на событие ResourceStorageChangedEvent. Когда количество ресурсов меняется, презентер получает новое значение и вызывает StorageView.SetResourceCount(resourceType, count).
BaseStructurePanelGroup — управление базой
Эта панель появляется, когда игрок выбирает базу (кликает на неё). Она содержит:
- Кнопка “Build Worker” — запускает постройку нового рабочего (если хватает ресурсов).
- Кнопка “Place Flag” — позволяет разместить флаг для указания зоны сбора.
- Информация о базе — название, количество рабочих, уровень (не реализовано).
Презентер
BaseStructurePresenter создаётся фабрикой BaseStructurePresenterFactory при выборе базы. Он подписывается на события базы (например, WorkerBuilt) и обновляет UI. При нажатии кнопок презентер вызывает соответствующие методы на BaseStructure (например, StartBuildingWorker).
Связь Presenter → View → EventAggregator
Архитектура UI построена по принципу реактивного программирования: изменения в игровом состоянии публикуются как события, а презентеры реагируют на них, обновляя View.
Пример потока данных:
- Рабочий доставляет ресурс на базу.
- База публикует
ResourceCollectedEvent. ResourceStoragePresenter(подписанный на это событие) получает событие.- Презентер запрашивает у модели (
ResourceStorage) новое количество ресурсов. - Презентер вызывает
StorageView.SetResourceCount(...). - View обновляет текст на экране.
Код примера:
public class ResourceStoragePresenter : IPresenter
{
private readonly StorageView _view;
private readonly IEventAggregator _eventAggregator;
private readonly ResourceStorage _storage;
public ResourceStoragePresenter(StorageView view, IEventAggregator eventAggregator, ResourceStorage storage)
{
_view = view;
_eventAggregator = eventAggregator;
_storage = storage;
_eventAggregator.Subscribe<ResourceStorageChangedEvent>(OnStorageChanged);
}
private void OnStorageChanged(ResourceStorageChangedEvent evt)
{
var count = _storage.GetCount(evt.ResourceType);
_view.SetResourceCount(evt.ResourceType, count);
}
}
Шрифты
Во всём UI используется шрифт CrayonLibre‑Regular (из пакета TextMesh Pro). Он загружается как TMP_FontAsset из Assets/Resources/Fonts/CrayonLibre‑Regular SDF.asset.
Настройка шрифта:
- Размер по умолчанию: 24px.
- Стиль: Regular (обычный), без начертаний.
- Цвет: белый (#FFFFFF) с чёрной тенью для улучшения читаемости.
Адаптивность
UI разработан для разрешения 1920×1080, но использует Anchor Presets для корректного отображения на разных экранах:
StorageViewзакреплён в правом верхнем углу.ResourceManagementView— в левом верхнем углу.BaseStructurePanelGroup— в нижней части экрана по центру.
При изменении размера окна элементы сохраняют свои относительные позиции.
Анимации UI
Простые анимации (появление/исчезновение панелей, подсветка кнопок) реализованы через DOTween. Например, при выборе базы панель BaseStructurePanelGroup плавно выезжает снизу.
_view.PanelTransform.DOLocalMoveY(targetY, 0.3f).SetEase(Ease.OutBack);
Отладка UI
Для отладки UI в редакторе можно использовать:
- Game View с разными разрешениями (через меню “Game” → “Aspect Ratio”).
- UI Debugger (Window → Analysis → UI Debugger) для анализа иерархии и свойств элементов.
- Console — логи от презентеров (например, “Presenter initialized”, “View updated”).
Рекомендации по расширению
-
Добавление нового UI‑элемента:
- Создайте префаб с необходимыми компонентами (CanvasRenderer, Image, TextMeshPro‑Text и т.д.).
- Напишите View‑скрипт, реализующий интерфейс
IView(если используется) или просто публичные методы для обновления. - Создайте Presenter, который будет подписываться на соответствующие события и обновлять View.
- Зарегистрируйте Presenter в
Bootstrapили фабрике.
-
Локализация:
- Замените жёстко закодированные строки на ключи (например, “STORAGE_STONE”).
- Создайте систему локализации, которая будет загружать словарь из JSON и подставлять значения в
TextMeshProкомпоненты.
-
Оптимизация:
- Избегайте частых обновлений UI каждый кадр. Используйте события для реактивных обновлений.
- Объединяйте несколько изменений в один кадр (например, через
LayoutRebuilder.ForceRebuildLayoutImmediateтолько один раз).
Конфигурация и настройки
В проекте CollectorBots для хранения настроек используются ScriptableObject ассеты. Это позволяет изменять баланс игры без перекомпиляции кода, а также удобно настраивать различные параметры в редакторе Unity.
ScriptableObjects
Все конфигурационные файлы находятся в папке Assets/Resources/Configs/. Они загружаются через StaticDataProvider и доступны всем системам.
BaseStructureConfig
Настройки базовой структуры (главной и вторичной).
Поля:
| Поле | Тип | Описание |
|---|---|---|
WaitingArea | Area | Зона, где рабочие ожидают задачи. |
DeliveryArea | Area | Зона, куда рабочие доставляют ресурсы. |
SpawnArea | Area | Зона, где появляются новые рабочие после постройки. |
ScanRadius | float | Радиус сканирования ресурсов (в мировых единицах). |
ScanInterval | float | Интервал между сканированиями (в секундах). |
InitialWorkerCount | int | Начальное количество рабочих у базы. |
TaskAssignmentInterval | float | Интервал между назначениями задач (в секундах). |
Примеры значений:
-
StartBaseStructureConfig (главная база):
ScanRadius: 278.4ScanInterval: 1InitialWorkerCount: 3TaskAssignmentInterval: 1
-
SecondaryBaseStructureConfig (вторичная база):
ScanRadius: 278.4ScanInterval: 1InitialWorkerCount: 0TaskAssignmentInterval: 1
BuilderConfig
Настройки строительства (баз и рабочих).
Поля:
| Поле | Тип | Описание |
|---|---|---|
BaseCost | ResourceSpendRequest[] | Массив запросов ресурсов для постройки базы. |
WorkerCost | ResourceSpendRequest[] | Массив запросов ресурсов для постройки рабочего. |
BaseBuildTime | float | Время постройки базы (в секундах). |
WorkerBuildTime | float | Время постройки рабочего (в секундах). |
Пример значений (DefaultBuilderConfig):
- BaseCost:
- Камень (Stone) ×2
- Дерево (Wood) ×1
- Железо (Iron) ×2
- WorkerCost:
- Камень (Stone) ×1
- Дерево (Wood) ×2
- Железо (Iron) ×0
- BaseBuildTime: 20 секунд
- WorkerBuildTime: 10 секунд
ResourceSpawnerConfig
Настройки спавна ресурсов.
Поля:
| Поле | Тип | Описание |
|---|---|---|
ResourceWeights | ResourceWeight[] | Массив весов для каждого типа ресурса. |
SpawnArea | Rectangle | Прямоугольная область, в которой спавнятся ресурсы. |
SpawnInterval | float | Интервал между спавнами (в секундах). |
MaxResources | int | Максимальное количество ресурсов одновременно на карте. |
Пример значений (DefaultResourceSpawnerConfig):
- ResourceWeights:
- Stone: вес 100
- Wood: вес 95
- Iron: вес 90
- SpawnArea: прямоугольник от (-72.5, 105) до (72.5, -112.5)
- SpawnInterval: 4 секунды
- MaxResources: 50 (предположительно)
ResourceWeight
Вспомогательная структура, используемая в ResourceSpawnerConfig.
Поля:
| Поле | Тип | Описание |
|---|---|---|
ResourceType | ResourceType | Тип ресурса (Stone, Wood, Iron). |
Weight | int | Вес для взвешенного случайного выбора (чем больше, тем чаще появляется). |
Настройки навигации (NavMesh)
Навигационная сеть построена для поверхности Ground. Параметры NavMesh заданы в сцене SampleScene через окно Navigation (Window → AI → Navigation).
Настройки NavMeshAgent у рабочего
Компонент NavMeshAgent на префабе Worker.prefab имеет следующие параметры:
- Speed: 3.5
- Angular Speed: 120
- Acceleration: 8
- Stopping Distance: 0.5
- Auto Braking: true
- Radius: 0.5
- Height: 2
- Base Offset: 0
Эти значения обеспечивают плавное и реалистичное движение робота.
Область навигации
NavMesh покрывает всю поверхность Ground, за исключением участков под базами и ресурсами (они отмечены как Not Walkable). Это предотвращает попытки рабочих пройти сквозь объекты.
Настройки DOTween
DOTween используется для простых анимаций (появление/исчезновение UI, плавное перемещение камеры). Глобальные настройки хранятся в ассете Assets/Resources/DOTweenSettings.asset.
Параметры по умолчанию:
- Default Ease:
Ease.OutQuad - Default AutoPlay:
AutoPlay.All - Default UpdateType:
UpdateType.Normal - Default TimeScaleIndependent: false
- Default UseSafeMode: true
- Default LogBehaviour:
LogBehaviour.Default
Использование в коде:
// Плавное перемещение объекта за 1 секунду
transform.DOMove(targetPosition, 1f);
// Плавное изменение альфа‑канала UI изображения
image.DOFade(0, 0.5f);
Настройки камеры
Камера в сцене имеет следующие компоненты:
- Transform: позиция (0, 50, -50), поворот (45, 0, 0).
- Camera: Projection = Orthographic, Size = 30.
- Скрипт CameraController: обрабатывает перемещение и зум через
InputReader.
Параметры управления камерой (скорость перемещения, границы) заданы прямо в скрипте CameraController (не вынесены в конфиг).
Настройки физики
Проект использует стандартные настройки физики Unity (Edit → Project Settings → Physics):
- Gravity: (0, -9.81, 0)
- Default Material: None
- Bounce Threshold: 2
- Default Contact Offset: 0.01
Коллайдеры используются только для Ground (Terrain Collider) и ресурсов (Box Collider). Рабочие и базы не используют физику для движения (только NavMesh).
Настройки освещения
Освещение в сцене SampleScene настроено как Baked Global Illumination:
- Directional Light (солнце) с интенсивностью 1.0 и цветом белый.
- Ambient Source: Skybox.
- Environment Lighting: Intensity Multiplier = 1.0.
Такие настройки обеспечивают статичное, но приятное освещение без динамических теней (для производительности).
Настройки качества (Quality Settings)
Проект использует стандартные настройки качества Unity для платформы PC (Edit → Project Settings → Quality):
- Pixel Light Count: 4
- Texture Quality: Full Res
- Anisotropic Textures: Per Texture
- Anti‑Aliasing: 2x Multi Sampling
- Soft Particles: On
- Shadows: Hard and Soft Shadows, Shadow Distance 150
- Shadow Cascades: 4 Cascades
- Shadow Resolution: High
Как изменить конфигурацию
- Откройте папку
Assets/Resources/Configs/в окне Project. - Выберите нужный ассет (например,
DefaultBuilderConfig). - Измените значения в Inspector.
- Сохраните сцену (изменения применяются немедленно, но для работы в собранной игре нужно пересобрать проект).
Для добавления новой конфигурации создайте ScriptableObject, унаследованный от нужного базового класса, и поместите его в ту же папку. Затем загрузите через StaticDataProvider.GetConfig<T>().
Ресурсы (Assets)
В этом разделе описана структура папки Assets/ и содержимое ключевых ресурсов проекта: 3D модели, текстуры, материалы, анимации, шрифты и префабы.
Структура папки Assets
Assets/
├── 2D Casual UI/ # Готовые UI спрайты (используются для кнопок, панелей)
├── Plugins/ # Сторонние библиотеки (DOTween)
├── Resources/ # Ресурсы, загружаемые во время выполнения
│ ├── Animations/ # Animation Controller и клипы
│ ├── Configs/ # ScriptableObject конфигурации
│ ├── Fonts/ # Шрифты TextMesh Pro
│ ├── Materials/ # Материалы для 3D моделей
│ ├── Models/ # 3D модели (.fbx)
│ ├── Prefabs/ # Все префабы игры
│ └── Textures/ # Текстуры и иконки
├── Scenes/ # Единственная сцена SampleScene
└── Scripts/ # Все C# скрипты (см. раздел «Скрипты»)
3D модели
Все модели импортированы в формате FBX и находятся в Assets/Resources/Models/.
WorkerRobot_RTS.fbx
Модель рабочего робота.
- Полигоны: ~5 000 треугольников.
- Текстуры: используется материал
WorkerMat.mat. - Анимации: имеет скелетную анимацию (кости
Armature), поддерживает анимации захвата и доставки. - Масштаб: 1:1 (единица Unity = 1 метр).
Base_Structure_6X.fbx
Модель базовой структуры (главной и вторичной базы).
- Полигоны: ~10 000 треугольников.
- Текстуры: материал
SteelMap.mat(металлическая поверхность). - Особенности: содержит несколько дочерних объектов для зон ожидания, доставки и появления.
- Размеры: примерно 6×6×4 единиц.
Flag.fbx
Модель флага, который игрок может размещать для указания зоны сбора.
- Полигоны: ~500 треугольников.
- Текстуры: материал
FlagMat.mat(красный флаг на сером шесте). - Анимация: флаг развевается на ветру (через шейдер или простую анимацию).
SimpleResources.fbx
Один FBX‑файл, содержащий модели всех трёх типов ресурсов (камень, дерево, железо) в двух размерах (маленький и средний).
- Полигоны: ~200–500 треугольников на ресурс.
- Текстуры: используется общий материал
ResourcePalette.mat, который назначает цвет в зависимости от типа ресурса (через vertex color или текстуру). - Разделение: каждый ресурс — отдельный меш внутри файла, экспортированный как отдельный префаб.
Текстуры и материалы
Текстуры
- GoldSilverSteel.jpg — металлическая текстура для базы и рабочих (диффузная + specular).
- GradientAtlas 256 colors.png — атлас градиентов, возможно используется для UI или эффектов.
- Icons/ — иконки ресурсов (32×32 пикселя):
Iron_Icon.png— иконка железа.Stone_Icon.png— иконка камня.Wood_Icon.png— иконка дерева.
Материалы
- FlagMat.mat — материал флага (красный диффузный цвет, низкая гладкость).
- GroundMat.mat — материал земли (травяная текстура, возможно tiling).
- ResourcePalette.mat — материал ресурсов, использующий vertex color для окрашивания в разные цвета (камень — серый, дерево — коричневое, железо — серебристое).
- SteelMap.mat — материал для металлических поверхностей (база, части рабочего) с картой нормалей и отражениями.
- SteelMapPrewiew.mat — вероятно, упрощённая версия для превью в редакторе.
- WorkerMat.mat — материал рабочего (металл с тёмными акцентами).
Анимации
Анимации хранятся в Assets/Resources/Animations/.
Animation Controller
- BaseAnimator.controller — контроллер анимаций для базы. Содержит состояния
Idle(покой) и, возможно,Building(анимация постройки). - WorkerAnimator.controller — контроллер анимаций для рабочего. Состояния:
Idle— покой.Walk— ходьба.Grab— захват ресурса.Bring— доставка ресурса.
Переходы между состояниями управляются параметрами (IsWalking, IsGrabbing, IsBringing), которые устанавливаются скриптом Worker.
Animation Clips
- Armature_Grab_WithEvent.anim — анимация захвата ресурса. Включает события (
OnGrab), которые вызываются в определённый момент, чтобы прикрепить ресурс к точке захвата. - Armature_Bring_WithEvent.anim — анимация доставки ресурса. Событие
OnBringсигнализирует о моменте, когда ресурс должен быть отсоединён и добавлен в хранилище.
Оба клипа используют скелет Armature из модели рабочего.
Шрифты
Проект использует TextMesh Pro для всех текстовых элементов. Шрифт находится в Assets/Resources/Fonts/.
- CrayonLibre‑Regular.otf — исходный файл шрифта (OpenType).
- CrayonLibre‑Regular SDF.asset — сгенерированный
TMP_FontAssetс настройками SDF (Signed Distance Field), что позволяет масштабировать текст без потери качества.
Шрифт имеет рукописный стиль, что добавляет игре лёгкости и дружелюбности.
Префабы
Все префабы находятся в Assets/Resources/Prefabs/. Они сгруппированы по категориям:
Infrastructure
- Bootstrap.prefab — точка входа, содержит
Bootstrapкомпонент.
Universe
- World.prefab — контейнер игрового мира.
Structures
- Base.prefab — главная база.
- SecondaryBase.prefab — вторичная база.
- Flag.prefab — флаг.
Workers
- Worker.prefab — рабочий робот.
Resource
- IronResource.prefab, StoneResource.prefab, WoodResource.prefab — ресурсы маленького размера.
- MediumIronResource.prefab, MediumStoneResource.prefab, MediumWoodResource.prefab — ресурсы среднего размера.
Grounds
- Ground.prefab — террейн (земля).
UI
- ResourceManagementView.prefab — панель управления задачами.
- StorageView.prefab — панель ресурсов.
- BaseStructurePanelGroup.prefab — панель управления базой.
- Input.prefab — объект с
InputReader.
Каждый префаб настроен с необходимыми компонентами, ссылками на материалы и начальными значениями.
Адресные бандлы
В проекте не используются Addressable Assets. Все ресурсы загружаются через Resources.Load из папки Resources/. Это упрощает разработку, но имеет ограничения:
- Все ресурсы включаются в сборку, увеличивая её размер.
- Невозможно выгружать неиспользуемые ассеты во время выполнения.
Для будущей оптимизации рекомендуется мигрировать на Addressable Assets.
Рекомендации по оптимизации
3D модели
- LOD (Level of Detail): для моделей базы и рабочего можно добавить LOD‑группы, чтобы на расстоянии использовались упрощённые меши.
- Combine Meshes: статические объекты (например, ресурсы) можно объединять в один меш для уменьшения draw calls.
- Polygon Count: текущее количество полигонов приемлемо для PC, но для мобильных платформ стоит создать упрощённые версии.
Текстуры
- Разрешение: текстуры имеют разумный размер (1024×1024 или меньше). Проверить, можно ли уменьшить до 512×512 без видимой потери качества.
- Атласирование: иконки ресурсов уже собраны в один атлас? Если нет — создать текстуру‑атлас для UI.
- Сжатие: использовать формат ASTC (для мобильных) или BC7 (для PC) с максимальным сжатием.
Анимации
- Optimize Game Objects: в настройках импорта FBX включить опцию «Optimize Game Objects», чтобы уменьшить количество трансформ.
- Animation Compression: выбрать компрессию «Optimal» для клипов, чтобы уменьшить размер runtime‑данных.
Шрифты
- Character Set: в
TMP_FontAssetвключить только используемые символы (латиница, цифры, знаки препинания), чтобы уменьшить размер текстуры шрифта.
Префабы
- Pooling: активно использовать
ObjectPoolдля всех часто создаваемых/уничтожаемых объектов (ресурсы, рабочие). - Static Batching: пометить статические объекты (Ground) как static, чтобы Unity выполнил статический батчинг.
Инструменты для работы с ассетами
- Unity Editor: основная среда для настройки префабов, материалов, анимаций.
- Blender (или другая 3D‑программа) — для редактирования моделей.
- Adobe Photoshop (или GIMP) — для редактирования текстур.
- TexturePacker — для создания атласов.
Все исходные файлы (Blender‑сцены, PSD) рекомендуется хранить вне папки Assets/ (например, в SourceArt/), чтобы не загромождать проект.
Тестирование и отладка
В этом разделе описаны подходы к тестированию проекта CollectorBots, инструменты отладки, используемые в коде, а также известные ограничения и проблемы.
Методы тестирования
Ручное тестирование в редакторе Unity
Основной способ проверки работоспособности — запуск сцены SampleScene в редакторе и наблюдение за поведением игровых систем.
Что проверяется:
- Инициализация — при запуске сцены появляется база, три рабочих, ресурсы начинают спавниться.
- Сбор ресурсов — рабочие автоматически находят ресурсы, собирают их и доставляют на базу.
- UI обновления — количество ресурсов в
StorageViewувеличивается после доставки. - Постройка рабочих — при нажатии кнопки «Build Worker» списываются ресурсы, через 10 секунд появляется новый рабочий.
- Постройка базы — при достаточном количестве ресурсов можно построить вторичную базу.
- Навигация — рабочие корректно обходят препятствия и движутся по NavMesh.
- События — в консоли появляются логи при публикации событий (если включено логирование).
Тестовые сценарии
Для ускорения тестирования можно использовать предустановленные конфигурации:
- Быстрый старт: увеличить начальное количество ресурсов в хранилище, чтобы сразу тестировать постройку.
- Отключение спавна: временно отключить
ResourceSpawner, чтобы проверить поведение при отсутствии ресурсов. - Увеличение скорости: уменьшить интервалы сканирования и постройки, чтобы быстрее наблюдать циклы.
Инструменты отладки
Gizmos через GizmosAreaDrawer
Класс GizmosAreaDrawer позволяет визуализировать области (Area) в редакторе Unity. Это полезно для отладки зон базы (ожидания, доставки, появления) и области спавна ресурсов.
Как использовать:
- Добавьте компонент
GizmosAreaDrawerк любому игровому объекту. - В инспекторе укажите
Areaдля отрисовки. - Выберите цвет и тип (проволочный или залитый).
- В окне Scene (в режиме Gizmos) область будет отображаться как прямоугольник.
Unity Profiler
Для анализа производительности используется встроенный Unity Profiler (Window → Analysis → Profiler). Особое внимание стоит уделять:
- CPU Usage — нагрузка от скриптов (
Update, корутины, события). - Rendering — количество draw calls, треугольников, батчей.
- Memory — утечки памяти, размер текстур, мешей, объектов в пуле.
- Physics — затраты на NavMeshAgent.
Консоль и логирование
В коде используются стандартные методы логирования:
Debug.Log— для информационных сообщений.Debug.LogWarning— для предупреждений (например, «Ресурсов недостаточно»).Debug.LogError— для ошибок (например, «Не удалось загрузить префаб»).
Событийная система также может логировать публикацию и подписку (если включить флаг LogEvents в IntelligentEventAggregator).
Breakpoints и пошаговое выполнение
Поскольку проект написан на C#, можно использовать отладчик Visual Studio (или Rider) для пошагового выполнения кода. Для этого:
- Откройте проект в Visual Studio (через Open C# Project в Unity).
- Прикрепите отладчик к процессу Unity (Debug → Attach to Unity).
- Установите breakpoints в интересующих местах (например, в
Worker.CollectResource). - Запустите игру в редакторе — выполнение остановится на breakpoint.
ThrowIf utility
Утилита ThrowIf (файл Assets/Scripts/Common/Utilities/ThrowIf.cs) предоставляет методы для проверки предусловий с выбрасыванием исключений.
Примеры использования:
public void SomeMethod(string name, int value)
{
ThrowIf.Null(name, nameof(name)); // ArgumentNullException
ThrowIf.OutOfRange(value, 0, 100); // ArgumentOutOfRangeException
ThrowIf.Empty(collection, nameof(collection)); // InvalidOperationException
}
Преимущества:
- Уменьшает boilerplate‑код (не нужно писать
if (name == null) throw ...). - Делает проверки единообразными по всему проекту.
- Улучшает читаемость.
Известные ограничения
Нет системы сохранения
Текущая версия не сохраняет прогресс между сессиями. При перезапуске игры все построенные базы, рабочие и собранные ресурсы теряются.
Возможное решение: реализовать сохранение через PlayerPrefs (для простых данных) или сериализацию в JSON (для сложных структур). Ключевые данные для сохранения:
- Позиции и состояние всех баз.
- Количество рабочих у каждой базы.
- Количество ресурсов в хранилищах.
- Позиции ресурсов на карте (или seed генератора).
Одна сцена
В проекте используется единственная сцена SampleScene. Это ограничивает возможность создания меню, загрузочных экранов, разных уровней.
Возможное решение: добавить сцены меню и переключаться между ними через SceneManager.LoadScene. Для этого потребуется перенести инициализацию (Bootstrap) в отдельную сцену‑загрузчик.
Нет локализации
Все тексты в UI на английском (или русском, в зависимости от ассетов). Добавление поддержки других языков потребует интеграции системы локализации.
Возможное решение: использовать I2 Localization или Unity Localization Package. Заменить жёстко закодированные строки на ключи и загружать переводы из CSV/JSON.
Нет системы звуков
В игре отсутствуют звуковые эффекты (сбор ресурсов, движение рабочих, постройка) и фоновая музыка.
Возможное решение: создать AudioService с пулом аудиоисточников и подписываться на игровые события (ResourceCollectedEvent, WorkerBuiltEvent) для воспроизведения соответствующих звуков.
Ограниченный UI
UI содержит только базовые элементы. Нет панели статистики, настроек, паузы, помощи.
Возможное решение: расширить UIManager (если есть) или создать отдельные презентеры для каждой новой панели.
Автоматическое тестирование
На данный момент в проекте отсутствуют автоматические тесты (юнит‑тесты, интеграционные тесты). Рекомендуется добавить тестовый фреймворк (например, Unity Test Framework) и покрыть тестами ключевые системы:
PriorityQueue— корректность порядка элементов.AreaиRectangle— геометрические операции.ResourceStorage— добавление/удаление ресурсов.EventAggregator— подписка и публикация событий.
Пример юнит‑теста (псевдокод):
[Test]
public void PriorityQueue_Dequeue_ReturnsLowestPriority()
{
var queue = new PriorityQueue<int, int>();
queue.Enqueue(5, 5);
queue.Enqueue(1, 1);
queue.Enqueue(3, 3);
Assert.AreEqual(1, queue.Dequeue());
Assert.AreEqual(3, queue.Dequeue());
Assert.AreEqual(5, queue.Dequeue());
}
Отладка в собранной версии
Для отладки на устройстве (например, на PC вне редактора) можно использовать:
- Файл логов: Unity пишет логи в
%APPDATA%/../LocalLow/<CompanyName>/<ProductName>/output_log.txt(Windows). Добавить в код запись ключевых событий в файл. - Удалённый профилировщик: подключить Profiler к работающей собранной игре (в меню Build Settings включить «Development Build» и «Autoconnect Profiler»).
- Консоль отладки: в Development Build можно открыть консоль нажатием
Shift + Ctrl + C(Windows) для просмотра логов.
Рекомендации по улучшению тестируемости
- Внедрение зависимостей: использовать интерфейсы и внедрение зависимостей (через конструкторы), чтобы легко подменять реальные реализации mock‑объектами в тестах.
- Разделение логики и Unity‑зависимостей: выносить чистую логику в отдельные классы, не зависящие от
MonoBehaviour,Time.deltaTimeи т.д. Это позволит тестировать их без запуска Unity. - Тестовые данные: создать отдельные ScriptableObject с тестовыми конфигурациями (например, нулевая стоимость построек для быстрой проверки).
- Интеграция CI/CD: настроить автоматический запуск тестов при каждом коммите (например, через GitHub Actions и Unity Cloud Build).
Производительность и оптимизация
В этом разделе описаны меры, принятые для обеспечения хорошей производительности проекта CollectorBots, а также рекомендации по дальнейшей оптимизации.
ObjectPool для повторного использования объектов
Одна из самых затратных операций в Unity — инстанцирование и уничтожение игровых объектов (Instantiate/Destroy). Для ресурсов и рабочих, которые часто создаются и удаляются, используется ObjectPool.
Как работает
- Предзагрузка: при старте игры создаётся N экземпляров объекта (например, 10 ресурсов) и деактивируется.
- Взятие объекта: когда нужен новый ресурс, пул возвращает один из деактивированных, активирует его и настраивает.
- Возврат: после использования (например, ресурс собран) объект не уничтожается, а деактивируется и возвращается в пул.
Преимущества
- Уменьшает нагрузку на сборщик мусора (GC), так как объекты не уничтожаются.
- Снижает пиковые задержки при внезапном появлении множества объектов.
- Позволяет контролировать максимальное количество объектов (например, не более 50 ресурсов одновременно).
Реализация
Класс ObjectPool находится в Assets/Scripts/Infrastructure/Factory/ObjectPool.cs. Он поддерживает события (PoolObjectCreatedEvent, PoolObjectGettedEvent, PoolObjectReleasedEvent), что позволяет отслеживать использование пула.
NavMesh для оптимальной навигации
Перемещение рабочих реализовано через NavMeshAgent. Это эффективнее, чем ручное управление движением, потому что:
- Предрасчитанные пути: навигационная сеть заранее baked, что позволяет быстро находить маршруты.
- Оптимизация группового движения: Unity автоматически обрабатывает столкновения и перенаправление агентов.
- Минимальные затраты CPU: расчёт пути происходит в отдельном потоке (если используется
NavMeshAgentсautoRepath).
Настройки для производительности
- Agent Radius: 0.5 (достаточно для избегания столкновений).
- Obstacle Avoidance: Quality = High, но можно снизить до Medium, если много агентов.
- Auto Repath: включено, но с разумным интервалом (0.5 сек).
Кэширование в AssetProvider
Загрузка ресурсов через Resources.Load — операция не бесплатная, особенно если вызывать её каждый кадр. AssetProvider реализует простое кэширование:
private readonly Dictionary<string, UnityEngine.Object> _cache = new();
public T LoadPrefab<T>(string path) where T : UnityEngine.Object
{
if (_cache.TryGetValue(path, out var cached))
return (T)cached;
var asset = Resources.Load<T>(path);
_cache[path] = asset;
return asset;
}
Таким образом, каждый префаб или конфиг загружается только один раз за сессию.
Система событий с WeakReference (WeakReferenceComparer)
Система событий IntelligentEventAggregator хранит подписчиков как WeakReference. Это предотвращает утечки памяти, когда подписчик был уничтожен, но забыл отписаться.
Как это работает
- При подписке создаётся
WeakReferenceна делегат (или объект‑подписчик). - При публикации события проверяется, жив ли ещё подписчик (через
IsAlive). - Если подписчик был собран GC, запись автоматически удаляется из списка подписок.
Класс WeakReferenceComparer обеспечивает корректное сравнение weak‑ссылок в коллекциях.
Оптимизация UI обновлений
UI элементы обновляются не каждый кадр, а только при изменении данных (реактивно). Например, ResourceStoragePresenter подписывается на ResourceStorageChangedEvent и обновляет StorageView только когда количество ресурсов действительно изменилось.
Рекомендации
- Избегайте
Updateв UI скриптах: вместо этого используйте события. - Объединяйте несколько изменений: если за один кадр может прийти несколько событий, накапливайте изменения и применяйте их раз в кадр (через
Canvas.UpdateилиLayoutRebuilder). - Отключайте невидимые элементы: когда панель скрыта, можно временно отписаться от событий, чтобы не тратить ресурсы на обработку.
Оптимизация рендеринга
Статический батчинг
Объекты, которые не двигаются (Ground, базы), помечены как Static. Unity объединяет их в один draw call (статический батчинг), что значительно снижает нагрузку на GPU.
Динамический батчинг
Мелкие объекты с одинаковым материалом (например, ресурсы) могут быть сбатчены динамически, если их трансформации меняются не каждый кадр. В текущей реализации ресурсы не двигаются после спавна, поэтому они также могут быть статичными.
Уровни детализации (LOD)
Для моделей с высоким полигональным count (база, рабочий) можно добавить LOD‑группы. На расстоянии будет использоваться упрощённая модель, что уменьшит количество отрисовываемых треугольников.
Оптимизация скриптов
Корутины vs Update
Вместо использования Update для периодических действий (сканирование, спавн) применяются корутины с WaitForSeconds. Это эффективнее, потому что корутина «спит» между итерациями и не нагружает CPU.
Пример:
private IEnumerator ScanCoroutine()
{
while (true)
{
ScanForResources();
yield return new WaitForSeconds(_scanInterval);
}
}
Кэширование ссылок на компоненты
Избегайте вызовов GetComponent каждый кадр. Кэшируйте ссылки в Awake или Start.
private NavMeshAgent _agent;
private void Awake()
{
_agent = GetComponent<NavMeshAgent>();
}
Использование структур вместо классов
Для небольших данных, которые часто создаются (например, Rectangle, ResourceSpendRequest), используются структуры (value types). Это уменьшает нагрузку на кучу и сборщик мусора.
Профилирование и метрики
Unity Profiler
Регулярно запускайте Profiler (Window → Analysis → Profiler) для выявления узких мест:
- CPU: ищите методы с высоким self‑time (особенно
Update,FixedUpdate, корутины). - GPU: проверьте, не слишком ли много draw calls (цель — меньше 1000 для мобильных, меньше 2000 для PC).
- Memory: отслеживайте утечки (рост Managed Memory, увеличение числа объектов в куче).
Frame Debugger
Frame Debugger (Window → Analysis → Frame Debugger) показывает, как именно рендерится каждый кадр: какие draw calls, шейдеры, текстуры. Помогает найти лишние перерисовки.
Рекомендации по дальнейшей оптимизации
1. Миграция на Addressable Assets
Сейчас ресурсы загружаются через Resources.Load, что означает, что все ассеты включаются в сборку, даже если они не используются. Addressable Assets позволяют:
- Загружать ресурсы асинхронно.
- Выгружать неиспользуемые ассеты.
- Собирать контент в отдельные бандлы (например, для DLC).
2. Job System и Burst Compiler
Для вычислений, которые можно распараллелить (например, поиск ближайшего ресурса для множества рабочих), можно использовать Unity Job System и Burst Compiler. Это даст значительный прирост производительности на многоядерных процессорах.
3. GPU Instancing
Для отрисовки множества одинаковых объектов (ресурсы) включите GPU Instancing в материалах. Это уменьшит количество draw calls до одного на тип объекта.
4. Оптимизация анимаций
- Используйте Animation Culling для отключения анимации у объектов вне камеры.
- Переведите анимации рабочих в Humanoid тип, если возможно, для применения оптимизаций Unity.
- Примените Level of Detail для анимаций (более простые анимации на расстоянии).
5. Сокращение использования GC
- Избегайте аллокаций в
Update(например,new List<>,new Vector3). - Используйте пулы не только для GameObjects, но и для коллекций (например,
ListPoolизUnityEngine.Pool). - Замените LINQ на обычные циклы там, где это критично (LINQ создаёт итераторы и лямбды, что приводит к аллокациям).
6. Асинхронная загрузка сцен
Если в будущем появятся дополнительные сцены (меню, загрузка), используйте SceneManager.LoadSceneAsync с отображением прогресса, чтобы избевать фризов.
Заключение
Текущая архитектура проекта уже включает несколько важных оптимизаций (пулы, кэширование, weak‑ссылки, NavMesh). Однако всегда есть куда расти. Регулярное профилирование и следование рекомендациям выше позволят поддерживать высокий FPS даже при увеличении сложности игры.
Сборка и развёртывание
В этом разделе описаны шаги по сборке проекта CollectorBots для различных платформ, а также конфигурация mdBook для генерации документации.
Требования
Программное обеспечение
- Unity 2021.3+ (рекомендуется LTS версия). Проверено на Unity 2021.3.15f1.
- Git (для клонирования репозитория, опционально).
- Visual Studio 2019/2022 или JetBrains Rider (для редактирования C# кода, не обязательно для сборки).
- mdBook (только для сборки документации, опционально).
Аппаратные требования
- ОЗУ: минимум 8 ГБ (рекомендуется 16 ГБ).
- Процессор: любой современный многоядерный CPU.
- Видеокарта: с поддержкой DirectX 11 или OpenGL 4.5.
- Дисковое пространство: ~2 ГБ для проекта + место под сборки.
Инструкции по сборке
1. Подготовка проекта
Убедитесь, что проект открывается в Unity Editor без ошибок:
- Клонируйте репозиторий (или откройте существующую папку
i:/Code_Source/UnityProjects/CollectorBots). - Запустите Unity Hub, добавьте проект, выберите версию Unity 2021.3+.
- Откройте проект. Дождитесь завершения импорта ассетов (может занять несколько минут).
2. Настройка Build Settings
- В Unity Editor перейдите в File → Build Settings (или нажмите
Ctrl+Shift+B). - Убедитесь, что в списке Scenes In Build присутствует сцена
Assets/Scenes/SampleScene.unity. Если её нет, перетащите её из окна Project в список. - Выберите целевую платформу (по умолчанию PC, Mac & Linux Standalone). Для Windows выберите Target Platform = Windows, Architecture = x86_64.
- Нажмите Player Settings для дополнительных настроек.
3. Player Settings
В открывшемся окне Project Settings → Player настройте следующие параметры:
- Company Name: введите название компании (например, "CollectorBots Team").
- Product Name: "CollectorBots".
- Version: укажите версию (например, 1.0.0).
- Default Icon: установите иконку приложения (опционально).
- Resolution and Presentation:
- Fullscreen Mode: Windowed (или Fullscreen Window).
- Resolution: 1920x1080 (рекомендуется).
- Other Settings:
- Color Space: Linear (для лучшего качества графики).
- Auto Graphics API: включено.
- Graphics APIs: Direct3D11 (Windows), OpenGL (Linux), Metal (macOS).
- Scripting Backend: Mono (или IL2CPP для лучшей производительности).
- Api Compatibility Level: .NET Standard 2.0 (или .NET 4.x).
- Publishing Settings (для Windows):
- Create Visual Studio Solution File: можно включить, если планируется дальнейшая отладка.
4. Сборка
- Вернитесь в окно Build Settings.
- Нажмите Build.
- Выберите папку для сохранения сборки (например,
Builds/Windows). - Дождитесь завершения процесса. В консоли Unity будут отображаться этапы компиляции и сборки.
После успешной сборки в указанной папке появятся:
CollectorBots.exe— исполняемый файл.CollectorBots_Data/— папка с ресурсами.MonoBleedingEdge/(илиUnityPlayer.dll) — вспомогательные библиотеки.
5. Запуск собранной версии
Дважды кликните на CollectorBots.exe. Игра должна запуститься в отдельном окне.
Целевые платформы
PC/Windows (основная)
- Целевая архитектура: x86_64 (64‑битная).
- Минимальная версия ОС: Windows 10.
- Рекомендуемые настройки: DirectX 11, разрешение 1920×1080.
MacOS
- Целевая архитектура: Apple Silicon (ARM64) или Intel (x64).
- Минимальная версия: macOS 10.15 Catalina.
- Сборка: в Build Settings выберите платформу Mac OS X и настройте Architecture соответственно.
Linux
- Целевая архитектура: x86_64.
- Минимальные требования: дистрибутив с поддержкой OpenGL 4.5.
- Сборка: выберите платформу Linux и настройте Architecture = x86_64.
Мобильные платформы (Android/iOS)
На данный момент проект не адаптирован для мобильных устройств. Для портирования потребуется:
- Переработать UI под touch‑ввод.
- Оптимизировать графику для слабых GPU.
- Настроить управление камерой (жесты вместо мыши).
Конфигурация book.toml для mdBook
Документация проекта создана с помощью mdBook. Конфигурационный файл book.toml находится в корне проекта.
Содержимое book.toml
[book]
title = "Collector Bots"
authors = ["Dmitry Rysev"]
language = "en"
[output.html]
default-theme = "light"
preferred-dark-theme = "navy"
Сборка документации
- Установите mdBook (если ещё не установлен). Инструкции: https://rust-lang.github.io/mdBook/guide/installation.html.
- Откройте терминал в корне проекта (
i:/Code_Source/UnityProjects/CollectorBots). - Выполните команду:
Это создаст папкуmdbook buildbook/с HTML‑версией документации. - Для локального просмотра запустите сервер:
Документация откроется в браузере по адресуmdbook serve --openhttp://localhost:3000.
Структура документации
- Исходные файлы: находятся в папке
src/(все созданные в этом задании .md файлы). - Оглавление: определяется файлом
src/SUMMARY.md. - Генерация: mdBook преобразует Markdown в HTML, сохраняя навигацию и подсветку кода.
Развёртывание
Распространение игры
- Архивация: упакуйте всю папку сборки (включая
CollectorBots.exeиCollectorBots_Data) в ZIP‑архив. - Дистрибуция: разместите архив на платформе распространения (Steam, itch.io, собственный сайт).
- Установка: пользователь должен распаковать архив в любую папку и запустить исполняемый файл.
Обновления
Для выпуска обновлений рекомендуется использовать систему патчей (например, через Unity Cloud Build или Incremental Builds). Однако в текущей версии механизм обновлений не реализован.
Системные требования для конечного пользователя
Укажите в описании игры следующие минимальные требования:
- ОС: Windows 10 64‑bit / macOS 10.15 / Ubuntu 20.04.
- Процессор: Intel Core i5‑2500 или AMD equivalent.
- ОЗУ: 4 ГБ.
- Видеокарта: NVIDIA GeForce GTX 660 или AMD Radeon HD 7870 (2 ГБ VRAM).
- DirectX: версия 11.
- Место на диске: 500 МБ.
Отладка собранной версии
Development Build
При сборке включите опцию Development Build в окне Build Settings. Это позволит:
- Подключать Profiler к работающей игре.
- Видеть Console логи (открывается клавишей
Shift + Ctrl + Cв Windows). - Использовать Debug‑версию скриптов с возможностью установки breakpoints.
Логи
Логи игры записываются в файл, расположение которого зависит от платформы:
- Windows:
%APPDATA%/../LocalLow/<CompanyName>/<ProductName>/output_log.txt - macOS:
~/Library/Logs/<CompanyName>/<ProductName>/Player.log - Linux:
~/.config/unity3d/<CompanyName>/<ProductName>/Player.log
Эти логи полезны для диагностики проблем у пользователей.
Заключение
Сборка проекта CollectorBots стандартна для Unity‑проектов. Следуя описанным шагам, вы получите работающий исполняемый файл для выбранной платформы. Документация, собранная через mdBook, может быть размещена на GitHub Pages или любом другом хостинге для удобства команды разработчиков.
Заключение
CollectorBots — это полноценный прототип стратегической игры в реальном времени, демонстрирующий чистую архитектуру, модульность и использование современных технологий Unity. Проект успешно реализует базовый геймплей: автоматический сбор ресурсов, управление рабочими, строительство новых баз и интуитивный пользовательский интерфейс.
Что реализовано хорошо
Чистая архитектура
- Слоистая структура: код разделён на Infrastructure, Gameplay и Common, что обеспечивает низкую связанность и высокую сопровождаемость.
- Интерфейсы и внедрение зависимостей: ключевые сервисы (
IEventAggregator,IAssetProvider,IInputReader) абстрагированы, что позволяет легко заменять реализации. - Паттерны проектирования: активно используются Observer (события), Factory (пулы объектов), MVP (UI), Component‑Based (Unity).
Собственная система событий
IntelligentEventAggregator предоставляет мощный механизм подписки и публикации событий с поддержкой фильтров, условий и weak‑ссылок. Это позволяет системам взаимодействовать без прямых зависимостей и минимизирует утечки памяти.
Оптимизация производительности
- ObjectPool для повторного использования префабов.
- Кэширование ресурсов в
AssetProvider. - NavMesh для эффективной навигации рабочих.
- WeakReference в системе событий.
Гибкая конфигурация
Все балансовые параметры вынесены в ScriptableObject (BaseStructureConfig, BuilderConfig, ResourceSpawnerConfig), что позволяет настраивать игру без перекомпиляции кода.
Пользовательский интерфейс
UI построен по паттерну MVP с реактивными обновлениями через события. Элементы интерфейса (StorageView, ResourceManagementView, BaseStructurePanelGroup) интуитивно понятны и информативны.
Что можно улучшить
Система сохранения
Текущая версия не сохраняет прогресс между сессиями. Реализация сохранения (через PlayerPrefs, JSON‑сериализацию или бинарные файлы) значительно повысила бы ценность игры.
Локализация
Все тексты захардкожены на английском (или русском). Добавление поддержки нескольких языков потребует интеграции системы локализации (например, I2 Localization или Unity Localization Package).
Звуковое сопровождение
В игре полностью отсутствуют звуковые эффекты и фоновая музыка. Добавление звуков сбора, движения, постройки и ambient‑музыки улучшит immersion.
Расширенный UI
Можно добавить:
- Панель статистики (сколько ресурсов собрано, сколько рабочих построено).
- Меню настроек (громкость, качество графики, управление).
- Экран паузы с возможностью сохранения/загрузки.
- Подсказки и обучение для новых игроков.
Балансировка и контент
- Больше типов ресурсов (золото, кристаллы, энергия).
- Улучшения баз (апгрейды, увеличивающие эффективность).
- Враги или препятствия (например, дикие животные, которые мешают рабочим).
- Квесты/цели (например, «построй 5 баз», «собери 100 железа»).
Возможные направления развития
1. Мультиплеер
Превратить игру в кооперативную или соревновательную стратегию, где несколько игроков управляют своими колониями на одной карте, торгуют ресурсами или воюют.
2. Кампания и сюжет
Добавить сюжетную кампанию с миссиями, персонажами и диалогами. Это потребует создания новых сцен, скриптованных событий и системы диалогов.
3. Моддинг
Предоставить игрокам инструменты для создания собственных карт, ресурсов, конфигураций. Для этого можно вынести данные в JSON/XML и добавить редактор карт внутри игры.
4. Платформер для мобильных устройств
Адаптировать управление под touch‑экран, оптимизировать графику для слабых устройств и выпустить игру на iOS/Android.
5. Интеграция с Steam
Добавить достижения (Steam Achievements), облачные сохранения, торговую площадку (Steam Workshop) для модов.
Технический долг
Миграция на Addressable Assets
Сейчас ресурсы загружаются через Resources.Load, что увеличивает размер сборки и не позволяет выгружать неиспользуемые ассеты. Переход на Addressable Assets решит эти проблемы.
Unit‑тесты
Проект не покрыт автоматическими тестами. Добавление юнит‑тестов для ключевых систем (события, пулы, логика задач) повысит надёжность и упростит рефакторинг.
Рефакторинг некоторых скриптов
Некоторые файлы превышают 200 строк (правило проекта). Их можно разбить на более мелкие классы с единственной ответственностью.
Заключительные слова
CollectorBots — отличный пример того, как даже небольшой проект может быть построен с учётом лучших практик разработки. Чистая архитектура, модульность и внимание к производительности закладывают прочный фундамент для будущего расширения.
Документация, которую вы сейчас читаете, охватывает все аспекты проекта: от высокоуровневой архитектуры до инструкций по сборке. Она поможет новым разработчикам быстро войти в проект, а текущим — эффективно поддерживать и развивать его.
Удачи в дальнейшей разработке! Пусть ваши роботы‑рабочие собирают ресурсы, а базы растут как на дрожжах.