Keep your place in this quest

Log in or sign up for free to subscribe, follow lesson progress, and access more learning content.

В предыдущем уроке вы узнали, как Python может управлять сущностями во время игры. Но Python в Cave не ограничивается только запущенной игрой. Вы также можете использовать его для создания инструментов редактора, которые помогут вам быстрее создавать вашу игру.

Это особенно полезно, потому что во многих проектах много повторяющихся задач. Возможно, вы часто расставляете врагов, создаете контрольные точки, организуете папки, тестируете значения или просматриваете данные сцены. Вместо того чтобы выполнять всё вручную каждый раз, вы можете создавать небольшие инструменты, которые автоматизируют часть вашей работы. Вы даже можете создавать более продвинутые редакторы, позволяющие делать процедурно сгенерированные уровни, процедурные здания и многое другое.

В этом уроке вы узнаете:

  • В чем разница между игровыми скриптами и скриптами редактора.
  • Для чего можно использовать инструменты редактора.
  • Как структурирован редакторский таб-инструмент.
  • Почему важна метка #editoronly.
  • Когда стоит создавать собственный инструмент.

Вам не нужно сразу создавать инструменты при начале работы, но полезно знать, что такая система существует. Это одна из тех функций, которые становятся ценными по мере роста вашего проекта.

Игровые Скрипты и Инструменты Редактора

Короче говоря:

  • Игровые скрипты запускаются во время игры.
  • Инструменты редактора работают внутри редактора, чтобы помочь вам работать над проектом.
Тип скрипта Запускается в Пример
Игровой скрипт Режим игры и экспортированная игра. Движение игрока, AI врагов, двери, подбираемые объекты.
Инструмент редактора Cave Editor. Помощник по уровням, пакетное переименование, инспектор сцены, генератор процедурных зданий, инструмент размещения.

Например, скрипт открытия двери — это игровая логика, потому что игрок должен взаимодействовать с ней во время игры. А инструмент, который размещает десять факелов вдоль коридора — это логика редактора, так как он помогает вам создавать уровень, но не нужен в экспортированной игре.

Почему Инструменты Редактора Полезны

Сначала может показаться, что кастомные инструменты нужны только большим командам.

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

Инструменты редактора помогают с такими вещами, как:

  • Размещение групп сущностей.
  • Проверка отсутствующих обязательных компонентов.
  • Создание типовых настроек сцены.
  • Вывод отладочной информации.
  • Тестирование значений без входа в режим игры.
  • Помощь дизайнерам в настройке игровых данных.

Например, если вы создаете игру от третьего лица с множеством вражеских лагерей. Вместо того, чтобы вручную создавать одни и те же папки каждый раз, вы можете создать инструмент, который автоматически добавит Enemy Group, несколько точек появления и зону триггера.


Скрипты только для редактора

Скрипты редактора обычно начинаются с этой строки:

#editoronly

Это говорит Cave, что скрипт предназначен для использования в редакторе.

Это важно, потому что инструменты редактора могут использовать API или поведение, которые имеют смысл только внутри редактора. Обычно вы не хотите, чтобы помощник по дизайну уровней или панель отладки были частью финального игрового запуска.

Это также необходимо, чтобы Cave знал, какие скрипты запускать при старте игры, а какие — нет. По умолчанию запускаются все скрипты, поэтому если какой-то нужно исключить, в нем должна быть эта метка первой строкой.

Так что, если вы создаете скрипт только для помощи в работе внутри Cave Editor, делайте его исключительно редакторским.

Инструменты на вкладках редактора

Один из распространенных способов создания инструмента — использовать Editor Tab.

image.png

Вкладка редактора — это пользовательская панель, появляющаяся внутри Cave Editor. У нее есть метод draw(), который Cave вызывает, пока вкладка видима, чтобы инструмент мог рисовать кнопки, текст, свойства и другие элементы управления.

Очень простой редакторский таб выглядит так:

#editoronly
import cave

class ExampleTab(cave.ui.DebugTab):
    def __init__(self):
        super().__init__()
        self.counter = 0

    def draw(self):
        cave.ui.text("This is a sample tool.")
        cave.ui.separator()

        self.counter = cave.ui.prop("Counter", self.counter)

        if cave.ui.buttonDark("Increase counter +1"):
            self.counter += 1
            print("Counter increased by +1")

Это также код по умолчанию при добавлении вкладки редактора. Если открыть его во вкладке свойств, а затем перейти на вкладку инструментов редактора, вы увидите класс example tab как debug tab. Вам останется только зарегистрировать или перезагрузить вкладку — и она появится в интерфейсе:

