Skip to content

Latest commit

 

History

History
114 lines (82 loc) · 11.1 KB

File metadata and controls

114 lines (82 loc) · 11.1 KB

Пример: игра про аномалии

Что это: Пошаговый пример сборки игры про аномалии (выживание, случайное появление, исправление, победа/поражение) на компонентах NeoxiderTools.

Как использовать: Выполните шаги в разделах 1–5; нужные компоненты перечислены ниже.


Что понадобится

  • TimerObject (2 экземпляра): один — время до победы (например выжить 6 часов), второй — интервал появления аномалий.
  • Selector + SelectorItem на каждом объекте-аномалии.
  • VisualToggle или ToggleObject для визуала аномалии (опционально).
  • NeoCondition по Selector.CountActive для поражения (например, 4 активных аномалии → проигрыш).
  • GM / EM для победы и поражения (опционально).
  • RandomRange — для сценария «от 0 до N аномалий на уровень» (опционально).

1. Таймер «время до победы»

Цель: игрок должен продержаться, например, 6 часов игрового времени.

  1. Создайте пустой GameObject (например, TimerVictory).
  2. Добавьте компонент TimerObject.
  3. Настройте:
    • Duration = 21600 (6 × 3600 секунд).
    • Count Up = true.
    • Looping = false.
    • Time Scale = множитель скорости игры (например, 24, если 1 реальная минута = 24 игровых минуты).
    • Auto Start = true (или запускайте по событию старта игры).
  4. В On Timer Completed привяжите вызов победы (например, GM.Win() или свой UnityEvent перехода на экран победы).

2. Таймер «спавн аномалий»

Цель: через случайные интервалы «включать» следующую аномалию.

  1. Создайте GameObject (например, TimerAnomalySpawn).
  2. Добавьте TimerObject.
  3. Настройте:
    • Use Random Duration = true.
    • Random Duration Min / Max = желаемый диапазон в секундах (например, 5–30).
    • Looping = true.
    • Time Scale = тот же множитель, что и у таймера победы (чтобы интервалы были в игровом времени).
    • Auto Start = true (или при старте игры).
  4. В On Timer Completed привяжите вызов Selector.SetRandom() у вашего Selector с аномалиями. Таймер сам будет вызывать команду выбора следующей аномалии по истечении интервала.

3. Менеджер аномалий (Selector + SelectorItem)

  1. Создайте родительский объект (например, AnomalyManager).
  2. Сделайте дочерними объекты-аномалии (каждый — префаб или объект с визуалом и, при необходимости, VisualToggle / ToggleObject).
  3. На каждый дочерний объект добавьте компонент SelectorItem. Индекс проставится автоматически при обновлении списка детей.
  4. На родителя AnomalyManager добавьте Selector:
    • Включите Auto Update From Children (по умолчанию включено).
    • Включите Use Random Selection.
    • Включите Notify Selector Items Only: на дочернем объекте с SelectorItem селектор вызывает только SelectorItem.SetActive (сам компонент не дергает GameObject.SetActive на этом объекте — только реактивное поле и UnityEvent). Прямой GameObject.SetActive селектор использует только для элементов без SelectorItem, если они есть в списке.
    • Флаг Control Game Object Active в инспекторе — это общий «разрешить прокидывать выбор в элементы». Для сценария «только через SelectorItem» оставьте его включённым, иначе селектор не вызовет ни GameObject.SetActive, ни SelectorItem.SetActive (останутся только индекс и OnSelectionChanged*).
  5. На каждом SelectorItem:
    • В On Activated привяжите показ аномалии (например, вызов VisualToggle.SetActive(true) на том же объекте).
    • При «исправлении» аномалии игроком вызовите ExcludeFromSelector() (например, кнопкой или другим событием), чтобы этот индекс больше не участвовал в случайном выборе до сброса.
  6. При необходимости сброса пула (новая игра или новый уровень) вызовите Selector.IncludeAllIndices().

4. Условие поражения и починка аномалий

Если одновременно активно слишком много аномалий — поражение; игрок должен «чинить» аномалии, чтобы вернуться в безопасное состояние.

  1. Используйте NeoCondition (или аналог проверки по полю).
  2. В качестве объекта проверки укажите ваш Selector.
  3. Настройте условие по полю CountActive (например, «больше или равно 4»).
  4. При выполнении условия вызовите поражение (например, GM.Lose()).

Починка аномалий через InteractiveObject

Чтобы игрок мог чинить аномалии кликом/клавишей:

  1. На каждом объекте-аномалии добавьте коллайдер (Collider/Collider2D) подходящей формы.
  2. Добавьте компонент InteractiveObject (Scripts/Tools/InteractableObject/InteractiveObject.cs):
    • Включите Use Mouse Interaction (по умолчанию включено) или Use Keyboard Interaction (клавиша, например E).
    • Убедитесь, что Include Trigger Colliders In Mouse Raycast включён, если используете Is Trigger-коллайдер.
  3. В событии On Interact Down InteractiveObject привяжите вызов SelectorItem.ExcludeFromSelector() (на том же объекте или через ссылку), а также, при необходимости, скрытие визуала (например, VisualToggle.SetInactive).
  4. При вызове ExcludeFromSelector соответствующая аномалия перестанет выбираться Selector.SetRandom(), а CountActive уменьшится, что отодвигает поражение.

5. Два таймера вместе

  • TimerObject «победа»: duration = 21600 (6 ч), countUp, не looping; On Timer Completed → победа.
  • TimerObject «спавн»: useRandomDuration (например, 5–30 с), looping; On Timer Completed → Selector.SetRandom().
  • При необходимости оба таймера могут использовать один и тот же Time Scale, чтобы и время до победы, и интервалы появления аномалий шли в одной «игровой» шкале времени. Это опционально: таймер победы и таймер спавна можно ускорять по-разному или оставить один из них в реальном времени.

6. Замок: 0–5 аномалий на уровень и новый день (без повторов)

Если на уровне (например, «замок») нужно включать случайное число аномалий от 0 до 5, а при переходе на следующий день уровень сбрасывается и аномалии не должны повторяться в течение дня:

  1. RandomRange: добавьте компонент RandomRange на объект (например, уровень или менеджер). Mode = Int, Min = 0, Max = 5. При старте уровня вызовите Generate() (из стартового события сцены или таймера).
  2. NeoCondition по RandomRange: создайте NeoCondition с условием «объект — RandomRange, поле ValueInt, оператор GreaterOrEqual, порог 1». При On True включите таймер спавна аномалий (например, вызов TimerAnomalySpawn или активация GameObject с таймером). Так таймер будет работать только если выпало хотя бы 1 аномалия.
  3. Ограничение числа активных аномалий: можно добавить второе условие по Selector.CountActive (например, «меньше ValueInt») и вызывать Selector.SetRandom() по таймеру только когда CountActive < ValueInt (через NeoCondition или отдельную логику).
  4. Для нового дня используйте сам Selector: при переходе на следующий день или перезагрузке уровня вызовите Selector.IncludeAllIndices() и, если нужно, Selector.ResetAll(). Так пул аномалий начнётся заново без отдельного вспомогательного компонента.
  5. Если в течение одного дня аномалии не должны повторяться, исключайте их по мере исправления через SelectorItem.ExcludeFromSelector() или напрямую через Selector.ExcludeIndex(int). В конце дня очищайте исключения вызовом IncludeAllIndices().

См. также