Godot: Никто не знает, как работает Годо. (Re-MultiScript, узел на основе Re-Class)

Созданный на 16 окт. 2018  ·  63Комментарии  ·  Источник: godotengine/godot

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

Некоторые связанные проблемы: #19486 #7402 #15996 #8502
Это топ-4, но есть много похожих, и все они направлены на решение одной и той же проблемы: каждый ищет удобный рабочий процесс.

Удивительно, но пользователям Godot удалось создать неэффективные рабочие процессы, копирующие другие знакомые движки. Чтобы продемонстрировать это, я буду использовать фиктивный класс того, как будет выглядеть MeshInstance , созданный в Godot.


Есть псевдо Unity, он же дочерние узлы:


Пользователи Godot используют дочерние узлы для создания эквивалента MultiScripts.

MeshInstance(Spatail +script)
--- Сетка(Сетка+скрипт)
--- Материал (узел + скрипт) - Шейдер (узел + скрипт) - Текстура (узел + скрипт)
--- Преобразование (Position3D + скрипт)

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

Проблемы:
1.) Это цифровой эквивалент добавления холодной воды в кипящий котел; это помогает в краткосрочной перспективе, но вызывает больше путаницы в более крупных проектах.
2.) Большинство пользователей заканчивают тем, что используют сигналы, подобные событиям, связывая их только с отправляющим их узлом и используя Экспорт для поиска цели.
3.) События могут быть перехвачены до достижения нижних узлов.
4.) Производительность медленная и на отметке 50 000 объектов может зависнуть, когда игра пытается загрузить сцены.


Pseudo Unreal, он же контроллеры и промежуточные:

Пользователи Godot создают контроллеры и узлы-владельцы, которые манипулируют всеми потомками. Торговой маркой этого рабочего процесса являются классы, производные от расширений.

MeshWithTexturedMaterial.instanced() *только узел в дереве
-> расширяется из -> MaterialTextured -> расширяется из -> Материал -> расширяется из -> Шейдер

Эта система требует серьезного планирования, иначе вы получите похожий код во многих классах. Как камера, классы персонажей и транспортных средств, каждый из которых содержит свою собственную копию «следуй за целью».
Проблемы:
1.) Беспорядочные большие сценарии, которые сложно отлаживать.
2.) Дублирующийся код в разных классах.
3.) Godot не рассматривает узлы как классы; вынуждая этих разработчиков сильно полагаться на самозакодированные классы.
4.) Расширения не имеют смысла, например, _боевая система_ расширяет _систему оружия_ и, наконец, расширяет игрока.


Псевдо Panda3D, он же Preload(Script):

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

MeshInstance (узел)
Предварительная загрузка (сетевой скрипт)
Предварительная загрузка (сценарий материала)
Предварительная загрузка (скрипт преобразования)

Как ни странно, именно эти разработчики отказываются отказываться от GDscript, даже когда C# явно лучше подходит для этого подхода. Вот почему я предполагаю, что они знакомы с Python.
Проблемы:
1.) Путаница в том, как следует вызывать импорт, поскольку константы могут быть переменными с onready; кто знает.
2.) Редко использует узлы Godot, я даже видел, как разработчики полностью игнорируют инструменты пользовательского интерфейса.
3.) Больно отлаживать, так как нет указания на то, где скрипт связан.


Скрипт ВТФ:

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

MeshInstance (узел) с пустым узлом сверху позволяет легко перемещать и изменять дизайн дочерних элементов.
--- Сетка (Сетка + Сценарий || Сигнал)
--- Материал (Спрайт + Сценарий || Сигнал)
--- Преобразование (Position3D +Script || Сигнал)

Когда дерево должно соединить объекты глубиной 2 сцены и более, вместо этого будет использоваться группа. Примечательным в этом рабочем процессе является наличие неглубоких деревьев.
Проблемы:
1.) Сигналы и группы позволяют целым частям игры просто терпеть неудачу без предупреждения.
2.) Мелкие бессмысленные скрипты просто слоняются. Все, что они делают, это отправляют сигнал и отслеживают одно значение.
3.) Перемещение объекта с таким количеством подключенных сигналов как минимум разочаровывает.
4.) Конфликты с системой экземпляров. Потому что экземпляры текут вниз, а сигнал лучше всего соединяется вверх.

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

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

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

archived discussion core

Самый полезный комментарий

Если вопрос звучит просто: «Есть ли несколько способов добиться одного и того же результата в Годо?», ответ — да. И пытаться навязать единый рабочий процесс абсурдно, поскольку у каждой системы в игре могут быть разные требования. Вы не программируете так же, как систему, которая требует много производительности, и систему, которая требует частого обновления геймдизайнером. У всех решений есть компромиссы, поэтому нет смысла создавать «официальный» рабочий процесс.

Все 63 Комментарий

Если вопрос звучит просто: «Есть ли несколько способов добиться одного и того же результата в Годо?», ответ — да. И пытаться навязать единый рабочий процесс абсурдно, поскольку у каждой системы в игре могут быть разные требования. Вы не программируете так же, как систему, которая требует много производительности, и систему, которая требует частого обновления геймдизайнером. У всех решений есть компромиссы, поэтому нет смысла создавать «официальный» рабочий процесс.

может сделать класс таким же сложным, как MeshInstance, с несколькими компонентами

С какими именно компонентами?

РЕДАКТИРОВАТЬ: И просто чтобы вы знали, одна из проблем, которые вы цитировали, была закрыта автором, заявившим: «Эта идея действительно и совершенно отстой и совершенно бессмысленна».

Чтобы продемонстрировать это, я буду использовать фиктивный класс того, как будет выглядеть MeshInstance, созданный в Godot.
Есть псевдо Unity, он же дочерние узлы:
Пользователи Godot используют дочерние узлы для создания эквивалента MultiScripts.
Pseudo Unreal, он же контроллеры и промежуточные:
Псевдо Panda3D, он же Preload(Script):
Скрипт ВТФ:
Да, я знаю, что у Godot есть класс MeshInstance.
Это демонстрирует то, что большинство рабочих процессов, используемых разработчиками прямо сейчас, могут сделать класс столь же сложным, как MeshInstance, с несколькими компонентами; за исключением того, что каждый рабочий процесс имеет серьезные недостатки.

Я не совсем понимаю, что вы пытаетесь сказать здесь. Зачем кому-то создавать класс MeshInstance, если он уже есть? И почему проблема в том, что Godot имеет функции, аналогичные другим движкам? Кроме того, если вы пытаетесь прикрепить несколько скриптов к одному узлу, вы либо не используете ООП, либо помещаете две отдельные функции в один узел, что легко исправить с помощью системы узлов Godot.

Если вопрос звучит просто: «Есть ли несколько способов добиться одного и того же результата в Годо?», ответ — да...

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

Вот где Годо, разработчики качаются в темноте, надеясь, что как-то это позволит им что-то создать.

С какими именно компонентами?

Такие вещи, как материалы и преобразования, считаются ли они частью исходного экземпляра или нет?
Если мы создадим похожие компоненты, как мы прикрепим их к узлу?

А как насчет других задач, таких как «следовать за целью» или «стрелять по цели», их следует добавить в класс или как-то прикрепить?
Так как Godot никогда не делал правильных функций Include или Import для Godot, значит ли это, что он никогда не предназначался для использования таким образом?

Мы знаем, что не можем иметь все, поэтому вопрос в том, что у нас есть? Как это работало?

@MysteryGM Свободные и несвязанные аналогии бесполезны.

Такие вещи, как материалы и преобразования

Преобразование — это пространственное свойство, а материалы — свойство сетки. MeshInstance построен поверх Spatial, поэтому он наследует все свойства Spatial. Это простая иерархия, которая имеет смысл для меня.

Если мы создадим похожие компоненты, как мы прикрепим их к узлу?

Зачем вам создавать свою собственную Mesh-систему, если они уже есть у Godot?

А как насчет других задач, например, "следить за целью" или "стрелять по цели"?

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

Зачем вам создавать свою собственную Mesh-систему, если они уже есть у Godot?

Потому что игровые объекты так же сложны, как сетка, если не более того. Помните, что движки, где часть игр оригинальна, это просто повторно использованная часть.

Если Godot не может эффективно создать класс Mesh внутри движка, то его нельзя использовать для создания сложных игр. Все игры должны быть менее сложными, чем движок.
Это, в свою очередь, означает, что он бесполезен для профессиональной команды разработчиков. Если только такая команда не использует C++ только с исходным кодом.

Код идет в скриптах.

Но каким образом?
Я уже знаю, что не могу создать дочерний элемент для каждого скрипта, потому что мне понадобится более миллиона функций, и даже миллион пустых узлов — это слишком много для Godot.
Что это значит, сколько функций нужно сгруппировать или я должен потратить 2-4 месяца на планирование наследования объектов на бумаге?

