Создание игры-реставрации: от идеи до рабочего прототипа в Godot и Blender опыты дилетанта

belkov.k.v

Новичок
Репутация
0 / 0

дисклеймер статья написана ботом где обсуждалось как создать и что добавить и т.д. но прежде чем чем опубликовать я ее прочел и дополнил

и это статья так сказать рассказ об собственном опыте чем как обучающий материал

Создание игры-реставрации: от идеи до рабочего прототипа в Godot и Blender​

Введение​

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

Выбор инструментов​

Для разработки были выбраны:

  • Godot 4 — бесплатный движок с открытым исходным кодом, отличной поддержкой 3D и удобным скриптовым языком GDScript.
  • Blender — мощный инструмент для 3D-моделирования, позволяющий создавать сложные разбитые объекты и автоматизировать экспорт с помощью Python-скриптов.
  • JSON — для хранения всех необходимых данных о деталях предмета: их трансформации, материалы, соседи и этапы реставрации.

Подготовка модели в Blender​

Разбиение на осколки​

Первым шагом было создание целой модели (например, вазы). Для её разбиения на осколки использовался встроенный аддон Blender Cell Fracture. Он позволяет выбрать объект и разбить его на множество фрагментов с настраиваемыми параметрами (количество осколков, шум, масса). Важно выполнить разбиение в том состоянии, когда все осколки ещё находятся в собранном виде — это необходимо для дальнейшего вычисления их взаимного расположения.

Создание аддона Restoration Item Creator​

2026-03-07_08-05-58.png

Для удобства работы мы разработали собственный аддон для Blender, который добавляет панель во вкладку Restoration. С его помощью можно:

  • Задавать общие свойства предмета (имя, эпоху, порог для определения соседей).
  • Для каждой детали указывать её тип (основная, крепёж, фрагмент), материал (керамика, дерево, металл), тип соединения (клей, винт, защёлка), необходимый инструмент, порядок разборки и список этапов реставрации.
  • Визуализировать связи между соседними осколками (зелёные линии), что позволяет подобрать правильный порог расстояния.
  • Автоматически переименовывать осколки по шаблону (например, Piece_001, Piece_002), что гарантирует совпадение имён в Blender и Godot.
  • Экспортировать все данные в JSON вместе с моделью в формате GLB, создавая отдельную папку для каждого предмета.
З.Ы. аддон еще сырой его еще пилить и пилить

Ключевая часть аддона — вычисление локальной трансформации каждого осколка относительно центра целого предмета и определение соседей по расстоянию между центрами осколков. Для каждого соседа сохраняется относительная матрица 4×4, которая впоследствии позволит точно позиционировать осколки при склеивании.

Пример структуры JSON:
Код:
{
  "item_name": "Vase",
  "vase_center_global": [0.0, 0.5, 0.0],
  "pieces": [
    {
      "name": "Piece_001",
      "type": "FRAGMENT",
      "material": "CERAMIC",
      "connection_type": "GLUE",
      "required_tool": "кисточка",
      "disassembly_order": 1,
      "stages": [],
      "vase_center_local": [0.1, 0.2, 0.3],
      "local_transform": [[1,0,0,0.1],[0,1,0,0.2],[0,0,1,0.3],[0,0,0,1]]
    }
  ],
  "neighbors": {
    "Piece_001": [
      {
        "neighbor": "Piece_002",
        "relative_matrix": [[1,0,0,0.5],[0,1,0,0.2],[0,0,1,0.3],[0,0,0,1]]
      }
    ]
  }
}

Импорт в Godot​

Для автоматического создания сцены с осколками в Godot был написан скрипт AutoSetup.gd. Он:

  • Загружает GLB-модель и JSON.
  • Для каждого меша создаёт RigidBody3D, копирует его трансформацию, добавляет коллизию (выпуклую оболочку ConvexPolygonShape3D).
  • Прикрепляет к телу скрипт Piece.gd и заполняет его данные (имя, локальную трансформацию, материал, соседей и т.д.).
  • Настраивает физические параметры (массу, трение, слои коллизий).
Важно: для корректной работы физики и рейкастов мы используем слои коллизий. Осколки находятся на слое 1, пол — на слое 2. Маска коллизий осколков включает оба слоя (collision_mask = 1 | 2), чтобы они взаимодействовали друг с другом и с полом.

Скрипт Piece.gd хранит все данные и предоставляет методы для работы с ними, например, get_vase_transform(), вычисляющий глобальную трансформацию виртуальной вазы для данного осколка.

Управление предметами в игре​

Изначально планировалась система с фиксированными слотами (левый и правый), но в процессе разработки мы пришли к более гибкому подходу, напоминающему работу с объектами в 3D-редакторах.

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

Поднятие и опускание предметов​

  • Двойной клик левой кнопкой мыши по осколку переключает его состояние: если он лежит на полу, он поднимается (физика отключается, объект становится доступным для манипуляций); если он уже поднят — возвращается в точку сброса (центр площадки) и падает.

Перемещение и вращение​

  • Одиночный клик по уже поднятому осколку и движение мыши перетаскивают его в плоскости экрана (dragging).
  • Правая кнопка мыши при наличии нескольких поднятых осколков перемещает всю группу как единое целое (плоскость строится по среднему центру группы).
  • Колесико мыши вращает осколок под курсором (или всю группу) вокруг оси взгляда камеры.
  • Клавиши A/D вращают вокруг вертикальной оси камеры, W/S — вокруг горизонтальной.
  • Клавиши Q/E приближают и отдаляют объект вдоль оси взгляда.

