NeoxiderPages — это sample-модуль навигации по страницам/экранам поверх Unity UI.
Для корректной работы требуется DOTween Pro (и DOTween).
После импорта sample через Package Manager > NeoxiderTools > Samples модуль находится в:
Assets/Samples/NeoxiderTools/<version>/NeoxiderPages/
Ключевые артефакты:
- документация:
Assets/Neoxider/Docs/NeoxiderPages/README.md - dev path:
Assets/Neoxider/Samples/NeoxiderPages/ - UPM source path перед релизом:
Assets/Neoxider/Samples~/NeoxiderPages/ - demo-сцена после импорта:
Assets/Samples/NeoxiderTools/<version>/NeoxiderPages/Demo/Scenes/UI.unity - runtime/editor код: внутри
RuntimeиEditorsample-модуля
Базовая идея модуля:
UIPage— помечает GameObject как страницу и хранит идентификатор страницы.PM— переключает страницы, отслеживает текущую и предыдущую.UIKit— статический API для вызоваShowPage(...)без прямой ссылки наPM.
Assets/Neoxider/Samples~/NeoxiderPages/
Runtime/ # runtime код Neo.Pages
Editor/ # editor-инструменты Neo.Pages.Editor
Demo/ # сцена и demo-ассеты
- Что есть в модуле (кратко)
- Пример использования
- Как добавить новую страницу
- Выбор страницы: Dropdown и Asset
- Частые вопросы (FAQ)
- Скрипты (справочник)
-
PM(Runtime/Scripts/Page/PM.cs)- singleton
PM.I - все
UIPageдолжны быть потомками объекта с PM в иерархии сцены (поиск страниц ограничен поддеревом PM) ChangePage(pageId)— переключение (выбирает стратегию: Exclusive/Popup по настройкеUIPage)SetPage(pageId)— активирует страницу и деактивирует остальные (Exclusive)ActivePage(pageId)— активирует страницу, не выключая остальные (Popup)SwitchToPreviousPage()— возврат на предыдущуюCloseCurrentPage()— закрыть текущуюOnPageChanged(UIPage)— событие смены
- singleton
-
UIPage(Runtime/Scripts/Page/UIPage.cs)- поле
pageId: PageId(ассет-идентификатор страницы) - флаги:
popup,ignoreOnExclusiveChange StartActive()/EndActive()- опциональная анимация через
DOTweenAnimationна том же объекте
- поле
-
BtnChangePage(Runtime/Scripts/Page/BtnChangePage.cs)- компонент на UI-кнопку:
Action= OpenPage/Cancel/CloseCurrent - для OpenPage использует
targetPageId: PageId - может выполнить
GameState.State(Start/Restart/Pause/…) - опционально анимирует нажатие (DOTween)
- компонент на UI-кнопку:
-
FakeLoad(Runtime/Scripts/Page/FakeLoad.cs)- фейковая загрузка с прогрессом и событиями
-
UIKitAPI(Runtime/API/UIKitAPI.cs)- удобные фасады
G,Audio,Wallet,Score,Level,GameState - позволяет Pages-слою работать «поверх» Neoxider без прямого расползания ссылок по сцене
- удобные фасады
ChangePage(pageId)выбирает стратегию по целевойUIPage: обычная страница открывается черезSetPage, popup-страница открывается черезActivePage.SetPage(pageId)включает входящую страницу и, если у нее есть Forward-анимация, ждетWaitForShowAnimation()перед закрытием исходящих страниц. Это нужно, чтобы не показывать пустой фон между страницами.- Исходящие страницы закрываются через
UIPage.EndActive(), поэтому Back-анимация воспроизводится в режимахBackwardOnlyиForwardAndBackward. - Активные popup-страницы по умолчанию закрываются при открытии обычной non-popup страницы. Настройка находится в
PM:closePopupsOnExclusivePageChange = true. - Страницы с
Ignore On Exclusive Changeне закрываются при exclusive-переходах. BtnChangePageне содержит логики ожидания/закрытия страниц: он вызываетPM, а управление переходом остается внутриPM.
using Neo.Pages;
using UnityEngine;
public class OpenShopExample : MonoBehaviour
{
[SerializeField] private PageId shopPageId;
public void OpenShop()
{
UIKit.ShowPage(shopPageId);
}
}- Добавь
BtnChangePageна UI-кнопку. - Выбери
Action:OpenPageи задайtargetPageId- либо
Cancel/CloseCurrent
using Neo.Pages;
using UnityEngine;
public class PageAnalytics : MonoBehaviour
{
[SerializeField] private PM pm;
private void OnEnable()
{
if (pm != null) pm.OnPageChanged.AddListener(OnChanged);
}
private void OnDisable()
{
if (pm != null) pm.OnPageChanged.RemoveListener(OnChanged);
}
private static void OnChanged(UIPage newPage)
{
Debug.Log($"Page changed to: {newPage?.PageId?.DisplayName}");
}
}Идентификатор страницы — это PageId ассет. Добавление новой страницы не требует правок кода:
- Создай UI (префаб/объект) страницы и повесь на корень компонент
UIPage. - В инспекторе
UIPageв секции Generate впиши имя (напримерMenuилиPageMenu) и нажми Generate & Assign.- Если страница уже существует, новый ассет создан не будет — появится лог, и будет назначен существующий.
- Убедись, что страница находится в сцене вместе с
PM, чтобыPMеё нашёл.
В UIPage и BtnChangePage можно выбирать страницу двумя способами:
- Dropdown: выпадающий список всех
PageIdизAssets/NeoxiderPages/Pages. - Asset: обычное поле ассета (Object Picker/Drag&Drop).
- В Project:
Create → Neoxider → Pages → Page Id. - Переименуй ассет в формате
Page{Name}(напримерPageMenu,PageShop,PageSettings).- Ключ
PageId.Idгенерируется автоматически из имени ассета.
- Ключ
- Если хочешь создать стандартный набор страниц одним кликом:
Tools → Neoxider → Pages → Generate Default PageIds.
- На объекте страницы открой компонент
UIPage. - Выбери страницу через Dropdown или укажи ассет вручную.
- На кнопке открой компонент
BtnChangePage. - Выбери
Action:OpenPage— открыть страницу поtargetPageIdCancel— вернуться на предыдущуюCloseCurrent— закрыть текущую
using Neo.Pages;
public class OpenPagesExamples
{
public void Open(PageId pageId)
{
UIKit.ShowPage(pageId);
}
}Проверь:
- В сцене есть активный
PM(обычно изAssets/NeoxiderPages/Prefabs/PM.prefab). - На странице есть
UIPage, и у него заданpageId. - Для
BtnChangePageвыбрана корректная страница.
PM собирает страницы через Resources.FindObjectsOfTypeAll<UIPage>() и фильтрует по текущей сцене.
Если страница лежит в другом месте (например, в префабе вне сцены) — она не попадёт в список.
Проверь:
- у страницы включен
ignoreOnExclusiveChange- такие страницыPMне закрывает приSetPage; - страница является
popup, но вPMвыключенclosePopupsOnExclusivePageChange; - popup уже неактивен или не находится в списке страниц текущего
PM.
По умолчанию активный popup закрывается при открытии обычной non-popup страницы и закрывается через EndActive(), поэтому Back-анимация должна проиграться.
Ниже перечислены основные .cs файлы внутри sample-модуля и их назначение.
-
Assets/Neoxider/Samples~/NeoxiderPages/Runtime/Scripts/UIKit.csUIKit.OnShowPage/UIKit.ShowPage(PageId)— запрос показа страницы по ассету
-
Assets/Neoxider/Samples~/NeoxiderPages/Runtime/Scripts/Page/PageId.csPageId(ScriptableObject) — ассет-идентификатор страницыPageId.Idгенерируется из имени ассета (рекомендуемый формат:PageMenu,PageShop, …)
-
Assets/Neoxider/Samples~/NeoxiderPages/Runtime/Scripts/Page/PM.cs- менеджер страниц (singleton
PM.I) - основное API:
ChangePage,SetPage,ActivePage,SwitchToPreviousPage,CloseCurrentPage - переключение только по
PageId - событие:
OnPageChanged(UIPage)
- менеджер страниц (singleton
-
Assets/Neoxider/Samples~/NeoxiderPages/Runtime/Scripts/Page/UIPage.cs- компонент “страницы” (GameObject) с
pageId: PageId - флаги:
popup,ignoreOnExclusiveChange - поведение:
StartActive()/EndActive()+ (опционально) DOTween-анимация
- компонент “страницы” (GameObject) с
-
Assets/Neoxider/Samples~/NeoxiderPages/Runtime/Scripts/Page/BtnChangePage.cs- UI-кнопка переключения страниц через
PM.I Action:OpenPage/Cancel/CloseCurrent- для
OpenPageиспользуетtargetPageId: PageId - может выполнить
GameState.Stateперед переключением
- UI-кнопка переключения страниц через
-
Assets/Neoxider/Samples~/NeoxiderPages/Runtime/Scripts/Page/FakeLoad.cs- корутина “фейковой загрузки” с прогрессом
- события:
OnStart,OnFinisLoad,OnChangePercent(int),OnChange(float)
-
Assets/Neoxider/Samples~/NeoxiderPages/Runtime/Scripts/Core/PageSubscriber.cs- пример подписки на события Neoxider (
G.OnStart) и переключения страницы черезPM
- пример подписки на события Neoxider (
-
Assets/Neoxider/Samples~/NeoxiderPages/Runtime/Scripts/Core/ToggleAudio.cs- мостик UI → аудио-настройки (
Audio.IsActiveMusic/IsActiveSound) - работает через
VisualToggle(изNeo.UI)
- мостик UI → аудио-настройки (
Assets/Neoxider/Samples~/NeoxiderPages/Runtime/API/UIKitAPI.cs- набор статических фасадов для удобного доступа из UI:
Wallet,Score,Level— значения и события измененияAudio— включение/выключение музыки/звука +PlayUI()G— события/методы управления состояниями игры (Menu/Start/Pause/Win/…)GameState— enum +GameState.Set(state)для выполнения действия
- набор статических фасадов для удобного доступа из UI:
-
Assets/Neoxider/Samples~/NeoxiderPages/Editor/Tools/AutoSpriteAssignerEditor.cs- EditorWindow: массово назначает
SpriteвUnityEngine.UI.Imageпо имени GameObject ↔ имени Sprite - меню:
Tools/UIKit/Auto Sprite Assigner
- EditorWindow: массово назначает
-
Assets/Neoxider/Samples~/NeoxiderPages/Editor/Tools/AutoTMPFontAssignerEditor.cs- EditorWindow: массово назначает
TMP_FontAssetдля всехTMP_Textв сценах - меню:
Tools/UIKit/Auto TMP Font Assigner
- EditorWindow: массово назначает
-
Assets/Neoxider/Samples~/NeoxiderPages/Editor/Tools/PageIdGenerator.cs- генератор
PageIdассетов (в т.ч. дефолтный набор) - меню:
Tools/Neoxider/Pages/Generate Default PageIds
- генератор
-
Assets/Neoxider/Samples~/NeoxiderPages/Editor/Inspectors/UIPageEditor.cs- удобный инспектор
UIPageс переключателем Dropdown/Asset + генерациейPageId
- удобный инспектор
-
Assets/Neoxider/Samples~/NeoxiderPages/Editor/Inspectors/BtnChangePageEditor.cs- удобный инспектор
BtnChangePageс переключателем Dropdown/Asset + генерациейPageId
- удобный инспектор