Я хочу знать, как Godot справляется с большими играми со сложными системами, такими как погодные эффекты, объемный туман и большие ландшафты?

Нижеследующее относится ко мне, моему мнению и опыту, _YMMV_

У каждого двигателя есть свои особенности, и Годо не исключение. Честно говоря, учитывая, сколько времени прошло с момента его первого стабильного выпуска, я определенно ошеломлен тем, насколько он хорош и как быстро он развивался. Это может быть причиной некоторых наших проблем. Система сцен/узлов — моя любимая часть, простота заскриптованных узлов — это то, что мне больше всего нравится. Несмотря на то, что у него есть свои недостатки для меня, мне не нравится синтаксис, похожий на python... и система предварительной загрузки... не могу понять, как заставить работать C#.

Возьмем, к примеру, Unity 4/5 (к которому я был привязан в течение многих лет), и его _компоненты_ настолько раздуты, что его нельзя сравнить ни с одной другой ECS, которую я когда-либо использовал. И о, вы хотите сделать http-запрос? Конечно, добавьте новый компонент к новому объекту в структуру вашей сцены, потому что имеет смысл связать HTTP-запросы с объектами сцены и ее компонентами. Функция «сохранение сцены без изменений ломает все UUID», казалось, была придумана только для того, чтобы нашим нетехническим дизайнерам было сложнее использовать контроль версий. Я даже не хочу начинать «Не уничтожать при загрузке» и префабы.

В любом случае, в чем была причина большинства этих вещей? Я бы сказал, что это, вероятно, органическая, итеративная разработка и некоторые хакерские обходные пути здесь и там (также найденные в Godot и, вероятно, во всех других игровых движках). Я имею в виду, что он так сильно падал, что моя Swift Keyboard начинала предсказывать слова «_Unity crashing_» каждый раз, когда я набирал «_With_». Это была основная часть моего рабочего процесса, сбой -> повторный импорт всех активов на минуту, работа на 30 минут, повтор.

Я видел так много кощунственного использования моноповедения, но кого я могу винить? Движок позволяет людям помещать _GameState_ "_component_" внутри объекта точечного освещения. Должны ли мы запрещать это? Как я могу утверждать, что данные о состоянии игры не должны находиться даже внутри компонента объекта сцены, когда в нем нуждается HTTP-связь (или практически любая асинхронная работа)?

Это подводит меня к мысли, что сравнивать движки на разных стадиях разработки сложно, и действительно Godot быстро развивается и добавляет/удаляет функции. Это означает, что наш рабочий процесс должен будет соответствующим образом измениться и адаптироваться. У меня есть достойный рабочий процесс 2D с Godot, он определенно лучше, чем тот, который у меня был с Unity. Да, лучшие практики туманны. Да, если вы спросите трех разработчиков, у вас будет три разных рабочих процесса. Но я не могу сказать, что это новая проблема для меня, или, по крайней мере, она присутствует на обоих сравниваемых двигателях.

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

Но каким образом?
Я уже знаю, что не могу создать дочерний элемент для каждого скрипта, потому что мне понадобится более миллиона функций, и даже миллион пустых узлов — это слишком много для Godot.
Что это значит, сколько функций нужно сгруппировать или я должен потратить 2-4 месяца на планирование наследования объектов на бумаге?

Возможно, поместить все функции в один скрипт? Godot можно использовать как объектно-ориентированный, поэтому, если вы когда-либо использовали ООП, вы можете использовать наследование сценариев или сцен, создавать классы и так далее.

Я хочу знать, как Godot справляется с большими играми со сложными системами, такими как погодные эффекты, объемный туман и большие ландшафты?

Погодные эффекты? Создайте сцену, содержащую узел частиц, солнце и мировую среду, и прикрепите скрипт к корню. Этот скрипт может управлять погодой. Вы также можете создать пустой узел и использовать его как конечный автомат, присоединяя пустые узлы для каждого состояния, которое у вас есть (например, дождь, солнце и т. д.). Теперь просто поместите код для каждого состояния в свои узлы. Этот конечный автомат может управляться корневым скриптом. Это очень простой для чтения способ ведения дел.

Объемный туман? Кажется, я видел это в новой демо-версии FPS.

Большие территории? Однажды у меня был проект с процедурными сетками ландшафта, и он довольно гладко работал на моем ноутбуке, которому пару лет.

Это всего лишь некоторые функции, а не «большая проблема», о которой вы говорите в ОП.

Погодные эффекты? Создайте сцену, содержащую узел частиц...

Ну, мы планируем быть немного более амбициозным, чем это :) с картой региона, чтобы сообщить ИИ, где идти, а затем использовать другой канал для зон исключения дождя, сохраняя при этом последний канал для глубины, чтобы снег мог накапливаться с течением времени.

Большие территории?

Пространство большое. Нам нужен какой-то способ сбросить сцены к Vector3(0,0,0) без зависаний, потому что нужно удалить слишком много узлов. Физика и все качается большими поплавками.

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

Согласитесь, компоненты могут быть ужасными, поэтому нас не удивит, если у Годо будет другая стратегия. Однако мы понятия не имеем, какую стратегию спланировал Годо и был ли он вообще реализован.

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

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

@MysteryGM Я действительно не понимаю, почему вы думаете, что Годо нельзя использовать для больших проектов. Его дизайн действительно подходит для больших проектов, потому что вы можете разделить все на отдельные сцены и использовать ООП для повторного использования работы. Если ваша проблема с использованием Godot для большого проекта заключается в том, что вы не знаете, как достичь цели, просто спросите на справочных каналах Godot Discords, и вы получите немедленный ответ.

Физика и все качается большими поплавками.

См. № 288

Однако мы понятия не имеем, какую стратегию спланировал Годо и был ли он вообще реализован.

Я понимаю, что поначалу это немного чуждо, но для меня использование node + script довольно просто. Я определенно рекомендую взглянуть на (по крайней мере) версию этого курса для хобби здесь: https://gumroad.com/gdquest
Он использует структуру сценария узла, очень похожую на мою, и определенно может дать вам лучшее представление о том, как его используют те, кто действительно связан с движком; автор вносит основной вклад в документацию godot.

редактировать: На самом деле, вы можете взглянуть на источник в репозитории, если вы не хотите, чтобы курс https://github.com/GDquest/make-pro-2d-games-with-godot

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

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

Кроме того, несмотря на то, что вы перечислили все проблемы со всеми вышеперечисленными системами, я думаю, что реальность любого крупного программного проекта такова, что каждый «выбор» архитектуры, который вы делаете, приведет к некоторым недостаткам в будущем, которые вам просто нужно решить. больше работать с по пути. Итак, вы ищете серебряную пулю? Потому что, честно говоря, я даже не думаю, что большинство проектов Unity или Unreal следуют точной «рекомендуемой» структуре и часто разветвляют движок, чтобы он соответствовал тому рабочему процессу, который лучше всего подходит для них. Я бы даже сказал, что каждая игра должна иметь свое собственное уникальное представление об архитектуре узлов. (Игра-симулятор будет иметь совершенно другую структуру, чем, например, шутер от третьего лица.)

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

отдельные сцены и использовать ООП для повторного использования работы.

Как я упоминал ранее, перемещение объектов после того, как сигналы были подключены, — это боль. Особенно, когда они перестают работать без каких-либо исключений или предупреждений.
Мы решили использовать сторонний инструмент рефакторинга после того, как другой разработчик упомянул об этом; но даже в этом случае он не может решить уникальные проблемы Годо.
Неподвижные вещи приводят к этой проблеме (изображения с нашей «доски задач»):
pawndefend
Поэтому, чтобы исправить это, мы создали дочерние узлы. За исключением того, что около 50 000 он начинает вызывать проблемы, даже если это просто узлы.
pawnfollow

Мы хотим знать, как мы справляемся с этими проблемами, как Годо планировал с ними справиться; мы протестировали каждый рабочий процесс, о котором я упоминал выше.

См. № 288

Спасибо за это, мы так привыкли к покоящимся мировым координатам, что никогда не проверяли это.

Я понимаю, что поначалу это немного чуждо, но для меня использование node + script довольно просто.

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

Зачем вам в игре 50 000 объектов? Конечно, это отставало бы от ЛЮБОГО двигателя.

Зачем вам в игре 50 000 объектов?

Потому что мы используем узлы для добавления дополнительных скриптов к объектам. Потому что инструменты пользовательского интерфейса Godot используют контейнеры в контейнерах в контейнерах... для масштабирования в реальном времени.
Наш самый маленький пользовательский интерфейс содержит более 800 объектов. Большинство таких контейнеров.