Все эти манипуляции применяются либо к конкретному осколку под курсором (если он активен), либо ко всей группе.

Защита от проваливания под пол​

Чтобы осколки не уходили под пол при перемещении, в каждом кадре проверяется их позиция по оси Y. Если она ниже заданного уровня (floor_level), она корректируется. Альтернативный метод — использование коллизий (рейкаст вниз), но для ровного пола достаточно простой проверки.

Склеивание осколков​

Главная механика игры — соединение осколков в целый предмет. Для её реализации мы используем данные из JSON.

з.ы. вот тут начинается уже рассказ моей проблемы о которой я хочу рассказать​

Проверка совместимости​

Для каждой пары активных осколков проверяется:

  1. Являются ли они соседями (поле neighbors в JSON).
  2. Совпадают ли виртуальные центры вазы, вычисленные для каждого осколка. Если два осколка находятся в правильном положении друг относительно друга, то трансформации виртуальной вазы должны совпадать (с заданным допуском).
Для вычисления виртуальной вазы используется метод get_vase_transform():
Код:
func get_vase_transform() -> Transform3D:
    return global_transform * local_transform
Здесь local_transform — матрица, переводящая осколок из его локального пространства в пространство собранного предмета (центр предмета в начале координат). Если осколок на своём месте, то global_transform * local_transform даст глобальную трансформацию предмета.
Проверка выполняется в функции find_potential_glue_pair():
  • Перебираются все пары активных осколков.
  • Если они соседи и разница между их виртуальными вазами меньше порогов (glue_pos_threshold, glue_angle_threshold), пара считается готовой к склейке.

Визуальная подсказка​

З.Ы.. метод не работает. не мог понять почему
Когда такая пара найдена, оба осколка подсвечиваются зелёным цветом (через метод highlight() в Piece.gd). Это даёт игроку понять, что они могут быть соединены.

Выполнение склейки​

При нажатии клавиши F вызывается функция glue_pieces(), которая:
  • Получает относительную матрицу соседа из данных (если есть).
  • Точнее позиционирует второй осколок относительно первого с помощью этой матрицы (или через виртуальную вазу).
  • Размораживает физику обоих осколков, чтобы они могли упасть.
  • Помечает их как склеенные и удаляет из списка активных.
Изначально мы пытались использовать PinJoint3D для физического соединения, но столкнулись с проблемами при замороженных телах. Отказ от joint в пользу точного позиционирования и последующей независимой физики оказался проще и надёжнее. После склейки осколки просто лежат рядом и при необходимости могут быть снова подняты.

Проблемы и их решения​

Несовместимость аддонов​

Первая попытка использовать готовые аддоны для разрушения в Godot (Destronoi, VoronoiShatter) привела к вылетам и ошибкам. Было решено готовить разбитые модели в Blender вручную или с помощью Cell Fracture, а в Godot импортировать уже готовые фрагменты.

Коллизии​

При создании коллизий для осколков важно было использовать ConvexPolygonShape3D, так как ConcavePolygonShape3D не подходит для динамических тел и может вызывать ошибки. Мы также применяем масштабирование вершин, чтобы учесть возможный масштаб модели.
З.Ы. это вот пробела наверное номер 1!

Ошибки типов в Godot​

В процессе разработки возникали ошибки, связанные с несоответствием типов (например, попытка присвоить StaticBody3D переменной типа RigidBody3D). Все рейкасты были дополнены проверками is RigidBody3D.

Потеря данных о соседях​

На первых порах JSON не содержал поля neighbors, и склеивание не работало. После добавления вычисления соседей в аддон и корректной загрузки в Godot механика ожила. Мы также добавили отладочный вывод, чтобы убедиться, что данные читаются.
ЗЫ мы это вроде поправили

Управление​

Ранние версии управления с фиксированными слотами оказались неудобными. Переход к свободному манипулированию группой объектов сделал взаимодействие более интуитивным.

Итоги и перспективы​

В результате мы получили рабочий прототип, в котором игрок может поднимать осколки, свободно перемещать и вращать их,( а затем склеивать подходящие пары) ЗЫ а тут он соврал нам так еще не получилось). Все данные о предмете хранятся в JSON и автоматически загружаются при старте сцены.

Что можно добавить в будущем​

  • Инструменты и этапы реставрации — например, для склеивания требуется клей, а для очистки — кисть.
  • Иерархия разборки — чтобы некоторые детали можно было отделить только после удаления креплений.
  • Разные типы соединений (винты, защёлки) с соответствующими анимациями.
  • Сохранение прогресса — какие осколки уже склеены.
  • Более сложные предметы с подвижными частями (дверцы, ящики).
Разработанный аддон для Blender и скрипты для Godot могут быть использованы как основа для создания других игр, связанных со сборкой и реставрацией.

Заключение​

Создание игры-реставрации потребовало тесной интеграции Blender и Godot. Благодаря гибкости обоих инструментов и возможности писать собственные скрипты, удалось реализовать полноценный пайплайн от моделирования до геймплея. Надеемся, что наш опыт будет полезен другим разработчикам, желающим создавать подобные игры.
Все исходные коды скриптов доступны в репозитории (ссылка).
 

Похожие темы

Сверху