Pull to refresh

Comments 17

Я недавно попытался сделать меню на основе графа. Написал граф, привязал к нему меню. Граф-то рабочий, а вот меню юзать неудобно. Много кода при создании.
Спасибо за идею, надо будет обязательно попробовать вариант со машиной состояний.

Вообще меня удивляет, что в игровых фреймворках до сих пор нет вменяемого UI-комплекса. Казалось бы, вещь, которая всем нужна.
Использование машин состояний и автоматов для GUI — достаточно стандартное решение. Но всё равно спасибо за статью. Ещё один вариант решения никогда не лишний. Можно и из него какие-то идеи взять. Единственное — не хватило картинок. Автоматы описываются графами переходов. Графы удобнее визуально понимать. Если бы были скрины из какого-нибудь тестового приложения с реальными менюшками — вообще идеально было бы.

P.S.: Если уж зашла речь о UI — задам вопрос. Была идея написать статью про используемую у нас на проекте объектную обёртку вокруг системы mutlytuch-событий для упрощения обработки пользовательских жестов. Как думаете, имеет смысл писать, или есть какое-то однозначное популярное решение в этой области?
Однозначно писать. Вменяемой хорошей информации по Unity на русском — крупицы. Вобще шикарно будет, если статья будет затрагивать разные подходы и ± в них.
Да в играх почти для всего Машина состояний вполне логичное решение, за некоторыми исключениями
Спасибо. Обязательно буду использовать иллюстрации в дальнейших статьях.
Мне кажется, что смысл писать есть. Сейчас количество информации действительно меньше, по сравнению с тем, которое я хотел бы видеть, начиная изучать Unity.
С unity 5.x появилась поддержка графов на базе аниматора и StateMachineBehaviour — свой огород можно больше не городить, а гонять штатный. На ноды графа теперь можно вешать компоненты с методами-реакциями на вход-выход в / из ноды, например, как тут.
В статье не хватает «для чего и в каких случаях это хорошо». Если конечным автоматом с состояниями представлять навигацию по главному меню скажем — ок, а вот если речь идёт уже о попапах, диалоговых окнах и т. п. то нет. И стейты далеко не всегда нужны, так как во многих задачах они будут избыточны и будут только усложнять структуру кода. Просто далеко не всегда нужна полная смена гуя, и иногда проще стейтмашину ставить независимо от интерфейса, а тут оно достаточно жёстко связано. Простой енам и выбор, какой именно гуй инстанцировать/показывать был бы ничем не хуже (хотя может я просто не вижу минусов)

А по данной реализации, она интересная, но на мой взгляд, она слишком сложная для такого функционала, и я не совсем понимаю, почему бы стейт свитчер не сделать синглтоном.
если речь идёт уже о попапах, диалоговых окнах и т. п.
то, в общем-то, да, достаточно просто завести банальный статический класс, который будет менеджить и слушать колбеки со всяких DialogPopup, MessageBox и т.д.
Тут же речь идет о полноценной смене одного менюшного стейта (скрина) на другой. Можно сделать и енамом, но это другие масштабы. Когда у меня было 15 полноценных стейтов, енам из 15 элементов и 15 кейсов свитча — было менее удобно, признаться.
Я просто себе слабо представляю 15 взаимосвязанных стейтов интерфейсов в игре, так как глубина переходов больше, чем в 3 — это уже плохо с точки зрения проектировки UI. А если они достаточно независимы, то я для этого использую модульную систему и в нужных местах вызываю необходимые модули. Не спорю, такие ситуации возможно могут возникать, просто в моём понимании они очень специфичны.
Насчет предложений, возможно вам понравится философия Redux (React.js), с еще одним явным компонентом — хранилищем состояний.
Спасибо! Обязательно изучу в ближайшее время.
Можно освободить часть кода, если убрать код связанный с вызовом Enter(), так как метод Enter(params object[] parameters) имеет возможность вызова без параметров, в этом случае передаётся пустой массив.

Какой смысл здесь дублировать аргументы:
new GameEndState(GameEndUI.Instance, GameEndUI.Instance),
...
public GameEndState(IUIShowableHidable uiShowableHidable, GameEndUI gameEndUI)
{
    ShowableHidable = uiShowableHidable;
    this.gameEndUI = gameEndUI;
}
если можно написать так:
public GameEndState(GameEndUI gameEndUI)
{
    ShowableHidable = gameEndUI;
    this.gameEndUI = gameEndUI;
}

Ничего не сказано о CachableMonoBehaviour и об этом методе:
protected bool TrySendAction(Action action)
{
    if (action == null) return false;
    action();
    return true;
}
Да, вы правы!
Признаться честно, я не знал, что в метод с parameters можно ничего не передавать. В таком случае, метод OnEnter() действительно можно опустить.
Насчет CachableMonoBehaviour — код был выдернут из под одного проекта, который требовал использования монобеха с закэшироваными полями, вроде transform, gameObject и т.д. Все монобехи были заменены автозаменой на CachableMonoBehaviour, в т.ч. и этот.
TrySendAction — метод, который был рассчитан на то, чтобы не писать каждый раз «if» в лямбдах на кнопках.
Извиняюсь, что забыл подтереть эти упоминания.
Так и подумал, про CachableMonoBehaviour и TrySendAction мне стоило написать в личку. К слову, спасибо за статью.
Очень забавно, но после множества итераций и коллективного обсуждения опыта реализации интерфейса в нескольких небольших проектах мы пришли к очень похожей схеме построения меню. Просто поразительно похожей)
Конечно в итоге система получилась немного сложнее — были добавлены штатные абстракции под загрузку ресурсов, анимированное появление меню, переключение сцен между стейтами(когда надо не только сменить состояние с меню на битву, но и загрузить для битвы сцену с картой, к примеру).
А интерфейс получил возможность отображаться как монопольно, так и слоями(для реализации диалоговых окон, переиспользования одинаковых кнопочек и т.д)
Но вообще сходство поразительное, стейты можно было реализовать и по другому.
без картинок не информативно
Only those users with full accounts are able to leave comments. Log in, please.