У нас есть 50 000 объектов, потому что один вражеский ИИ — это +/-8 узлов с целью и +/- 64 узла, которые только там есть, чтобы мы могли прикрепить к ним скрипты.
Потому что, разбивая каждую задачу на отдельный код, мы можем увидеть, где наши проблемы. Потому что другого способа быстро найти конкретную часть игры нет.

В этом случае кажется, что вы проникли в зону, где пользовательские модули являются хорошим вариантом.
http://docs.godotengine.org/en/3.0/development/cpp/custom_modules_in_cpp.html
Вы можете создавать там пользовательские узлы и избегать большого количества вложений.

edit: хотя я бы сказал, что 800 объектов для одного (самого маленького?) пользовательского интерфейса указывают на плохой дизайн/архитектуру.

Я серьезно не понимаю, как можно иметь где-то около 64 сценариев для одного объекта. Это больше похоже на проблему дизайна вашего проекта, чем на проблему Годо (опять же, вероятно, отставание любого движка). Объедините свой код в меньшее количество сценариев. Не создавайте сценарий для каждой части функциональности, а вместо этого для каждого типа объекта (если узел «Враг» может выполнять XYZ, добавьте эту часть в сценарий врага вместо добавления дочерних узлов для функций X, Y и Z) . Если для этого вам нужны более продвинутые функции, возможно, вы могли бы использовать настраиваемое наследование и/или интерфейсы C#.

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

Видите ли, это было одной из вещей, о которых мы задавались вопросом, потому что все мы знаем C++, если потребуется Custom Modulse, мы вместо этого просто отредактируем движок Godot.
Мы знаем, что можем безопасно использовать #include там, где предварительная загрузка Godot() сомнительна; никто не может сказать нам, насколько он стабилен или есть ли какие-либо недостатки.

Я серьезно не понимаю, как можно иметь где-то около 64 сценариев для одного объекта.

Просто каждый ИИ может выполнять более или менее 64 задачи, а не второстепенные задачи.
Скрипт, например, SquadFlightPatters, и здесь есть все формации полета, все 20 из них, затем есть SquadFlightPattersCosmetic, который разрешает только анимацию, звук и частицы, связанные с моделями полета.

Наше правило на данный момент — отделять отзывы пользователей от механики.

Если узел «Враг» может выполнять XYZ, добавьте эту часть в сценарий врага вместо добавления дочерних узлов для функций X, Y и Z.

Если вы посмотрите на изображения и Pseudo Unreal, они же контроллеры и промежуточные.

поскольку все мы знаем C++, если потребуется Custom Modulse, мы вместо этого просто отредактируем движок Godot.

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

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

В ответ на упомянутые проблемы в OP:

  • 19486 :

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

    Классы скриптов решают последнюю проблему. Пространства имен можно создать, создав класс сценария верхнего уровня с константами, которые служат псевдонимами для других сценариев. Изменения, которые я внес в док сцены редактора в версии 3.1, также значительно упростили расширение пользовательских сценариев. Что касается межъязыкового наследования, то оно никогда официально не будет реализовано, но если мультискрипты когда-нибудь снова будут введены, то они могут достаточно хорошо его подделать.

  • 7402 : Опять же, классы сценариев являются решением этой проблемы («более простое решение», о котором подумал Редуз, если вы видите некоторые из последних комментариев к этому выпуску).

  • 15996 : Это было то, что я понял, что то, что я хотел, было системой черт (до того, как я понял, что такое черты), и, следовательно, понял, насколько ужасным было мое первоначальное предложение, поскольку оно полностью искажает целевой дизайн сцен и узлов и преобразует весь в систему наследования на основе композиции - что-то более похожее на то, что на самом деле делает Unity, что отвратительно (в Unity вы можете использовать getComponent из любого COMPONENT, и он извлекает компонент-брат на владеющем GameObject. Компоненты, на практике, являются расширение GameObject, накладывая свои зависимости друг на друга).

  • 8502 : MultiScript — это просто инструменты, позволяющие различным языкам сценариев наследоваться друг от друга, подобно тому, как Blueprints UE4 могут наследоваться напрямую от сценариев C++ (что в Godot было бы невозможно, поскольку сравнение заключается в том, что GDScript расширяет NativeScript. VisualScript вообще не поддерживает наследование, поэтому GDScript здесь является более подходящим сравнением).

    Теперь, поскольку MultiScript по существу поддерживает ЛЮБОЙ скрипт, который расширяет базовый тип движка (так что у вас может быть несколько скриптов, расширяющих Node, из разных языков, которые делают разные вещи, но не связаны друг с другом), он на самом деле работает почти так же, как межъязыковая система признаков... вроде того. Я думаю, что повторное добавление MultiScript было бы довольно круто.

Многие из вопросов, поднятых в ОП, связаны с наличием нескольких потенциальных способов решения проблемы, каждый из которых может иметь различную неэффективность. Обычно, когда есть конкретный способ сделать что-то наиболее оптимальным, движок предоставляет свою собственную реализацию в основном движке C++ (нет необходимости в скриптах или плагинах), и это предлагаемое использование.

Если такой класс существует и люди его не используют, то это признак того, что 1) они не проверяют должным образом документацию, чтобы убедиться, что их потребности уже удовлетворены движком / как движок предлагает его использовать или 2) движок/организация недостаточно хорошо делает документацию доступной для пользователей (поскольку они не находят существующие ресурсы).

Единственное, что нужно сделать для решения проблемы 1, — это чтобы эти люди озвучили свою проблему, а кто-то другой перенаправил их на документацию или сайт вопросов и ответов, чтобы помочь им найти решение. Я создал проблему (# 23043), которая предлагает разрешить людям просматривать и использовать сайт вопросов и ответов непосредственно из редактора, что должно сильно помочь с проблемой 2. Причины описаны в ссылке.

(Редактировать: если есть много способов решить проблему, и один из этих способов намного лучше, чем любой другой, и Godot еще не реализовал для него свое собственное решение, то это можно было бы предложить в качестве новой функции. для движка.Вот как мы добавили материал SimplexNoise, так как люди писали свои собственные алгоритмы SimplexNoise в коде GDScript / шейдера и т. д.).


Основываясь на изображенной вами «проблемной доске», проблема, с которой вы столкнулись, заключается в том, что множественное наследование не поддерживается (и это не является хорошей идеей), поэтому вы выбрали узлы компонентов, которые предоставляют функциональность своему родителю (что звучит разумно для меня). Если вы сталкиваетесь с проблемами, связанными с отставанием игры из-за того, что она просто создает слишком много узлов, то мне кажется, что более чем вероятно проблема с вашим общим подходом (это то, что вы, кажется, признаете и ищете помощи). для идентификации здесь).


Что касается ваших примеров рабочих процессов в OP...

  • Подход Unity, дочерние узлы:

    Имеет смысл использовать дочерние узлы, предполагая, что один из них пишет логику сопряжения. Это идеальное место, где система признаков была бы полезна (чтобы можно было один раз написать логику спаривания и просто реплицировать ее везде по мере необходимости). Я часто пишу компоненты таким образом, чтобы они автоматически устанавливали себя в качестве «целей» для своих родителей, когда они являются родительскими/неродственными, и автоматически подключают/отключают соответствующие сигналы. Для этого вы можете использовать уведомления NOTIFICATION_(UN)PARENTED в _notification(what) .

  • Подход UE4 с контроллерами:

    Godot 3.1 позволяет вам назначать классы сценариев для сценариев, поэтому их больше не нужно предварительно загружать. В этом случае Godot ДЕЙСТВИТЕЛЬНО позволяет вам назначать имена типов узлам, но это зависит от сценария, поэтому вы должны быть осторожны. Сцены не получают такой же обработки и, вероятно , не будут, поскольку это потребует добавления множества вещей в ядро ​​​​движка (которое разработчики ядра могут быть довольно обидчивыми).

    Я также не уверен, как вы получаете столько повторяющегося кода? Если для нескольких классов требуется одна и та же логика, вы объединяете эту логику в один узел, а затем воспроизводите этот узел в классах, которые в нем нуждаются, так же, как в случае с Unreal (компоненты, дочерние акторы), Unity (MonoBehaviours или дочерние объекты GameObject). , или почти любой другой движок, который переносит зависимости на принадлежащий объект, чтобы уменьшить повторное использование кода.

  • Подход Panda3D с предварительной загрузкой:

    Я мог понять, что с этим подходом много проблем, поскольку NodeRefs еще не вещь, и есть проблемы с экспортом скриптов ресурсов на данный момент, которые я надеюсь исправить для 3.2 (хотя вы, вероятно, могли бы сделать исправление самостоятельно достаточно легко, это довольно мало).

  • Подход сценария WTF:

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

    Конфликты с системой экземпляров. Потому что экземпляры текут вниз, а сигнал лучше всего соединяется вверх.

    Когда вы хотели бы, чтобы у потомка было поведение триггера родительского сигнала? Почему бы просто родителю не получить и не вызвать потомка и его метод напрямую? Нет никакой опасности, что родитель увидит своего ребенка. Это все равно, что сказать, что объект C++ не должен иметь доступа к своей структуре или переменным-членам класса (?).

    Маленькие бессмысленные скрипты просто слоняются. Все, что они делают, это отправляют сигнал и отслеживают одно значение.

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

    Перемещение объекта с таким количеством подключенных сигналов как минимум разочаровывает.

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

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

    Таким образом, проблема с любым булевым дизайном существования. Альтернативой является перебор ВСЕХ объектов, проверка, соответствуют ли они критериям, а затем выполнение логики, если они совпадают, и, если они совпадают, но не должным образом, выдается ошибка. В случае сигналов и групп поведение запускается для всего в наборе автоматически, поэтому, если что-то выпадает из набора, невозможно обнаружить, что проблема возникла во время выполнения. Единственный способ найти проблемы такого рода — это во время процессов настройки, когда группы/сигналы упорядочиваются в первую очередь.


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

