Фреймворк для игр на Unity. Он задаёт точку входа, порядок инициализации, жизненный цикл компонентов, модель данных и способ, которым игра его расширяет.
- игра запускается из bootstrap-сцены; порядок инициализации задают
MethodHookAttributeи этапы, а не вашStart; - компоненты наследуют
PRMonoBehaviourи получаютPRUpdate, паузу, игровое время и готовность черезReadySignal; обычныйMonoBehaviourвсего этого не получает; - поведение расширяется подключением к ядру, а не правкой ядра: хуки урона, провайдеры с автопоиском по атрибутам, фабрики окон, трекеры сущностей;
- данные игры описаны его моделью: каталоги, определения предметов, награды, проекты.
Warning
Проект находится в активной разработке. Публичные API, структура каталогов и процесс инициализации могут изменяться. Перед обновлением фиксируйте используемый commit.
| Система | Назначение |
|---|---|
PRUnitySDK |
Центральная точка доступа к настройкам, менеджерам, трекерам и сервисам |
Bootstrap |
Единая точка запуска и последовательная инициализация фреймворка |
PRMonoBehaviour |
Базовый Unity-компонент с PR lifecycle, поддержкой паузы и физическими callback'ами |
EventBus |
Глобальная типизированная шина событий с защитой от повторной подписки |
PauseManager |
Раздельное управление общей, логической, музыкальной и другими видами паузы |
PRTime / PRTimeScale |
Игровое и реальное время с учётом логической паузы и пользовательских time scale |
PRCoroutineBase |
Обёртки над Unity-корутинами с единым запуском и остановкой |
BackgroundTasks |
Работа по расписанию вне сцены и наблюдение за значениями, которые сами о себе не сообщают |
HookSystem |
Последовательная обработка изменяемых и отменяемых событий |
FlagsSystem |
Совместное управление состояниями объекта из нескольких источников |
Entity / Items / Wallet / Reward |
Базовые модели сущностей, предметов, ресурсов и наград |
GameRules |
Глобальные ограничения характеристик поверх персональных модификаторов |
Conditions |
Настраиваемые правила «когда это разрешено»: ассетом или прямо в инспекторе |
GameDataStorage |
Сохранение прогресса и состояния объектов сцены между запусками |
| State / Damage | Переиспользуемые игровые модули |
| Quality / Localization / Logging | Качество предметов, переводы и структурированное логирование |
Как части связаны между собой. Стрелка — «зависит от».
graph TD
Boot["Bootstrap<br/>единственная точка входа"]
Facade["PRUnitySDK<br/>facade, ServiceResolver"]
Hooks["HookSystem<br/>MethodHook и стадии"]
Boot --> Facade
Facade --> Hooks
subgraph BASE["Базис"]
Models["Models<br/>Enumeration, ProjectData"]
Utils["#Utils, #Extensions, Debug"]
Attrs["@Attributes"]
end
subgraph LIFE["Жизненный цикл и время"]
Mono["PRMonoBehaviour"]
Pause["PauseSystem"]
Time["PRTime, PRTimeScale"]
Coro["Coroutines, Yields"]
Bg["BackgroundTasks"]
end
subgraph DATA["Данные"]
Storage["GameDataStorage<br/>ProjectData, ObjectState"]
Db["#Database<br/>PRSDKDatabase, PRSDKSettings"]
Paths["ResourcePaths"]
end
subgraph WORLD["Модель мира"]
Entity["@Entity<br/>EntityBase, Metadata,<br/>Stats, Player"]
Items["Items"]
Wallet["Wallet"]
Reward["Reward"]
Rules["GameRules"]
Props["PropertyContainer"]
Flags["FlagsSystem"]
Cond["@Conditions<br/>ICondition, ConditionBase"]
end
subgraph RUNTIME["Рантайм-инфраструктура"]
Managers["@Managers<br/>PRManagerContainer"]
Trackers["Trackers<br/>Entities, Players, Cameras, Windows"]
Factories["Factories, ObjectPool"]
Bus["@Events<br/>EventBus"]
Bots["Bots"]
Input["Input<br/>InputTranslator, PlayerInputState"]
end
subgraph UIL["Интерфейс"]
Wnd["#UI<br/>MonoWindow, Notifiers,<br/>PRWindowsContainer"]
end
subgraph MODS["Модули"]
Damage["@DamageSystem"]
HitBox["HitBox"]
Cam["Camera"]
Tr["Translate"]
Tween["DOTweenEffects"]
end
Editor["Core/Editor<br/>окна Database и PRUnitySDKDebug"]
Mono --> Pause
Mono --> Time
Mono --> Bus
Bg --> Mono
Entity --> Models
Entity --> Mono
Entity --> Factories
Entity --> Rules
Entity --> Input
Items --> Models
Items --> Tr
Props --> Models
Flags --> Models
Rules --> Models
Reward --> Items
Wallet --> Models
Cond --> Items
Cond --> Wallet
Managers --> Storage
Managers --> Items
Trackers --> Entity
Trackers --> Wnd
Bus --> Items
Bots --> Bus
Wnd --> Mono
Wnd --> Pause
Cam --> Trackers
Damage --> Entity
Damage --> Hooks
Damage --> Items
HitBox --> Damage
Tween --> Time
Editor --> Entity
Editor --> Db
Editor --> Wnd
Editor --> Bg
Игра к фреймворку не подмешивается: зависимость всегда направлена от игры к нему. Как именно к нему подключаться — в разделе «Какой механизм расширения выбрать».
| Папка | Что в ней |
|---|---|
Assets/PRUnitySDK |
сам фреймворк: общее для любой игры |
Assets/PRUnitySDKPrivate |
проектный слой: механики конкретной игры, надстроенные над фреймворком |
Assets/PRUnityData |
данные игры: каталоги, настройки, проекты |
Какая из игр собирается сейчас, указывает PRSDKProject — окно PRUnitySDK/Game/Project. Подробности — в PRUnityData/README.md.
Опыт и уровни живут в проектном слое: XPManager, фоновое начисление и бустеры опыта — в PRUnitySDKPrivate/Modules/@ProgressionModule.
- Unity 2023.2 или новее (TextMeshPro из
com.unity.ugui2.0); - Newtonsoft Json for Unity;
- DOTween для tween-расширений и модуля
DOTweenEffects.
Некоторые интеграции имеют дополнительные зависимости:
YG2.Integrationтребует YG2 Plugin и соответствующие модули YG2.
Репозиторий пока не оформлен как UPM-пакет: в корне отсутствует package.json.
Размещайте содержимое репозитория внутри Assets/PRUnitySDK.
Через Git submodule:
git submodule add https://github.com/prethink/PRUnitySDK.git Assets/PRUnitySDK
git submodule update --init --recursiveЛибо скачайте репозиторий и скопируйте его содержимое в:
Assets/PRUnitySDK
После импорта убедитесь, что Unity завершил компиляцию без ошибок и установлены перечисленные выше зависимости.
- Создайте отдельную сцену и добавьте её первой в
File → Build Settings. - Поместите в неё GameObject с компонентом
Bootstrap. - Добавьте основную игровую сцену следующей, с build index
1.
После инициализации Bootstrap открывает Settings.Bootstrap.GameSceneIndex (по умолчанию 1).
В Unity Editor класс PlayFromBootstrap сначала запускает сцену с индексом 0.
Если включён Start From Editor Scene, после сборки SDK открывается сцена, которая была
активной в редакторе перед Play. В билде всегда используется Game Scene Index.
Important
Если проект использует другую схему загрузки сцен, измените обработчик
Bootstrap.OnInitialized() или переопределите bootstrap-процесс через
OverrideBootstrapAttribute.
Экран показывается с начала сборки SDK до первого кадра игровой сцены. Если он выключен,
SDK собирается одним вызовом, а сцена меняется через SceneChanger с затемнением.
На экране: подпись с пояснением, вращающийся значок и полоса прогресса. Первая половина полосы — сборка SDK, дальше загрузка сцены, в конце её включение и первый кадр. До готовности SDK подписи берутся по коду языка площадки, после — живые.
Настройка. Вид экрана лежит в настройках проекта (PRUnitySDK.Settings.LoadingScreen,
LoadingScreenSettings) и правится в окне PRUnitySDK → Windows → Loading Screen:
| Раздел | Что задаётся |
|---|---|
| Экран загрузки | показывать ли его вообще |
| Фон | цвет, картинка, способ вписать её в экран (растянуть, закрыть целиком, вписать), оттенок |
| Текст | шрифт; заголовок и пояснение на трёх языках, их цвет и размер, показывать ли каждый |
| Полоса прогресса | показывать ли, размер, цвета, картинки подложки и заполнения |
| Значок | показывать ли, картинка, размер, скорость вращения |
Язык, на котором свой текст не вписан, показывает стандартный (LoadingScreenLabels: «Загрузка...»
и «Подготавливаем игру. Это может занять несколько секунд.»), поэтому заполнять все три поля не обязательно.
Справа в окне — превью: тот же экран на выбранном языке и с выбранной долей прогресса.
Собирается методом BootstrapLoadingScreen.Build во временной сцене, открытую сцену не трогает.
Префаба нет: экран собирается кодом из настроек. Разметка (значок, заголовок, пояснение, полоса — сверху вниз по центру) задана в коде под холст 1920×1080.
Сборка SDK порциями. С экраном загрузки Bootstrap проходит шаги PRUnitySDK.InitializeSDKSteps
порциями (по умолчанию 200 мс) и отдаёт кадр между ними. Порядок шагов тот же, что у
PRUnitySDK.InitializeSDK(). SDK становится готовым только на последнем шаге: до него общий цикл
обновления не идёт, а подписчики ReadySignal ничего не получают. Выключается и настраивается
в настройках проекта — см. ниже.
Между шагами проходят кадры: у уже созданного менеджера работает собственный Update, а события
площадки (фокус, пауза) могут прийти при полусобранном SDK. Код, которому нужен готовый SDK,
обязан ждать ReadySignal, а не рассчитывать, что соседи уже созданы.
Значок в WebGL. В WebGL значок рисует и крутит страница (Plugins/WebGL/BootstrapSpinner.jslib).
Экран отдаёт ей спрайт и его место, а свой значок прячет. Полоса и текст остаются в Unity
и замирают вместе с ней.
Всё, что касается запуска, лежит в настройках проекта — PRUnitySDK.Settings.Bootstrap
(BootstrapSettings). На объектах загрузочной сцены настроек нет.
| Поле | По умолчанию | Что задаёт |
|---|---|---|
Game Scene Index |
1 | индекс игровой сцены в Build Settings |
Start From Editor Scene |
нет | только в редакторе: после Bootstrap открыть сцену, активную перед Play |
Spread Initialization |
да | собирать SDK порциями с кадрами между ними |
Frame Budget Seconds |
0,2 | сколько секунд сборки идёт подряд, прежде чем отдать кадр |
Probe Enabled |
да | замерять стадии запуска (только в отладочном режиме проекта) |
Probe On Screen |
да | показывать цифры на экране, а не только в логе |
Probe Background Color |
синий | фон загрузочной сцены при включённой диагностике |
Probe Summary Seconds |
20 | сколько держать итог в углу после загрузки |
Start From Editor Scene работает и для сохранённых сцен, отключённых в Build Settings
или не добавленных туда. Путь запоминается перед Play и сохраняется через перезагрузку домена.
Если открыта сама bootstrap-сцена или сцена ещё не сохранена, используется Game Scene Index,
а в Console появляется предупреждение. При нескольких открытых сценах запускается активная.
После выхода из Play Unity возвращает редакторный набор сцен.
Загрузчик создаёт зонд BootstrapProbe, если он включён в настройках запуска и проект в отладочном
режиме. Ставить его на сцену не нужно:
- фон сцены становится цветным (
Background Color): чёрный экран значит, что до сцены дело ещё не дошло; - вверху пишется стадия загрузчика (
Bootstrap.Stage), секунды в ней и счётчик кадров. Счётчик стоит — главный поток занят; идёт — игра ждёт чего-то снаружи; - после загрузки игровой сцены в левом верхнем углу
Summary Secondsсекунд висит итог, он же уходит в лог с пометкой[BootstrapProbe].
| Строка | Что в неё входит |
|---|---|
engine |
от запуска движка до первой сцены |
1 platform |
ожидание данных площадки; без площадки — ноль |
2 sdk |
сборка SDK: менеджеры, база, сохранение |
3 scene |
загрузка игровой сцены |
first frame |
от загрузки игровой сцены до её первого кадра |
engine frame 1 at |
когда движок отдал первый кадр: до этого на экране нет ничего от игры |
sdk steps N, work X, slowest: |
число шагов сборки SDK, их чистое время без отданных кадров и восемь самых долгих (PRUnitySDK.InitializationSteps) |
При сборке порциями стадия 2 sdk длиннее строки work: в неё входят и кадры между порциями.
Bootstrap сам записывает время стадий в момент перехода (Bootstrap.StageStartTimes).
Это инструмент проверки, а не экран загрузки: текст служебный и не переводится. Работает он только
в отладочном режиме проекта — PRUnitySDK.Settings.Project.IsDebug, то есть Release Type = Debug
в настройках проекта. В релизном режиме зонда нет вовсе: ни надписей, ни лога.
Перед выпуском достаточно переключить Release Type.
using UnityEngine;
public class RotatingObject : PRMonoBehaviour
{
[SerializeField] private float speed = 90f;
protected override void PRUpdate()
{
transform.Rotate(Vector3.up, speed * PRTime.Instance.GameDeltaTime);
}
}PRUpdate, PRLateUpdate и PRFixedUpdate не выполняются во время логической паузы.
Для временных расчётов используйте PRTime, если система должна следовать правилам
паузы фреймворка.
Физические callback'и объявлены в базовом классе, поэтому Unity вызывает их у любого наследника. Ненужные отключаются на уровне типа:
[DisableMethods("OnTriggerStay", "OnCollisionStay")]
public class Pickup : PRMonoBehaviour { }Атрибут действует только на физические callback'и и OnPauseStateChanged, имена
задаются строками, а у наследника список заменяется целиком, а не дополняется —
подробности в PRMonoBehaviour.
Там же чек-лист «метод не вызывается — что проверить».
Событие описывается интерфейсом:
public interface ICoinsChanged : IGlobalSubscriber
{
void OnCoinsChanged(int value);
}Подписчик реализует интерфейс и регистрируется в EventBus:
public class CoinsView : MonoBehaviour, ICoinsChanged
{
private void OnEnable() => EventBus.Subscribe(this);
private void OnDisable() => EventBus.Unsubscribe(this);
public void OnCoinsChanged(int value)
{
Debug.Log($"Coins: {value}");
}
}Вызов события:
EventBus.RaiseEvent<ICoinsChanged>(listener => listener.OnCoinsChanged(10));Компоненты, наследуемые от PRMonoBehaviour, автоматически регистрируются в
EventBus при стандартной инициализации и снимаются с регистрации при уничтожении.
PRUnitySDK.PauseManager.SetLogicPaused(true, this);
PRUnitySDK.PauseManager.SetLogicPaused(false, this);Состояние доступно через:
bool isPaused = PRUnitySDK.PauseManager.IsLogicPaused;var delay = new WaitGameSecondsCoroutine(
callback: () => Debug.Log("Completed"),
duration: 2f,
instance: this);
delay.Execute();Если MonoBehaviour не передан, корутина запускается на глобальном
PRMonoBehaviourHost. Для повторного запуска одного объекта корутины используйте
StopAndExecute(), а для остановки — Stop().
Основная последовательность запуска:
Bootstrap.Awake()вызываетPRUnitySDK.InitializeSDK().- Инициализируются правила, конвертеры, singleton-сервисы и фабрики.
- Через method hooks подключаются дополнительные модули.
- Инициализируются контейнеры менеджеров и окон.
- Устанавливается
PRUnitySDK.IsInitialized. - Публикуется
ISDKEvents.OnInitialized()и устанавливаетсяReadySignal.
Повторный параллельный запуск блокируется флагом PRUnitySDK.IsStartInitialize.
Готовность можно проверить через PRUnitySDK.IsInitialized или
PRUnitySDK.ReadySignal.
Во фреймворке шесть способов вклиниться в чужое поведение. Они не взаимозаменяемы: каждый решает свою задачу. Выбор определяется одним вопросом — что вам нужно сделать с чужим кодом.
| Нужно | Механизм | Где описан |
|---|---|---|
| Выполнить свой код в определённый момент | MethodHookAttribute |
Attributes |
| Узнать, что что-то уже произошло | EventBus |
EventBus |
| Изменить или запретить действие до того, как оно случилось | HookSystem |
HookSystem |
| Согласовать решение, на которое влияют несколько компонентов | FlagsSystem |
FlagsSystem |
| Собрать данные из всех модулей в один список | InvokePartialAttribute |
Attributes |
| Подменить стандартную реализацию сервиса | OverridePropertyAttribute |
Attributes |
| Выполнять работу по расписанию вне сцены | BackgroundTask |
BackgroundTasks |
| Узнать об изменении значения, которое само о себе не сообщает | WatcherTask<T> |
BackgroundTasks |
MethodHook — «выполни это на такой-то стадии». Инициализация модуля, регистрация
фабрик, клонирование данных. Порядок задаёт число, результат не собирается.
[MethodHook(MethodHookStage.SDK, order: 20)]
private static void InitializeInventory() { }EventBus — «сообщи, что уже случилось». Отправитель не ждёт ответа и не знает
подписчиков. Обновить UI, проиграть звук, записать метрику.
public class CoinsView : MonoBehaviour, IResourceValueChangedEvent { }HookSystem — «дай вмешаться до того, как случится». В отличие от EventBus,
обработчик получает изменяемый контекст: может уменьшить урон, заменить награду или
отменить действие. Обработчики идут цепочкой в порядке Order.
public class DamageResistanceComponent : PRMonoBehaviour, IHookListener<DamageHookEvent> { }FlagsSystem — «можно ли сейчас?». Когда на один вопрос («можно ли прыгать») влияют
несколько независимых источников — оглушение, катсцена, туториал. Каждый добавляет своё
влияние, система сводит их к ответу.
flagResolver.Add(PlayerFlags.CanJump, this, false);InvokePartial — «соберите со всех». Каждый модуль возвращает свой кусок, вызывающий
получает объединённый результат.
IEnumerable<Modifier> modifiers = this.CollectPartialResult<Modifier>(context);OverrideProperty — «замени реализацию». Интеграция подставляет свой сервис вместо
стандартного до применения fallback, например серверное время платформы вместо локального
или облачное хранилище вместо PlayerPrefs.
[OverrideProperty(typeof(IServerTime), order: -100)]
private static void UsePlatformServerTime() => ServerTime = new PlatformServerTime();BackgroundTask — «делай это раз в N секунд». Работа без владельца на сцене, которая
должна пережить её смену: автосохранение, офлайн-доход, отложенная аналитика. Задача сама
переживает паузу так, как ей нужно, и умеет пропускать запуск, пока условия не готовы.
[AutoBackgroundTask]
public class PlaytimeTrackerTask : BackgroundTask
{
public override Enumeration Key => BackgroundTaskKeyEnumerations.PlaytimeTracker;
public override float RepeatSeconds => 60f;
protected override void OnExecute() { }
}WatcherTask<T> — «сообщи, когда значение изменится». В отличие от EventBus, источник
ничего не отправляет: смену суток, состояние сети или баланс на сервере можно узнать только
опросом. Наблюдатель опрашивает по расписанию и поднимает событие только в момент изменения.
EventBusтам, где нуженHookSystem. Событие уведомляет уже после того, как решение принято, и повлиять на него нельзя.HookSystemтам, где хватило быEventBus. Перехват делает поток неочевидным: обработчик может незаметно отменить действие.- Свой флаг вместо
FlagsSystem. Булево поле «нельзя прыгать» ломается при двух источниках запрета: снявший один разрешает, хотя второй ещё против. MethodHookдля реакции на игровое событие. Хуки стадий вызываются там, где код явно их запускает; для игровых событий естьEventBus.partial voidкак точка расширения. У partial-метода ровно одна реализация на класс; вторая часть получит ошибку компиляцииCS0757. Если участников может быть несколько, используйтеMethodHookилиInvokePartial.- Своя корутина вместо
BackgroundTask. Корутина требует объекта-хозяина, теряется при смене сцены и не даёт ни счётчиков, ни защиты от череды ошибок. - Опрос в
UpdateвместоWatcherTask<T>. Проверять раз в кадр то, что меняется раз в минуту, — лишняя работа; наблюдатель опрашивает по расписанию и сообщает только об изменении.
Отдельно стоят механизмы, которые не перехватывают чужое поведение, а дополняют данные. Им не нужен ни один из шести способов выше:
| Что добавить | Как |
|---|---|
| Поле в сохранение | partial class ProjectData + [MethodHook(Cloning)] |
| Новое окно | partial class MonoWindowKeyEnumerations + partial class PRWindowsContainer |
| Фоновая задача | наследник BackgroundTask + [AutoBackgroundTask] + ключ partial-частью BackgroundTaskKeyEnumerations |
| Путь к ресурсам модуля | partial class ResourcePaths |
| Новый ключ, тип, слой | наследник EnumerationProviderBase или partial-часть существующего |
Правило простое: общие файлы фреймворка править не нужно — почти всё расширяется partial-частью
рядом с модулем.
PRUnitySDK/
├── Core/ # Ядро, сервисы, базовые модели и инструменты
├── Core.Data/ # Данные ядра отдельно от логики: GameRules, данные сущностей
├── Modules/ # Опциональные игровые модули
├── Examples/ # Примеры использования
├── Resources/ # Runtime-ресурсы фреймворка (данные игры — в PRUnityData)
├── Utils/ # Дополнительные утилиты
├── Plugins/ # Сторонние плагины (SerializedCollections)
└── *.Integration/ # Интеграции площадок: YG2, GamePush и другие
- SDK — facade, инициализация и service resolver
- ResourcePaths — канонические пути к runtime-ресурсам и правила расширения
- Окна Database и Settings — секции с описанием и сбросом, поиск, заполнение каталогов, валидация definitions и наборы состава базы для разных игр
- Attributes — method hooks, переопределение сервисов и расширение Inspector
- Actions — переиспользуемые действия с единым контрактом проверки и выполнения
- Conditions — переиспользуемые правила «когда это разрешено». Действие совершает поступок, условие только спрашивает. Оттуда же берут подпись для игрока: чего не хватает, чтобы условие выполнилось
- EventBus — типизированная шина уведомлений о произошедшем
- HookSystem — перехват действий с возможностью изменить или запретить их
- FlagsSystem — согласование независимых решений компонентов без прямых зависимостей
- PRMonoBehaviour — базовый компонент с lifecycle-хуками, учитывающими логическую паузу
- Coroutines — обёртки над корутинами с запуском, перезапуском и остановкой
- Yields —
CustomYieldInstruction, останавливающие корутины на логической паузе - PauseSystem — раздельные причины паузы и мониторы аниматоров и физических тел
- PRTime — источник времени: реальное, игровое и учёт паузы
- PRTimeScale — слои скорости времени, модификаторы с владельцами и драйверы для анимации и физики
- BackgroundTasks — фоновые задачи по расписанию и наблюдение за значениями
- Обзор менеджеров — доступ, жизненный цикл, порядок и расширение контейнера
- GameManager — загрузка и сохранение
ProjectData/GameSettings, autosave и готовность данных - ProjectPropertiesManager — свойства
long,float,DateTime,stringиbool - ResourceManager — игровые ресурсы, баланс, списание и события изменений
- OpenedItemsManager — открытые предметы и количество в
ProjectData - SelectedItemsManager — что из имеющегося надето у каждого локального игрока
- ReservedItemsManager — предметы, которые выдаются не покупкой: награды, подарки, кейсы
- PRManagerContainer — hook-порядок создания runtime-менеджеров
- SoundManager — музыка, UI-звуки, позиционные эффекты и наборы
AudioSet - CursorManager — запросы Show/Hide курсора с приоритетом последнего обращения
- Statistics — числа об игроке за всё время: заходы, время в игре, полученные ресурсы
- Entity — сущности игрового мира: идентификаторы, описание, реестр и пул
- EntityStats — характеристики сущности: базовые значения, персональные модификаторы и расчёт итоговых
- Ввод — состояние ввода игрока или бота и его маршрутизация по
InputGuid - Фабрики MonoBehaviour — обычные prefab, singleton-компоненты, MonoWindow и Notifier
- Trackers — игроки, сущности, камеры и UI-реестры
- MonoWindow — модальные runtime-окна, фабрики и параметры открытия
- UIButtonDefinition — описание экранной кнопки: иконка, подпись, действие, условие показа
- Звук нажатия — один общий щелчок на всё, что нажимают в интерфейсе
- Reward — модели наград, экземплярный сервис выдачи и проектные обработчики
- Purchase — контракт покупок за реальные деньги
IPurchaseService - Metrics — отправка событий метрики через адаптер площадки
- RemoteFlags — значения, которые площадка меняет без пересборки: A/B-тесты, цены
- Review — оценка игры на площадке (
IReviewService) - Wallet — баланс, начисление и списание валюты поверх
ResourceManager - Enumeration — расширяемый строковый идентификатор вместо
enum - Services —
NameServiceи сервис имени текущего игрока - Локализация — переводы в базе, ассетах и на префабах, живой перевод чисел, сбор и обмен через CSV
- Utils — мелкие помощники: логирование, ресурсы, работа с материалами
- GameDataStorage — storage-контракты и универсальный
ProjectDataMap - Состояние объекта сцены —
SaveableObjectState: объект появляется таким, каким его оставили - Extensions — extension-методы общего назначения для Unity и типов SDK
- Quality — качество предметов: уровни редкости и их отображение
- Utils — вспомогательные классы: время, отложенные вызовы, имена
- Proxies — переадресация Unity-callback'ов с дочерних объектов родительским компонентам
- Property modifiers — динамические характеристики, персональные модификаторы и
GameRules - GameRules — глобальные границы характеристик, применяемые последними
- Reflection — список типов, которые SDK находит по контракту, вместо перебора сборки при запуске
- Modules — оглавление модулей публичного SDK
- ModuleSystem — модули и интеграции, которые вырезаются из сборки, окно PRUnitySDK → Модули
- DamageSystem — создание, модификация и применение урона через хуки; правила урона игры (
DamageRules) из настроек проекта, со сцены и из кода - GameSessions — сессия карты и раунды с режимами и правилами; одиночная игра и локальный мультиплеер
- HitBox — связь физических коллайдеров с
DamageSystem - DOTweenEffects — связь DOTween с логической паузой и
PRTimeScale - YG2 Integration — облачные сохранения, реклама и платформенные возможности Яндекс Игр
- GamePush Integration — те же контракты на плагине GamePush
- Фреймворк распространяется как Unity Assets, а не как UPM-пакет.
- Автоматический installer пока не создаёт настройки, слои, теги и prefab'ы.
- Bootstrap по умолчанию предполагает сцены с индексами
0и1. - Часть каталогов и API всё ещё находится в процессе переноса и рефакторинга.
- Не все модули имеют отдельную документацию и тестовое покрытие.
- Версии нет: понять, на какой сборке фреймворка сделана игра, пока негде.
- Имя
PRUnitySDKзашито в путиResources, пункты меню и сериализованные ассеты, поэтому переименование требует миграции.