image.png

Этот пример прост, но уже показывает основную идею:

  • cave.ui.DebugTab создаёт пользовательскую вкладку редактора.
  • draw() определяет, что показывает вкладка.
  • cave.ui.text() рисует текст.
  • cave.ui.prop() рисует редактируемое свойство.
  • cave.ui.buttonDark() создаёт кнопку.
  • print() можно использовать для вывода информации в консоль.

Вот насколько просто создавать пользовательские инструменты для Cave Editor. Позже вы можете использовать эту же структуру для создания настоящих инструментов.

Что означает метод draw()

Метод draw() не похож на start() в игровом компоненте.

Он вызывается repeatedly (многократно), пока инструмент видим, потому что пользовательский интерфейс редактора нужно рисовать и обновлять. Это значит, что код внутри draw() должен описывать текущий интерфейс инструмента.

Например:

def draw(self):
    cave.ui.text("Level Helper:")

    if cave.ui.buttonDark("Create Enemy Group"):
        print("Create enemy group clicked")

Кнопка рисуется каждый раз при обновлении вкладки, но код внутри if выполняется только при клике пользователя по кнопке.

Такой шаблон очень распространён в инструментах редактора.

Практическая идея инструмента

Допустим, вы создаёте уровень и часто нужны одни и те же базовые папки:

  • Environment
  • Enemies
  • Gameplay Triggers
  • Lighting
  • Audio
  • Debug Helpers

Вы могли бы сделать инструмент редактора с кнопкой Create Level Folders. При нажатии он создаёт эти папки-сущности в текущей сцене. Напомним: Папка в Scene Graph — это просто Entity без компонентов.

Это кажется маленькой мелочью, но такие инструменты делают крупные проекты легче в организации. Они также помогают следовать собственным конвенциям без необходимости запоминать каждый шаг вручную.


Компоненты редактора

Иногда нужно смешивать игровую логику с логикой редактора. Например, вы можете захотеть прикрепить компонент к сущности, который также выполняет редакторскую логику — например, отображение отладочной информации или сферы, показывающей зону атаки врага. В этом случае вместо cave.Component используется cave.EditorComponent.

Это полезно, когда сущности нужна специальная редакторская логика, но она не должна быть частью игры.

Например:

  • Точка спауна может показывать дополнительную информацию в редакторе.
  • Объем триггера может предоставлять элементы управления отладки.
  • Маркер уровня может проверять, правильно ли он настроен.

Главная идея: скрипты редактора предназначены для работы над игрой, а игровые скрипты — для самой игры.

ВАЖНО: В этом случае поведение отличается от обычного компонента, потому что EditorComponent имеет метод обновления редактора, который вызывается каждый кадр, пока редактор запущен и игра — нет. Но и это важнее всего, такой компонент будет зарегистрирован, инициализирован и запущен вместе с сущностью независимо от режима (игра активна или нет). Значит, логика в методе start этого компонента вызовется даже вне режима игры.

Это потенциально опасно, например: если в методе start такого компонента будет код, который получает все сущности сцены и удаляет их, то ваша игра будет полностью удалена в редакторе без возможности отмены. Это не ошибка и не баг — так задумано. Будьте осторожны.

Если нужна более безопасная альтернатива, можно использовать Python Code Component, так как в нем есть метод обновления редактора, а при этом start и end методы редактором не вызываются. Например, в начальном проекте Cave есть враг, который использует Python Code Component для рисования отладочной сферы вокруг врагов, показывая радиус их перемещения. Это хороший пример для изучения.


Когда следует создавать инструмент?

Не создавайте кастомный инструмент для каждой мелочи.

Создавайте инструмент, когда он решает реальную проблему рабочего процесса, например:

  • Вы повторяете одну и ту же задачу много раз.
  • Легко забыть какой-то набор настроек.
  • Сцена требует проверки.
  • Дизайнеру нужен удобный интерфейс для изменения значений.
  • Для прототипа нужны быстрые кнопки отладки.

Для новичков лучше сначала создавать игровые объекты вручную, а когда вы поймете все шаги, автоматизировать скучную часть.

Что важно помнить

Python в Cave можно использовать и для игровых скриптов, и для инструментов редактора.

Игровые скрипты управляют происходящим во время игры, инструменты редактора помогают создавать, инспектировать, отлаживать и организовывать проект внутри Cave Editor.

Инструменты редактора не нужны для создания первой игры, но они очень полезны, когда проект начинает расти. Маленький инструмент, сэкономивший 5 минут сегодня, может сэкономить часы впоследствии.