В любом случае, проблемы, которые вы здесь подняли, не кажутся «новыми» проблемами с дизайном или реализацией Godot Engine как таковыми. Godot предоставляет людям API, и то, как люди используют этот API, зависит от них самих. Если у вас есть идея, как сделать конкретную функцию более интегрированной/доступной в Godot (например, оживить MultiScript), то это будет прекрасным предложением.

Однако в нынешнем виде вопрос здесь скорее сводится к тому, «какой лучший способ спроектировать систему, подобную X», что… на самом деле не является проблемой GitHub. Кажется более подходящим на сайте вопросов и ответов для вопросов типа «лучшие практики». Это или это предложение о том, что мы должны предоставить возможность сделать такого рода информацию, относящуюся к конкретному варианту использования, более ясной / общедоступной, и это именно то, о чем мой выпуск вопросов и ответов.

Классы скриптов решают последнюю проблему.

Во-первых, спасибо за длинный ответ, это много и явно заняло некоторое время, чтобы написать.
Я рад услышать о классах сценариев, мы не использовали 3.1; только для запуска демо FPS.

но если мультискрипты когда-нибудь будут повторно введены, то они могут достаточно хорошо их подделать.
Вполне понятно, что Godot никогда не реализует мультискрипты. По правде говоря, я просто указал, что многие пользователи GitHub искали похожие решения для рабочих процессов, которые мы пробовали.

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

Я чувствую, что должен объяснить это. В то время у нас были очень большие сценарии, в каждом из которых было примерно +/- 30 функций. По этой причине мы хотели избежать добавления дополнительных сигнальных функций к уже большому сценарию.
В результате мы создали свободные сценарии, чтобы снять нагрузку с большого сценария.

Это уже признак того, что дизайн проекта не очень хорош.

Это действительно корень проблемы. Главным образом то, что мы попробовали множество дизайнов, рекомендованных сообществом Godot, а также некоторые из руководств.
1.) Поначалу у нас были безумные наследства, от которых быстро отказались, когда стало ясно, что при сохранении ветки сцены или перемещении объекта в другую сцену отключаются сигналы.
2.) Мы последовали этому примеру с большими скриптами. За исключением абстрактных названий этих сценариев, чтобы попытаться объяснить, что каждый из них делает, трудно найти проблемы.
Мы знали, как называются функции, вызывающие проблемы, но не знали, где именно они расположены.
3.) Затем, прочитав руководство, мы нашли подход к дочернему узлу. Возможно, это было слишком заманчиво, потому что допускало прямые узлы, и мы могли видеть структуру в редакторе; также отфильтруйте его, чтобы найти именно тот скрипт, который нам нужен.

В конце концов, я здесь, и я думаю, что последний ответ затрагивал многое из того, о чем я задавался вопросом; Я должен буду перепроверить завтра, так как здесь 2 часа ночи.

«Как лучше спроектировать систему, подобную X», что… на самом деле не является проблемой GitHub.

Я хочу отметить, что мы исчерпали большинство наших других вариантов. Каждый из нас поспрашивал на форумах вопросов и ответов, мы завели друзей в сообществе и собрали у них примеры. Просмотрел документы в поисках объяснений.
Все рабочие процессы, которые я описал, — это то, что мы пытались объяснить пользователям Godot, которые используют эти рабочие процессы. Каждый из них будет работать в упомянутых двигателях, просто в Godot они не работают так хорошо.

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

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

Главным образом то, что мы попробовали множество дизайнов, рекомендованных сообществом Godot, и некоторые из руководств.

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

Следуя тому, что @willnationsdev сказал ранее, возможно, стоит подумать о внутреннем коде, чтобы помочь масштабировать игру, как с точки зрения производительности, так и просто для того, чтобы иметь меньше кода для управления в самом редакторе. Кроме этого, я ничем не могу помочь, так как, как и многие здесь, у меня нет опыта работы с более крупными проектами. Удачи!

Привет, у нас есть еще один вопрос.

Если у нас есть два несвязанных объекта, например, здание и вода, но мы хотим, чтобы скрипты этих объектов взаимодействовали, как нам это сделать без нод или предварительной загрузки?
Вода — это текстура, поэтому она также не может столкнуться со зданием.

@MysteryGM Вы говорите, что вам не нужны узлы, представляющие здание и воду, или вы просто не хотите, чтобы к ним были прикреплены сценарии? Нет ничего плохого в том, чтобы иметь данные для обработки, которые каким-то образом не существуют в дереве сцены, кроме единственного узла, содержащего данные.

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

Имея 50 000 чего угодно , вы уже давно превысили точку, в которой объектно-ориентированная метафора Godot's SceneTree-and-nodes является полезной.

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

Во всех движках решение в основном одинаковое: создавайте свои собственные решения. Что это такое, зависит больше от вашей игры, архитектуры и деталей, чем от движка.

Классы менеджеров, коммуникационные шины pub-sub, брокеры сообщений, менеджеры экземпляров, аналогичные тем, что делаются для частиц, пулы объектов, пользовательские шейдеры для переноса работы на GPU, вычислительные шейдеры, перемещение обработки в потоки или другие процессы/серверы — есть тонн строительных блоков для возможных решений, и какие из них вам нужно будет объединить, зависит от вашего конкретного набора проблем.

Unity упрощает эту задачу благодаря своей новой инфраструктуре ECS. Насчет UE4 не уверен. Однако в конце, на этом продвинутом уровне, вам придется выполнять большую часть тяжелой работы самостоятельно (или нанять кого-то опытного, чтобы он сделал это за вас).

UE4 и Unity проще только потому, что они старше, более устоялись, и, следовательно, большее количество людей сталкивается с такими проблемами масштабирования, а это означает, что для их решения доступно больше знаний (и нанимаемых талантов).

Но на самом деле, в конце концов, ни один двигатель не унесет вас так далеко. Каждая амбициозная игра столкнется с ограничениями на любом движке. Я знаю множество примеров для средних и крупных игр в UE или Unity, которым также нужно было решать подобные проблемы. Либо решите их, либо уменьшите масштаб.

Что нужно разработчикам игр Godot от разработчиков Engine, так это явное замедление официального рабочего процесса для создания сложных объектов и систем.

Это во многом зависит от вашей игры. В любом большом двигателе нет прямого ответа на этот вопрос.
Стоит ли использовать в Unity подход, основанный на игровых объектах и ​​сценах? Или гибрид ECS? Полная новая ECS? Какой конвейер рендеринга вы используете?
Будете ли вы использовать Blueprint или C++ в своем проекте UE4?

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

Поэтому, если вам нужен конкретный совет о том, как подойти к вашей конкретной игре в Godot, как ее структурировать, какую архитектуру использовать, вам нужно предоставить гораздо больше контекста и информации.

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

Я могу только согласиться с Гроудом:

У всех решений есть компромиссы, поэтому нет смысла создавать «официальный» рабочий процесс.

@mhilbrunner Просто играя в защитников дьяволов, но лучший дизайн движка (например, правильная ECS в большинстве случаев, когда важна производительность) делает многие из этих ограничений значительно выше, чем почти любая игра на самом деле когда-либо испытывала (именно так новый Rust Amethyst игровой движок разрабатывается, чтобы сосредоточиться, например).

Но да, я сделал что-то похожее на ECS в Godot (2), и это работало намного лучше, чем стиль создания экземпляров scenetree с точки зрения эффективности и распределения функциональности. Это можно сделать, но немного болезненно, так как в Годо для этого не хватает некоторых полезных примитивов.

@OvermindDL1

Я могу говорить только за себя, а не за других разработчиков Godot, и у меня есть опыт работы только с UE, Unity и Godot, поэтому я ничего не знаю о Rust Amethyst.

Это можно сделать, но немного болезненно, так как в Годо для этого не хватает некоторых полезных примитивов.

Обсуждение того, где имеет смысл добавить такие примитивы / как Godot может лучше приспособить такие варианты использования, было бы очень ценным, я думаю. Может не в этом вопросе :)

Но мы должны каким-то образом собрать эту обратную связь.

И я согласен с тем, что существуют разные ограничения в зависимости от движка, но опять же, я видел, как люди сталкивались с аналогичными барьерами в Unity и UE4. Может быть , позже, может быть, они были выше, но в конце вам нужно будет решать проблемы, с которыми вы сталкиваетесь в любом движке. :)

@MysteryGM Вы говорите, что вам не нужны узлы, представляющие здание и воду, или вы просто не хотите, чтобы к ним были прикреплены сценарии?

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

У обоих объектов уже есть код, что мне теперь делать? Я не могу добавить больше узлов, и до сих пор неясно, является ли предварительная загрузка возможным решением.

Мой вопрос, если я сформулирую это как дизайн ООП: как два скрипта получают доступ к интерфейсам друг друга?

Проблема в том, что GDscript не имеет прямого доступа к другим скриптам.
Если я хочу, чтобы Огонь сжигал Древесину, я должен иметь либо Древесину->продлить->Огонь, либо Огонь->расширить->Дрова.

@MysteryGM : один совет: сигналы. Огонь может иметь сигнал ожога (цель), где целью является ваше дерево.

Как два скрипта получают доступ к интерфейсам друг друга?

$NodeWithScript.do_function() ?

_/я все еще играю в адвоката дьявола, не принимайте это как меру того, что "должно" быть сделано в Годо, в лучшем случае это сбрасывание велосипедов_

Я могу говорить только за себя, а не за других разработчиков Godot, и у меня есть опыт работы только с UE, Unity и Godot, поэтому я ничего не знаю о Rust Amethyst.

UE использует модель Actor SceneTree. Unity использовала модель EC (хотя недавно они создали ECS и отказались от старой модели EC, она еще не совсем завершена, но выглядит многообещающе). А Godot использует модель Component SceneTree. ECS — это подмножество шаблона потока данных (в частности, его обобщение).

Краткий обзор ECS:

  • «Entity» — это просто целочисленный идентификатор, хотя большинство движков упаковывают генерацию и индекс сущности в один int32 (8-битная генерация и 24-битный индекс) или int64 (32-битная каждая, int64 значительно более распространен, поскольку ECS фактически позволяет вам для масштабирования до такого значительного количества сущностей).

  • «Компонент» — это структура POD в терминологии C /C++, она ни в коем случае не должна содержать функциональность. Как правило, это должно быть тривиально memcpy'able.

  • «Таблица» компонентов — это хранилище для компонентов, в большинстве случаев это может быть просто массив с изменяемым размером, но обычно используются несколько типов:

    • Массив с изменяемым размером: часто используется, когда компонент очень распространен, например, позиция.
    • Разреженный массив: часто используется, когда компонент имеет тенденцию использоваться в группах сущностей одновременно.
    • Отображение: возможно, хешированная карта или карта дерева или что-то в этом роде, в зависимости от ожидаемых характеристик производительности, но обычно используется для менее распространенных компонентов.
    • Наборы битов: используются исключительно как определение того, существует ли компонент в объекте вообще, но ничего не хранит, обычно известный как компонент флага.
    • Octree или какой-либо другой SceneGraph (здесь может подойти средство визуализации Godot): отображение дерева сцен, которое притворяется компонентом.
    • И т. д.: Многие другие типы в зависимости от характеристик доступа и производительности, ожидаемых для компонента.
  • « Система » — это, по сути, функция, которая принимает объединенный набор компонентов, хотя в большинстве библиотек это не виртуальный класс или модуль или что-то в этом роде, она работает с этим объединенным набором компонентов, чтобы «делать» что-то, что может включать изменение значений в компонентах, добавление или удаление компонентов и т. д. Некоторые примеры:

    • Система, которая берет все объекты с компонентом «Позиция» и «Преобразование» и эффективным и удобным для кэширования способом преобразует все матрицы позиций с преобразованиями, необходимыми в заданный тик/время. Когда преобразование больше не требуется (сущность становится статической), компонент Преобразования удаляется из сущности, и она больше не обрабатывается.
    • Система ввода прослушивает события ввода (мышь/клавиатура/геймпад/и т. д.) и преобразует их в компоненты, добавляемые к соответствующим объектам или для выполнения других действий.
    • Система печи (метафора Minecraft) берет сущности, у которых есть Inventory, Fuel, RecipeMapping, BlockPos, Cooking и другие компоненты, перебирает эти сущности и обновляет соответствующие состояния по мере необходимости, пока больше нечего готовить, а когда заканчивается топливо, она удаляется. Компонент Cooking Flag, чтобы он больше не обрабатывался до тех пор, пока инвентарь не будет снова изменен, чтобы установить любые компоненты флага.

Внутренне вы можете думать о ECS как о базе данных, где вы можете подписаться на набор сопоставлений данных, хотя, если они хорошо сделаны, они чрезвычайно хорошо оптимизированы. Зная, какие системы должны работать перед какими другими системами и какие системы работают поверх неперекрывающихся (в зависимости от чтения или чтения/записи), вы также можете тривиально выполнять многопоточные вызовы. (Я продолжаю использовать Amethyst и его специфичную для ECS библиотечную часть под названием specs в качестве примера, потому что я приложил руку к ее созданию, перенеся свою старую библиотеку C++ ECS ). Как, эффективность, использование и т. д. Amethyst подробно описывает, как использовать ECS с общими игровыми системами, рендерингом и т. д.

Если вы хотите увидеть хорошо написанную библиотеку C++ ECS, посмотрите на https://github.com/skypjack/entt , так как из всех библиотек C++ ECS, которые я видел, которые я не делал, она кажется лучшей. в целом (хотя спецификации по-прежнему превосходят его в моих простых тестах, хотя и ненамного, что впечатляет, учитывая, что спецификации превосходят все, с чем я когда-либо сравнивал, со значительным отрывом).

Общее «использование» ECS заключается в том, что у вас есть «сущность» (просто целое число, без данных), и у вас есть набор таблиц, которые сопоставляют компоненты с сущностями, и системы для фактического выполнения работы. В псевдокоде GDScript я бы предположил, что это простой API, хотя и с немного странным соглашением об «интеграции» в дерево сцен Godot, поскольку дерево сцен не было разработано с учетом этого.

# All of this would generally be wrapped up in one or more function calls for easy
# building.

# Create a new entity
var e = createEntity()

# Map it to some Components, starting with a godot scenetree component
# I'm using long names to be descriptive, but eh...
var eNode = scenetreeComponentTable.set(e, SomeNodeType())
# Generally things like the transformation matrix and so forth would be their own
# components, but since the godot scenetree already bakes all that in then just
# deal with it all via the node type, you definitely lose a little efficiency doing
# it this way though since nodes involve multiple virtual calls to access and
# the usual ECS patterns entirely get rid of virtual calls with potentially only
# the occasional indirect calls inside a table (maps, etc...)

# 8x4 inventory slots
inventoryComponentTable.set(e, 8, 4)
# 1 fuel slot, accepts items that have the "burn" tag
fuelStorageComponentTable.set(e, 1, "burn")
# Give this entity the furnace component that uses the "basicFurnaceRecipes" recipes
furnaceComponentTable(e, "basicFurnaceRecipes")
# Add other components

# All of the above component mappings could also be in, say, a JSON file, and
# loaded something as such:
componentTables.map(e, "res://entity_types/basicFurnace.json")
# Or maybe via a preloaded JSON object or so

# Once at startup:

# And you could make a system something like, I'll use a GDScript class for this:
val furnaceCookSystemHandler = systems.register(FurnaceCookSystem.new())
furnaceCookSystemHandler.staticTickRate(0.05) # 20 times a second exactly

# Where the `FurnaceCookSystem` could be something like:
class FurnaceCookSystem:
  def _entity_matchers():
    furnaceBurnMatcher =
      componentTables.matcher().
      write(inventoryComponentTable).
      write(fuelStorageComponentTable).
      writeEither(inventoryChangedComponentTable, furnaceCookingComponentTable)
      read(furnaceComponentTable)
    return [furnaceBurnMatcher]

  # Assume we have matching semantics here to destructure a list, I'm lazy...
  def _entities_process([furnaceBurnEntities], delta):
    # This function takes a list of entity sets in the same order as the matchers
    # returned above.
    while entity in furnaceBurnEntities:
      val furnace = furnaceComponentTable[entity] # or .get(entity) or whatever API
      val cooking = furnaceCookingComponentTable[entity]
      if cooking == null or cooking.cookTimeRemaining <= 0:
        if cooking != null:
          if inventoryComponentTable.put(item) == False: # No space, try later
            continue
        # Get next item that has a "burnable" tag, if any
        val item = inventoryComponentTable[entity].getAndRemoveFirstOf("burnable")
        if item == null:
          furnaceCookingComponentTable.remove(entity)
        else:
          cooking = furnaceCookingComponentTable.set(entity, item, furnace.cookTime * getCookTimeModifierOfItem(item))
      else:
        cooking.cookTimeRemaining -= delta

 # ... whatever other functions are useful to the system

# Then of course just with the right components on any entity it will just work
# 'as' a furnace.  You can have a whole variety of 'generic' systems that can be
# mixed and match with impunity.  If you want a random rock that can be a furnace
# then just add the proper components, or if you want an Ent that can both be
# chopped down like a tree for wood but will also attack the player then just add
# the proper components, etc.... etc....

@MysteryGM : один совет: сигналы. Огонь может иметь сигнал ожога (цель), где целью является ваше дерево.

Извините, я имел в виду скрипты, а не экземпляры. Я хочу, чтобы скрипты взаимодействовали, не нуждаясь в узле в дереве Godot.

Извините, я имел в виду скрипты, а не экземпляры. Я хочу, чтобы скрипты взаимодействовали, не нуждаясь в узле в дереве Godot.

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

Кроме того, вы пробовали С#? Если вы пытаетесь создать сложную систему, в которой есть сценарии, взаимодействующие с узлами и управляющие ими с помощью чего-то другого, кроме прикрепления сценариев к узлам, вам, вероятно, будет намного лучше работать с C#, чем с GDScript для такой системы.

@MysteryGM Получение сценариев для взаимодействия друг с другом без использования узла в сцене означает, что вы должны как минимум получить загруженную версию ресурса сценария. Единственный способ сделать это в версии 3.0 — preload / load скрипт по пути к файлу. 3.1 добавляет функцию «класс сценария» для GDScript и NativeScript, где имена, присвоенные сценариям, регистрируются глобально. Затем GDScript вручную преобразует эти глобальные регистрации в движке в глобальные переменные языка.

Затем, если у вас есть ресурс Script , вы можете вызвать статические методы сценария или вызвать .new() , чтобы получить ScriptInstance , а затем вызвать функции-члены/переменные-члены доступа. Если Script является производным от объекта, ссылки, ресурса или другого типа, отличного от узла, то простое создание экземпляра Script / ScriptInstance будет всем, что вам нужно. статический/нестатический контент. Если это узел, то применяется то же самое, за исключением вещей, которые требуют доступа к SceneTree (например, get_node ), и в этом случае вам придется использовать add_child , чтобы сначала добавить его в SceneTree.

Все вышеперечисленное применимо к любому языку сценариев, используемому с Godot (хотя, как я полагаю, предварительная загрузка — это операция, специфичная для определенных языков...).

скрипт по пути к файлу. 3.1 добавляет функцию «класс сценария» для GDScript.

Когда будет официальный релиз 3.1?

@MysteryGM Когда процент завершения вехи достаточно высок / когда основные разработчики оценили прогресс достаточно далеко, чтобы они считали сборку «стабильной».

Веха: https://github.com/godotengine/godot/milestone/7

Для сравнения, версии 2.1 и 3.0 в настоящее время завершены на 99%. Не совсем уверен, что это был тот статус, в котором они были, когда они вышли в эфир.

В основном, ответ "когда он будет готов".

Спасибо за ответы и приносим свои извинения за то, что отняли ваше время.
Похоже, Годо не соответствует нашим потребностям в то время. Возможно, в будущем у нас снова появится возможность использовать этот движок.

Если я хочу, чтобы Огонь сжигал Древесину, я должен иметь либо Древесину->продлить->Огонь, либо Огонь->расширить->Дрова.

@MysteryGM
Смотрите здесь .
Решение (независимо от движка или языка) может состоять в том, чтобы иметь «системный» сценарий, который контролирует взаимодействие между огнем и лесом. Эта презентация фокусируется на компонентах, но можно создать систему, работающую и с объектами.

В C# я мог бы сказать, что Wood реализует IBurnable , который использует Fire .

Привет, спасибо за постоянную заботу, и мы очень благодарны за поддержку @willnationsdev . Мы считаем, что скрипты как решение для экспорта ресурсов имеют большой потенциал. Как упоминалось в # 22660.

Поскольку у нас еще есть 10 дней, чтобы решить, какой движок использовать, мы попытались еще немного с Godot.
Мы рассмотрели проблемы рабочего процесса, и я считаю, что наш программист сказал это лучше всего:

«Разработчики Godot хранят каждую проблему в Github в отдельной публикации, всегда открывают одну проблему для одной ошибки , но не разрешают один и тот же рабочий процесс для своего движка».
Дело в том, что мы должны сделать скрипт И мы вынуждены добавить его в иерархию.

«системный» скрипт, который управляет взаимодействием между огнем и лесом. Эта презентация посвящена компонентам

Да, это то, что мы хотим, как нам это сделать в GDscript?

В C# я мог бы сказать, что Wood реализует IBurnable, который использует Fire.

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

Нам нужен Огонь, Горение, Древесина. Нам не нужен Огонь (Дрова+Горение).
Преимущество этого рабочего процесса заключается в том, что мы можем отлаживать запись самостоятельно, без необходимости исправлять каждый объект, который может быть записан.

В C# мы просто объявим Burning как собственный класс. Публичный класс Burning и наша проблема решена.
В C++ мы бы включили прожиг, и проблема была бы решена.

Да, это то, что мы хотим, как нам это сделать в GDscript?

@MysteryGM

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

Чтобы ускорить процесс, можно выполнять проверки только тех объектов, которые действительно столкнулись (например, отправив signal from object в систему, когда происходит столкновение).

Некоторые специфичные для GDScript примеры перекрестных ссылок скриптов (для версии 3.0):

Здесь Enemy выступает в роли типа/интерфейса, его можно проверить с помощью оператора is :

# Cache the enemy class.
const Enemy = preload("enemy.gd")

# Use 'is' to check inheritance.
if (entity is Enemy):
    entity.apply_damage()

Здесь runnerGame указывает на сцену _autoload_ (она же singleton) с путем /root/runner:

onready var runnerGame = get_node("/root/runner")
onready var runnerScript = preload("res://runner/runner.gd")

func _ready():
    runnerGame.setMode(runnerScript.SPAWN_TITLE)

Здесь мы связываем «нажатие» кнопки signal с обработчиком (который может быть в другом объекте и скрипте, мы используем self для ссылки на тот же самый):

func _button_pressed(which):
    print("Button was pressed: ", which.get_name())

func _ready():
    for b in get_node("buttons").get_children():
        b.connect("pressed", self, "_button_pressed",[b])

См. также документы здесь, есть еще несколько доступных функций: http://docs.godotengine.org/en/3.0/getting_started/scripting/gdscript/gdscript_basics.html#inheritance

См. также документы здесь, есть еще несколько доступных функций:

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

Вот пример:

Шаг А.
MeshInstance+ HomingScript = HomingMissile .
Но теперь, если я хочу самонаводящуюся мину, у меня есть проблема.
(MeshInstance+ProximityScript) = Landmine .
(MeshInstance+ ProximityScript) + HomingScript = ОШИБКА более одного скрипта
(MeshInstance+ ProximityScript) + (childNode + HomingScript) = FAILED, так как перемещается только невидимый узел.
(MeshInstance + ProximityScript) + (childNode + ExtendedHomingScript) = УСПЕХ, поскольку теперь мы расширяем класс Homing, чтобы он мог иметь узлы из дочернего узла. Получаем HomingLandmine .

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

Шаг Б.
Самонаводящаяся ракета [из самонаведения]
HomingLandmine [от Homing][+ProximityScript] Скрипт теперь копируется и вставляется в фугас.

Позже в производстве то же самое происходит с другими сценариями, которые у нас есть.
ШагC.
Наземная мина[от близости]
ProximityAlarm[из Proximity] [+ AlarmScript]
// HomingLandmine[from Proximity] [+ HommingScript] // Теперь наш фугас тоже может подойти сюда.

Таким образом, мы должны продолжать проходить Шаг А, чтобы найти правильное наследование для Шага Б. Он продолжает повторять этот шаблон, выходящий за рамки StepF и т. Д.

Мы нашли способ продлить шаг А. Мы просто избегаем добавления скрипта в верхний узел и всегда делаем его пространственным или каким-либо первичным узлом.
(Пространственный + MeshInstance+ ProximityScript) + HomingScript = HomingLandmine
За исключением того, что это точно такая же проблема, но с более дорогим ParentSpatial; вместо дочернего узла.

Прошу прощения за то, что так долго.

@MysteryGM

«Разработчики Godot хранят каждую проблему в Github в отдельной публикации, всегда открывают одну проблему для одной ошибки , но не разрешают один и тот же рабочий процесс для своего движка».
Дело в том, что мы должны сделать скрипт И мы вынуждены добавить его в иерархию.
...
Нам нужен Огонь, Горение, Древесина. Нам не нужен Огонь (Дрова+Горение).
Преимущество этого рабочего процесса заключается в том, что мы можем отлаживать запись самостоятельно, без необходимости исправлять каждый объект, который может быть записан.
...
В C# мы просто объявим Burning как собственный класс. Публичный класс Burning и наша проблема решена.
В C++ мы бы включили прожиг, и проблема была бы решена.

Что вы должны понимать, так это то, что Годо в этом случае действует точно так же. В то время как решение для перехода состоит в том, чтобы создать подузел со своим собственным скриптом (в данном случае для «прожига»), вы можете просто определить «прожиг» как свой собственный класс и включить/использовать его через статические функции (или экземпляр, а затем использовать свойства/методы)

  • С++

    • класс горения {};

    • включить "burning.h";

    • Burning::apply(дерево, огонь);

    • Сжигание *b = Сжигание::get_singleton(); б->применить(дерево, огонь);

  • C# (отредактировано для изменения стиля)

    • открытый класс Burning {}

    • использование Game.Burning;

    • Burning.apply(дерево, огонь);

    • Сжигание b = Сжигание.Экземпляр; b.apply(дерево, огонь);

  • GDScript (3.1)

    • расширяет ресурс #burning.gd

    • const Burning = предварительная загрузка ("res://burning.gd")



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


        расширяет ссылку


        const Burning = предварительная загрузка ("res://burning.gd")


        const Смачивание = предварительная загрузка ("res://wetting.gd")


        расширяет ссылку


        const Stimuli = предварительная загрузка ("res://stimuli.gd")


        # используйте Stimuli.Burning или Stimuli.Wetting


      • в 3.1 можно просто использовать классы сценариев. Сжигание и смачивание не требуют «включения», поскольку они глобальны.


        Кроме того, если вы не против глобального использования, можно сделать «Стимулы» классом сценария с теми же объявлениями констант, чтобы он всегда был доступен как псевдопространство имен.



    • Burning.apply(дерево, огонь)

    • var b = Burning.new()

      b.apply(дерево, огонь)

Для подхода Unity/ScriptableObject можно использовать сценарии ресурсов Godot для той же цели.

  • параметры можно настроить в Инспекторе.
  • «сборки» функции можно сохранить в файл, чтобы можно было легко менять определенные настройки по мере необходимости, даже во время выполнения.
  • Редактор автоматически создает экземпляр ресурса на узле, используя объявление сцены, поэтому ручное обновление не требуется. Массив таких ресурсов может работать достаточно хорошо, хотя из-за того, что система подсказок типа массива сломана в 3.1 (до 3.2, надеюсь), вам придется написать EditorInspectorPlugin для правильной генерации содержимого Inspector (что на самом деле то, над чем я работаю в моем репозитории godot-next FileSystemItemList (предупреждение, это ранний WIP), который будет использоваться в моем репозитории Godot-Builder для массивов файлов/каталогов.

«системный» скрипт, который управляет взаимодействием между огнем и лесом. Эта презентация посвящена компонентам

Да, это то, что мы хотим, как нам это сделать в GDscript?

Самый простой способ сделать это — использовать какой-либо узел/сцену автозагрузки. Причина в том, что даже если вы используете только один узел с тоннами ресурсов для всех различных систем (чтобы свести к минимуму количество используемых вами узлов), вы все равно, вероятно, захотите иметь доступ к узлу, который находится в дереве , поэтому что вы получаете доступ к дельта-времени, входным данным, операциям выхода (особенно в сочетании с использованием сигнала), узлам анимации/твина/таймера, список можно продолжить. Кроме того, в качестве автозагрузки GDScript снова сгенерирует глобальную переменную для узла, чтобы к «системам» можно было получить доступ по имени в любом месте вашей кодовой базы (еще одна подходящая замена для использования класса скрипта в этом случае).

На самом деле у меня есть большой рефакторинг старого плагина WIP, godot-skills , который я хотел бы сделать, и я считаю, что он включает в себя это и многое другое. Пожалуйста, прочитайте (извините, длинную) ветку Reddit по этой теме. Он включает в себя изучение жизнеспособности использования скоординированной многопоточности в серверной архитектуре (аналогичной базовой архитектуре Godot) для реализации аналогичной универсальной и повторно используемой интерактивной системы.

Кстати, если вы когда-нибудь захотите пообщаться в режиме реального времени на эту тему, не стесняйтесь написать мне в Reddit/Discord/Twitter, где я использую то же имя пользователя.

@MysteryGM

MeshInstance+ HomingScript = _HomingMissile_.
Но теперь, если я хочу самонаводящуюся мину, у меня есть проблема.
(MeshInstance+ProximityScript) = _Landmine_.
(MeshInstance+ ProximityScript) + HomingScript = ОШИБКА более одного скрипта
(MeshInstance+ ProximityScript) + (childNode + HomingScript) = FAILED, так как перемещается только невидимый узел.
(MeshInstance + ProximityScript) + (childNode + ExtendedHomingScript) = УСПЕХ, поскольку теперь мы расширяем класс Homing, чтобы он мог иметь узлы из дочернего узла. Получаем _HomingLandmine_.

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

Я считаю, что я что-то упускаю здесь. Afaik, правильный способ сделать узел «поведение компонента» - это тот, который не меняет себя, а напрямую изменяет «целевой» узел, где целью по умолчанию является родитель. Это полностью обходит проблему, с которой вы столкнулись, если я не ошибаюсь.

extends Node
var src_target
export(NodePath) onready var dst_target = get_node(dst_target) if dst_target else null
func _notification(p_what):
    match p_what:
        NOTIFICATION_PARENTED:
           src_target = get_parent()
        NOTIFICATION_UNPARENTED:
           src_target = null
func _physics_process():
    # if necessary, can manually assign src_target elsewhere to be NOT a parent
    if src_target and src_target is KinematicBody2D:
        src_target.move_and_slide(...) # do logic to get parameters that move towards dst_target

Что-то вроде этого означало бы, что вам не нужно ничего менять, просто сделав узел со сценарием дочерним элементом того, что вы хотите иметь функцию «возврата». Вам просто нужно присвоить значение экспортируемого свойства (либо в сцене, либо во время выполнения), чтобы сообщить ему, что делать дома. Другие экспортированные свойства можно использовать для изменения типа движения, и эти вещи также могут быть переданы ресурсу, если вы хотите иметь разные «сборки». Опять же, Godot позволяет вам быть очень гибким в дизайне вашего игрового фреймворка.

Некоторые исправления:

 - C#
-   - public class Burning {};
+   - public class Burning {}
    - using Game.Burning;
    - Burning.apply(wood, fire); // is it :: here? I forget...
-   - Burning b = Burning::GetSingleton(); b.apply(wood, fire);
+   - Burning b = Burning.GetSingleton(); b.apply(wood, fire);

Точка с запятой после закрывающей скобки класса не нужна. Вы используете точку для статических элементов вместо :: .
В качестве примечания: соглашение для доступа к синглтону заключается в использовании свойства (обычно называемого Instance ) вместо метода.

@neikeq Спасибо. Я слишком отвык от C#, лол.

Что касается подхода "Глобальные скрипты", то я категорически против этого. Это побудило бы разработчиков плохо кодировать свою игру. Обычный вопрос предыдущих разработчиков игр на чистом C++ и Java, когда они пробуют Unity/Unreal/Godot/и т. д., звучит так: «Где находится основной игровой цикл, в котором я могу написать свой код?». Добавление такой системы позволит этим разработчикам делать это, поэтому они могут в конечном итоге написать код в глобальных сценариях, которые ссылаются на объекты, которые они хотят изменить, вместо того, чтобы просто использовать сценарий для объекта.

Возможно, вместо этого мы могли бы улучшить производительность базового узла Node , чтобы он не создавал накладных расходов для «компонентов» объектов, которые содержат исключительно скрипты. Или, может быть, даже отдельный простой узел «только для скриптов».

@ааронфранке

Что касается подхода "Глобальные скрипты", то я категорически против этого. Это побудило бы разработчиков плохо кодировать свою игру. Обычный вопрос предыдущих разработчиков игр на чистом C++ и Java, когда они пробуют Unity/Unreal/Godot/и т. д., звучит так: «Где находится основной игровой цикл, в котором я могу написать свой код?».

Как я уже упоминал, если кто-то не хочет этого делать (в разумных пределах в большом проекте), то нет проблем с простым созданием глобального класса скрипта "пространства имен", который поддерживает константы других скриптов для перемещения дальше по иерархии API. Здесь мы говорим только о сценариях, а не о фактических ссылках на узлы.

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

Эта система уже может быть реализована кем угодно в Godot с помощью автозагрузки (не предлагается «добавление» какой-либо функции). Кроме того, проблема, с которой они сталкиваются в первую очередь, заключается в том, что они не хотят добавлять сами системы в качестве подузлов в мире (хотя я также предлагаю это в последующем комментарии), поскольку они иметь там и узел, и сценарий на этом узле, и, возможно, рефакторинг отношений между всеми узлами и сценариями, когда они позже поймут, что вещи должны перемещаться.

Возможно, вместо этого мы могли бы улучшить производительность базового узла Node, чтобы он не создавал накладных расходов для «компонентов» объектов, которые содержат только скрипты.

Каким образом? Единственный способ сделать это прозрачно — внедрить систему MultiScript, а вместе с этой парадигмой возникает целый ряд проблем. Единственной другой альтернативой, которую я мог придумать, пытаясь решить эту проблему, была система признаков GDScript, которую я предложил в #23101, которая ограничивает проблемы MultiScript одним языком, но имеет свой собственный набор еще более серьезных проблем.

Или, может быть, даже отдельный простой узел «только для скриптов».

Как только мы исправим систему подсказок типа массива в 3.2, мы сможем сделать это всего лишь...

extends Node
export(Array, Script) behaviors = []

Можно даже реализовать эту функцию сейчас, используя словарь (для доступа к сценариям по имени) и EditorInspectorPlugin из версии 3.1, чтобы определить пользовательский интерфейс, когда эти узлы открываются в инспекторе (создайте пользовательский интерфейс экспортированного массива сценариев, но он добавляет скрипт с ключом, который соответствует имени файла под капотом).

расширяет ресурс #burning.gd

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

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

FileSystemItemList (предупреждение, это ранняя WIP)

Обязательно надо будет присмотреться к этому.

@MysteryGM

Я не думаю, что кто-либо из нас даже знал, что мы можем создавать собственные ресурсы.

Да! Недавно я добавил в документацию раздел, в котором описывается процесс. :-D

Вы можете расширить ЛЮБОЙ тип движка с помощью скрипта, включая Object, Reference, Resource и, конечно же, Node (или любые производные от этих классов). Единственное, что не может быть расширено, — это синглтоны движка и редактора (например, ОС, движок или EditorFileSystem).

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

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

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

Учитывая, что предзагрузка ресурсов решает проблему включения скриптов. Также может использоваться в качестве альтернативы MultiScript и ScriptableObject Unity путем экспорта переменной ресурса в GDscript.
В сочетании с тем фактом, что документы были обновлены для более подробного объяснения ресурсов.
Не говоря уже о том, что в Godot 3.1 также будут классы сценариев, которые должны обеспечить еще больше рабочих процессов.

Я думаю, что первоначальная цель этой проблемы была решена, и теперь эту проблему можно закрыть?

Еще раз хочу сказать спасибо всем за участие в обсуждении, и особенно спасибо @willnationsdev , который предоставил огромное количество информации о движке Godot.

@MysteryGM Я думаю, что ваши мысли в начале и в конце этой темы могут быть полезны для записи в блоге или в черновике Godot-docs. Я думаю, что большинство ранних пользователей часто допускают ошибки производительности при попытке добиться сложной организации сценариев, нам нужны хорошие описания «до» и «после» с точки зрения обучения. Уроки и шаблоны, которые мы изучаем в ранних руководствах, плохо переносятся в крупномасштабные игры, что для меня просто означает, что нам нужно больше блогов/советов по крупномасштабным урокам.

@pgruenbacher , это отличная идея. У нашей команды есть две проблемы с этим: во-первых, только двое из нас знают английский на полезном уровне, а во-вторых, это займет много времени.

Тем не менее, есть хорошее изменение, которое заключается в том, что мы создадим блог разработчиков и будем вести записи обо всем, что обнаруживаем. Возможно, мы сделаем запись в блоге «Переход к Годо».

Прямо сейчас я работаю над некоторыми учебниками в формате PDF «Ускоренный курс Godot для художников», потому что мы хотим нанять фрилансеров в команду, но Godot еще малоизвестен.
Эти уроки предназначены для того, чтобы познакомить с Godot профессионального игрового художника.
Как только я это сделаю, я поделюсь ими с другими пользователями Godot, я сохраню их в формате PDF для начала, потому что легче исправлять ошибки, пока я еще учусь.

@pgruenbacher @MysteryGM Хотя это и не похоже на опыт работы с Godot до/после, эта проблема и некоторые связанные с ней повторяющиеся вопросы побудили меня начать работу над статьей о передовых методах проектирования сцен/сценариев для godot-docs. У меня есть филиал на моей вилке, но это очень ранний банкомат WIP.

Чтение таких тем крайне обескураживает (в том смысле, что заставляет меня сомневаться, правильный ли мы выбрали движок). Наш проект насчитывает более 15 000 LoC, отлично организован и отлично работает. (я не буду вдаваться в подробности конкретных моментов, потому что здесь есть люди намного умнее меня).
С учетом сказанного, я рад, что вы останетесь с Godot, MysteryGM! Def с нетерпением жду чтения блога разработчиков

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

В среду, 14 ноября 2018 г., Аарон-Флейшер, [email protected]
написал:

Чтение таких тем крайне обескураживает (в смысле
заставляя меня перепроверить, если мы выберем правильный двигатель). Наш проект хорошо
более 15 000 LoC, отлично организовано и отлично работает. (я не пойду
в подробности конкретных моментов, потому что другие люди здесь намного умнее
чем я сам).
С учетом сказанного, я рад, что вы останетесь с Godot, MysteryGM! Def ищет
вперед к чтению блога разработчиков


Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/godotengine/godot/issues/23052#issuecomment-438871197 ,
или заглушить тему
https://github.com/notifications/unsubscribe-auth/ADLZ9pw2-G0kE19meyi7iSkceAldfAMjks5uvLb4gaJpZM4XelSe
.

@ Аарон-Флейшер

... заставляет меня сомневаться, правильно ли мы выбрали двигатель

Если движок, который вы используете сейчас, работает на вас, даже если вам придется что-то делать, то нет причин для беспокойства. Некоторые игроки (или другие разработчики) могут усомниться в ваших способностях/вменяемости, но это реальность разработки игр. Множество страстных людей, говорящих с явным авторитетом (часто намного выше их фактического уровня мастерства).

Вы тот, кто знает ваши проблемы, и именно вам придется выполнять работу. Избегайте того, чтобы вас парализовало то, что принесло бы вам еще 10-20% продуктивности. Сохраните его для следующей игры. Или не делайте этого, так как вы уже вложили массу средств в изучение инструментов, которые вы уже знаете. Твой выбор :)

Не знаю, у меня такое ощущение, что разработчики Godot не понимают, что делают.

При первом использовании стабильной версии Godot 3.0.6 я столкнулся с уродливым, нефункциональным «Менеджером проектов». Когда я даже могу понять, как это работает (и это совсем не интуитивно понятно), приложение вылетает каждый раз, когда я пытаюсь загрузить пример программы из библиотеки активов. Иногда приложение просто перестает отвечать. Иногда приложение выдает загадочные ошибки «условие !connected is true». Иногда загрузка останавливается. И каждый раз для загрузки файла размером 100 МБ требуется около 10 минут, в то время как я могу загрузить 10 ГБ в другом месте за то же время. «Повторить» запускает всю загрузку с нуля.

У меня есть ощущение, что «стабильный» здесь означает «надежно облажается каждый раз».

Расскажите о неудовлетворительном первом впечатлении.

@dejayc Это странно. У меня никогда не было проблем с менеджером проектов (со стабильной версией 3.0.6 или даже с основной веткой) в Windows 10 или на моем устройстве Linux Mint. Я бы порекомендовал вам создать новый вопрос о ваших проблемах здесь (поскольку это не совсем правильный вопрос для такой темы), и, надеюсь, кто-то может предложить лучшую помощь.

@dejayc
Если мы все пожертвуем на Patreon, проект Godot сможет нанять специалиста по юзабилити на полный рабочий день .

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

Тем не менее, я открыл вопрос с предложениями о менеджере проектов, поскольку у меня есть свободное время, я собираюсь поработать над некоторыми улучшениями в этой области.

Я работал как с Unity, так и с Godot и обнаружил, что общий рабочий процесс и структура намного лучше и интуитивно понятнее в Godot (особенно модель сцены вместо сцены/префаба из Unity, модель с одним сценарием вместо многокомпонентной, скорость при загрузке/запуске движка и экспорте и возможность полноценной работы в автономном режиме).

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

Была ли эта страница полезной?
0 / 5 - 0 рейтинги