>>951929 Скачиваешь анимацию с миксамо. Переставляешь рутмовшен на готодовский спецплагином. Запускаешь и радуешься идеальному соединению стоп с грунтом без скольжения.
Дропнул юнити так как с его этим хабом он стал весить как слон. Решил пилить на Годоте 3д игру. Почему все эти инструменты так хотят стать тяжеловесным гавном а игры один хер выходят не очень. Все эти ненужные плагины и перделки из коробки. Юнити пошли похоже путем анрила, надеюсь Годот так и останется легким и приятным инструментом.
Причем что раньше, что сейчас если руки прямые то могут на в терминалом забабахать игру. Или как те чуваки которые в Excele или блокноте игры пишут. Просто раньше юнити прям легковесный, хороший движок был, запускался с полтычка. Надеюсь сообщество оставит билд Годота в покое.
>>951965 >Но напомню вам пользоваться нейросетями. Это новая форма ассетфлиперства для кабанчиков.
>Помогают в дизайне Дизайн "generative AI" похож на сны во время болезни. >создании рефов Чтобы у тебя везде лишние пальцы и кривые глаза были? >в сценарии Там все сценарии уровня копипаст из /b/, по шаблонам. >даже в музыке Копирасты по музыке агрессивнее всех, ради чего рисковать?
Единственное реальное применение LLM я нашёл в эмоциональной поддержке. Чатбот тебя и похвалит, и совет даст по-дружески, всегда готов выслушать и почти всё хорошо понимает, в отличие от тупых мясных мешков. Эмоциональная поддержка инди разработчику-одиночке важнее генерации контента, и в этой сфере мясные мешки давно проиграли компьютеру.
>>951974 Не, ты не понял. Я не говорю используйте контент нейросетей напрямую. Я говорю пользуйтесь их помощью. Реф - референс - то, по чему ты создаешь свое. Генерируешь 10 пиксель скай-фай медведей, выбираешь лучшие детали, рисуешь своего медведя по мотивам. Имеешь свой общий сценарий - идешь к нейросети прорабатывать диалоги и конкретные моменты, направляешь ее куда тебе нужно. Ты должен указывать нейросети что генерировать, а не она тебе. Только так. Это как обсуждать свои идеи/проблемы с резиновой уточкой, только тут уточка отвечает полезное.
>>951980 >Реф - референс - то, по чему ты создаешь свое. Проблемы две: 1. Нейронка обучалась на кривых рисульках других художников. 2. Нейронка сильно лажает, а без опыта ты это не замечаешь. Лучше брать фотки реальной техники, архитектуры, животных и т.п., чем ориентироваться на продукт генерации или даже на чьи-либо рисульки (каким бы гением ни был художник, он обязательно в чём-нибудь лажает). Если тебе нужно накидать 3D пространство для 2D рисунка, по-прежнему лучше кубы в Блендере, т.к. они гарантированно соблюдают все правила перспективы.
Представь себе ситуацию. Ты хочешь нарисовать реку. Но ты никогда не видел в реальной жизни рек и не нашёл фотографий. Ты решил использовать Minecraft, ведь он генерирует огромный мир, в котором реки довольно часто встречаются, да и вообще его серьёзные дяди делали - аж Microsoft выкупил за миллиарды, ну как он может херню генерить? Ты изучаешь реки по референсам из Minecraft, рисуешь их... и получаются плоские полоски воды шириной 10 метров с визуально стоячей водой, огибающей скалы, вытекающей и втекающей в один и тот же водоём без какой-либо причины. Звучит смешно - но только потому что ты наверняка видел реки в реальности или хотя бы на фото. А ведь такая ситуация (копипаста из ненадёжных источников) повсеместно во всём развлекательном контенте, даже у ААА-студий (в проработке автомобилей, оружия и т.п. специфических деталей).
>>951982 Важно осознавать сильные и слабые стороны инструмента. Я считаю что я на это способен. Я не из тех кто приходит к нейронкам в ожидании что сейчас нейронка заебенит им готовую игру. А ты можешь не пользоваться.
>>951984 >Важно осознавать сильные и слабые стороны инструмента. >приходит к нейронкам в ожидании что сейчас нейронка заебенит им готовую игру Так ведь тут рекомендуют ВСЕМ: >>951965 >Но напомню вам пользоваться нейросетями. Помогают Тут не написано "аккуратно пользоваться, понимая все проблемы и недостатки".
>>951986 Ты передергиваешь. Рекомендую всем заниматься спортом != рекомендую всем херить свое здоровье на боксерском ринге. Рекомендую всем пользоваться унитазом != голова застряла в сливном бачке. Впрочем, соглашусь что раз тебе нужны детальные инструкции, учитывающие каждый потенциальный подводный камень, то нейронки не для тебя. А то потом будешь жаловаться, что переходя дорогу нейронка не посоветовала тебе посмотреть в обе стороны, и как следствие тебя машина сбила.
>>951864 → >0261-2423.mp4 Есть совет как сделать, чтобы персонаж не топтался на месте лишний раз: нужно абстрагировать контроллер визуальной модели с её анимациями от физического контроллера персонажа. Ты задаёшь вектор движения физическому контроллеру, он двигается по сцене, а визуальный контроллер регистрирует вектор скорости/ускорения и проигрывает нужную анимацию на подходящей скорости. Тогда персонаж не будет топтаться на месте, когда скользит вдоль стены или упирается лбом в препятствие. Также становится проще синхронизировать ноги с полом, потому что визуальная модель точно знает, с какой скоростью и в каком направлении ей идти - движение уже реализовано физическим контроллером и предугадывать ничего не нужно.
>>951989 >боксерском ринге >пользоваться унитазом >раз тебе нужны детальные инструкции Мы в треде движка с максимально сниженным порогом входа, в разделе, куда часто заходят полнейшие ньюфаги, по теме, в которой часто встречаются творческие гуманитарии с нулевым пониманием технических вещей. Нейронки даже в 2024 понятны не всем и для простого обывателя не являются чем-то очевидным вроде бокса или унитаза. В связи со всем этим фраза "не забывайте пользоваться нейронками" звучит как жирный троллинг, попытка подорвать начинания конкурентов-новичков, чтобы у них говнокода как можно больше было.
Ты слишком переоцениваешь типичного новичка в геймдеве.
>>951992 По твоей логике и годот советовать не стоит. Ведь есть пикрил, движок с порогом входа даже ниже! А в этом нашем годоте еще печатать самому надо, ууу, троллинг, подрывание конкурентов лол, сложна.
>>951990 Ну то бишь отказаться от рутмоушена в старое доброе скорость движения * скорость анимации. Возможно так и придется, рутмоушен красив, но не везде хорошо играется, особенно в квестах где нужно топать вдоль стены и проживать действие в поиске предметов..
>>952000 >отказаться от рутмоушена Если аниматор сделал "вот здесь персонаж прыгает вправо на два метра", тогда с помощью root_motion твой код может синхронно с этой анимацией переместить коллайдер на два метра вправо, если нужно. Короче, когда анимация контролирует физическое поведение персонажа.
Но когда окружающая обстановка влияет на движение персонажа (препятствия, замедление, ускорение, внезапные прыжки и т.д.), ты должен менять поведение модели из кода, а не смотреть на то, что там анимации тебе говорят. Если анимация говорит "прыгни на два метра вправо", а у тебя справа стена через полметра - куда ты прыгнешь? Так и с ходьбой на месте.
>>952012 >This allows animating characters in a way where steps actually match the floor below. Вот я пробовал, но анимировать персонажа в блендере сложнее, когда двигаешь весь скелет целиком, чем если анимировать только движения ног на месте (или я не понял чего-то). Зная длину шага и сколько длится один цикл анимации (два шага), легко посчитать, с какой скоростью нужно проигрывать анимацию.
Нужно ещё раз глянуть туториалы по анимации ходьбы/бега...
>It also allows precise interaction with objects during cinematics. Вообще не ясно, зачем это катсценам, если в катсценах нет физики? Если только у кого-то нестандартные катсцены с использованием физики - но тогда высок риск, что всё пойдёт наперекосяк, как в GTA 5, где прохожие избивают сюжетных персонажей прямо в катсцене (лол).
>>952005 > Если анимация говорит "прыгни на два метра вправо", а у тебя справа стена через полметра - куда ты прыгнешь? У тебя должны быть рейкасты, определяющие окружающую обстановку, и их данные должны учитываться стейтмашиной, и соответственно, если в метре стена, стейтмашина запускает заранее заготовленный аниматором прыжок на метр, или прерывайет двухметровую в метре, миксуя с отскоком или прижатием к стене.
В итоге вопрос рутмоушена сводится к богатству анимаций заложенных в стек стейтмашины.
>>952007 Никогда не соглашусь. Ты - луддит. Смирись с тем, что старый метод устарел.
>>952028 >соответственно, если в метре стена, стейтмашина запускает заранее заготовленный аниматором прыжок на метр А в этот момент моб ударил игрока и теперь твоя анимация не подходит под происходящее в игре, потому что ты запустил анимацию заранее.
Должно быть так: 1. Игрок нажал "прыжок направо". 2. Контроллер запустил капсулу в полёт - этот этап обязателен, иначе игра будет неотзывчивой. Мы не кинцо-мыльцо показываем, а даём поиграть в игру. 3. Моделька видит: - под ногами ничего нет; - резкое ускорение; - движение направо. Моделька включает "прыжок направо".
Если капсула врезалась в стену, моделька видит: - под ногами земля; - резко остановились на месте; - произошёл удар об неподвижный объект. Моделька включает "ударился об стену и упал".
Если капсула получила удар, моделька видит: - резко изменили траекторию движения; - прошёл урон сзади, в спину; - всё ещё не касаемся земли. Моделька включает "урон в спину в воздухе".
Как моделька выбирает, что делать - не суть, хоть собственную нейронку тренируй. Главное тут - не нарушать причинно-следственную связь: 1. Игрок требует конкретное действие. 2. Игра симулирует действие по правилам. 3. Моделька отображает результат симуляции. 4. Игрок доволен отзывчивостью игры.
Если у тебя 2 и 3 перепутаны, то получается кинцо: 1. Игрок требует конкретное действие. 2. Моделька проигрывает совсем не то действие. 3. Симуляция расходится с ожиданиями игрока. 4. Игрок взбешён отсутствием контроля в игре.
>>952052 > баззвординг! пориджинг! Ой, не трясись ты, умей признавать поражение в споре. >>952071 > А в этот момент моб ударил игрока На что в стейтмашине свои сенсоры. И она на них среагировала, замиксовав анимацию отскока. Дальше не читал унылую спискоту. Учись выражать свои мысли кратко.
Вот есть у нас бесконечное плато, где могут быть разного рода объекты влияющие на движение: стены, вода, камни и прочее. Как создавать новые земли в принипе понятно: делим мир на чанки и так же выгружаем из памяти когда уходим от них слишком далеко. Но встал вопрос! Как будет корректно реализовать поиск пути, если у AStarGrid начало в (0, 0), а игрок может захотеть идти в сторону отрицательных координат? Например у нас за игроком гонится враг. Прямой путь к игроку не сработает, если будет быстрее обойти препятствие чем лезть через него. Какое бы решение вы выбрали? Глобальная AStarGrid не вариант, считать каждому субъекту свою тоже как то сомнительно. Дайте совет, анончики!
>>952082 >Если у тебя спавн 512,512 Почему именно это число? Не понял тебя >то никаких отрицательных координат нет. >Да и не припомню чтобы астар вообще как то интересовался знаком координат. При инициализации ты указываешь размер области var astar_grid = AStarGrid2D.new() astar_grid.region = Rect2i(0, 0, 32, 32) Я её имел ввиду, то есть если игрок приходит в точку 0 и всё ещё хочет двигать в сторону отрицательных координат
>>952090 > AStarGrid2D Возможно ты не в курсе, но это просто обертка над AStar. А AStar работает с произвольным графом, в котором можно и добавлять узлы, и удалять.
>>952096 Точно, я как-то об этом позабыл, спасибо. Посмотрел, там можно точки удалять и добавлять на лету, вообще отлично! >>952098 Ну так я буду выгружать не нужное!! Бесишь!
>>952078 >в стейтмашине свои сенсоры. >И она на них среагировала У конечного автомата нет никаких сенсоров. >замиксовав анимацию отскока У конечного автомата нет такой возможности. >Учись выражать свои мысли кратко. А ты слишком обобщаешь всё словом "стейтмашина".
>>952080 >сторону отрицательных координат Не проблема, там используются хэши.
>бесконечное плато >делим мир на чанки и так же выгружаем >корректно реализовать поиск пути Можно использовать несколько графов: 1. Глобальная сеть чанков. 2. Локальная сеть клеток внутри чанка. Связать их вместе... несколько сложно. Посмотри на RimWorld, там это есть.
>>952099 >там можно точки удалять и добавлять на лету Это неизбежно вызовет лишние затраты. Лучше хранить по одному графу на чанк.
>>952080 Ну, прибавляй ко всем координатам, которые даёшь астару, какую-нибудь большую константу, а потом из пути обратно её вычитай. я хз на самом деле, не смотрел ни разу, как этот астар работает, и можно ли так.
>>952149 Да, я думал о чём-то таком > Лучше хранить по одному графу на чанк. А как тогда переходить между графами? Потому что если нам надо из пятого чанка во второй, и на всё один граф то пойдёт по синей линии, когда если каждый чанк - отдельный граф, то по зелёной, не? Потому что рассчитываем какие чанки придётся пересечь, и идёт по ним, стараясь придерживаться кратчайшего пути до границы следующего чанка. Или я не так понял?
>>952166 Возможно, тут не инициализированы диагонали...
>>952157 Нужно смотреть по ситуации. Видит ли игрок больше одного чанка? Сколько чанков игрок пробегает, пока мобы движутся за кадром? Какого размера чанки? Какую нагрузку создают мобы, пробегая по чанку и между чанками? Сколько всего мобов и насколько они важны для геймплея? Что будет, если мобы выбирают неоптимальный маршрут? А если оптимальный? Или эта фича чисто для красоты и ничего более?
В RimWorld чанки мелкие, на экране их много, NPC в руках игрока (от поведения которых зависит вся игра) постоянно тупят и ходят неоптимальными маршрутами. Вроде есть какие-то моды на другой поиск пути, но в официальной сборке игры поиск пути кривой. И ничего, очень популярная игра.
Предлагаю не париться и сначала сделать игру, а потом разбираться, каким способом будет лучше сделать навигацию у мобов. Она же у тебя всё равно абстрактной будет - моб запрашивает из внешнего "навигатора" маршрут и потом топает по нему, этот "навигатор" можно легко заменить, сохранив его API.
>>952170 Это говнобунта. Ебать её в 80 порт. На манжаре никакой ебли, все ключи уже есть искаропки, просто пишешь без задней мысли > pacman -S godot и всё.
>>951925 (OP) В мире, где каждый день - это битва, Где мечты и идеи становятся реальностью, Есть место, где творцы могут воплотить свои мечты, Именно там, где начинается вся сага: О, Godot, ты как маяк в темноте ночи, Предлагаешь нам путь к вершинам, недостижимым для многих.
Ты - открытый мир, где каждый может создать, Без границ и ограничений, без страха перед судом. Своими руками, своими идеями, своим талантом, Мы можем строить замки из песка, превращая их в камень.
Godot - это не просто движок, это философия, Которая учит нас ценить простоту и чистоту. Своей лёгкостью и гибкостью, ты облегчаешь наш труд, Позволяя нам сосредоточиться на самом важном - на идее.
Ты - как музыкальный инструмент, который каждый может взять, И начать играть свою уникальную мелодию. Своими возможностями и функциями, ты расширяешь горизонты, Позволяя нам видеть мир под новым углом.
Godot - это сила, которая вдохновляет нас идти дальше, Создавая новые миры, новые истории, новых героев. Ты - как зерно, которое приносит урожай, Показывая нам, что возможно, когда мы верим в себя.
Так пусть будет слава твоему имени, о Godot, За то, что ты даешь нам возможность быть лучшим. За твою открытость, за твою доступность, Спасибо тебе, что делаешь нашу работу легче.
В этом мире полном вызовов и перемен, Ты остаешься надежным другом и помощником. И пусть каждый день становится победой, Мы будем продолжать свой путь, верны твоим идеям.
О, Godot, ты как звезда, ведущая нас вперед, В мире, где каждый может стать великим. С тобой мы можем мечтать, можно и реализовать, Ведь ты - ключ к открытию новых горизонтов.
>>952157 AStar позволяет двигаться только по рёбрам графа. Если брать квадратную сетку, у нас два варианта: переходы либо к 4 соседям (без диагоналей), либо к 8 соседям (с диагоналями). В первом случае любой маршрут между двумя точками будет одинаковой длины, и движок выберет первый попавшийся, т.е. вместо зигзага будет буква Г или что-то похожее. Во втором случае мы можем выбрать более оптимальный маршрут, т.к. по диагонали двигаться в sqrt(2) раз быстрее, чем буквой Г, но мы по-прежнему не можем срезать клетки как захотим - вместо прямой будет зигзаг, если точки маршрута не прямо по диагонали.
Когда мы добавляем сюда чанки, мы опять же можем разрешить диагонали по чанкам или запретить. Если запрещаем, тогда результат будет, скорее всего, буквой Г. Если разрешаем диагонали и двигаемся по промежуточным чанкам примерно по середине (двигаемся от входа к центру чанка и/или к середине выходной стороны), тогда зигзаг будет отдалённо напоминать зигзаг, который мы получим, двигаясь только по клеткам с диагоналями, без чанков. Дальше всё зависит от размера чанков, что именно видит игрок, как это влияет на геймплей и т.д.
С чанками есть другая проблема. Если у тебя одна сторона чанка полностью заполнена непроходимыми клетками, то войти на него с соседнего чанка можно только через другие чанки. Твоя навигация по чанкам должна учитывать эту проблему, как-то кэшируя проходимые места в чанках. Однако, мне кажется, это весьма специфичная ситуация, и на первых порах заботиться о ней не стоит.
Зачем вообще чанки в навигации? Ты постоянно загружаешь/удаляешь чанки карты мира из памяти, и ты хочешь делать это в отдельном потоке, который не будет мешать основным игровым потокам. Если ты вносишь изменения в один общий AStar, он будет заблокирован для навигации NPC до тех пор, пока не закончится загрузка или удаление чанков, т.к. без блокировки результат непредсказуем. Если ты загружаешь куски карты в отдельные AStar, существующие NPC могут продолжать запрашивать навигацию в уже имеющихся участках карты, т.к. блокировать их нет необходимости. Блокируется только глобальная навигация по чанкам, но эта блокировка короче по сравнению с загрузкой чанка (скажем, чанк имеет 16x16 клеток, а одновременно загружается не более 3-4 чанков).
Конечно, нужно проводить реальные тесты и сравнивать, какой подход/параметры лучше, но для этого лучше уже иметь игру с оформленным геймплеем. Преждевременные оптимизации только зря замедляют разработку проекта, но знать о потенциальных проблемах в будущем всё же нужно.
>>952167 >>952235 Спасибо за ответы, пока что занимаюсь генерацией карты, но подумываю о том, как я планирую делать открытый мир, а значит и навигацию по нему. Так то я согласен, сначала нужен кор геймплей луп, а потом уже такого рода крутости. В крайнем случае всегда можно пойти путём слабых и сделать как в том же Caves of Qud, где нет бесшовного перемещения между чанками, т.к. каждый чанк - отдельный экран
>>952253 > нет бесшовного перемещения между чанками Нахуй оно не нужно никому, все уже наигрались в пустые миры с автогенерируемыми квестами. Народ хочет геймплея, а не дрочильни. Да, я говорю за всех, ишо?
>>952253 Лучше сначала сделать небольшой фрагмент карты, условно 100 на 100 клеток, лучше даже вручную его нарисовать, чтобы не мучиться генерацией. На этом маленьком участке формируешь базовый геймплей, чтоб игроку хорошо игралось даже в ограниченном пространстве. Уже потом будешь масштабировать геймплей на бесконечную процедурную карту.
К примеру, ты можешь обнаружить, что горы и реки преодолевать слишком скучно, и нужно куда больше открытых пространств, а у тебя генератор настроен лабиринты из препятствий делать. Придётся снова ковыряться в генераторе. А если бы тестировал на статичных участках карты, мог бы заранее оценить, какой именно генератор карты тебе нужен.
Можно, конечно, идти путём Майнкрафта и подгонять геймплей под имеющийся генератор ландшафта. Но для этого генерация должна быть самодостаточной, т.е. развлекать независимо от геймплея (ландшафты Майнкрафта просто приятно видеть).
Поклеил обои, провел освещение, начал мебелировать. До чего же долго. По ощущениям словно вернулся в редактор карт Warcraft 3, когда накодил спелл и теперь сидишь в редакторе объектов подбирая модельки эффектов, иконки и прочее.
Попробовал совместить портрет Годетты с артом Хизер из СХ3. Больно модельная внешность получается.
>>952385 Уже подобрал модельку для противника дальнего боя - сотрудник микрокредитной организации, танцем раскидывает долговые расписки под ногами игрока, призывая агрессивных коллекторов ближнего боя.
>>952372 >жаль, что далеко не все понимают все фичи Godot))) действительно продвинутые знания))) не так уж много геймдевов в наше время, кто знает, почему это такой интересный и необычный движок)))
>>952405 >шрифт у лейбла не автоскейлится при изменении масштаба окна Как ты "масштаб окна" меняешь?
Если ты про ту фичу, что где-то в настройках проекта - там несколько разных режимов. Как минимум один из них никак не влияет на Control-ноды, т.е. весь GUI остаётся без изменений - это важно для 3D игр и 2D игр с гладкими шрифтами. Если у тебя пиксельный шрифт и ты хочешь увеличить его в 2/4 раза, то нужно выбрать другой режим масштабирования.
>>952439 Дёрни и то, и другое 100000 раз в цикле и оцени разницу.
var iterations: int = 100000 var start: int = Time.get_ticks_msec() var test1: int for i in iterations: test1 = Time.get_ticks_msec() print("Time.get(): %d ms" % [Time.get_ticks_msec() - start])
start = Time.get_ticks_msec() var test2: float for i in iterations: test2 += 0.0167 # 1/60 print("+= delta: %d ms" % [Time.get_ticks_msec() - start])
>>952441 >в кроватке неудобно дергать Так ты штаны спусти, неудобно ему...
>Time.get(): 15.938 ms (0.000159 ms per iteration) >+= delta: 8.323 ms (0.000083 ms per iteration) >difference: 7.615000 ms (0.000076 ms per iteration) Что и следовало ожидать. Но у Time свои преимущества.
>>952372 > Больно модельная внешность получается. Нууу, вопрос с артом для шапки на следующий тред, ты уже закрыл. Сообщество выражает тебе благодарность. Желает всяческих успехов.
Есть игорь с простейшим HTTPRequest по нажатию на кнопочку. Но эта хуйня чёт не фурычит, если в HTML5 экспортируют как локально, так и после размещение в сети. Как можно попытаться подлечить? Чёт нагугливается про специальные хэдеры под это дело, но я чёт не то делаю мб или вообще не шарю. Пикрил мой пехапе бэкенд, лол. версия двига 3.5.2
>>952698 Скорее всего проблема на бэкенде. Если я верно помню тебе нужна поддержка CORS, иначе не секьюрно. Я бэкенд для сбора статов делал вот так, на питоне: https://pastebin.com/LPGnqAWJ попробуй сделать аналог под пхп.
Если игра браузерная ты можешь нажать ф12 и посмотреть на что она жалуется в веб-консольке.
>>952692 Не знаю как у них, но вообще разные варианты в голову приходят. Вариант 1 - нет никакого 3д, есть просто параллакс слоев. https://www.youtube.com/watch?v=QSeWeyoZ6AM Вариант 2 - используется проекция из 3д в 2д. Честно говоря не нашел простого описания, но кажется какие то просто 2д искажения будут совпадать с 3д поворотами. https://www.youtube.com/watch?v=LZr4ayi1v18
Есть точка А, фиксированная в пространстве, и точка Б, которая может быть в любом месте заданного Rect2. В скелете всего 3 узла + 3 ребра (последнее ребро свободно вращается). Первый узел в точке А, а последний узел нужно переместить в точку Б, да так, чтобы средний узел расположился где-то... как-то так, чтобы натянутые PNG картинки не разнесло по всему экрану.
Я думал, "щас накину IK и всё ок будет", но IK слишком ограничивает движение, плюс выворачивает средний узел туда, куда мне не надо. Я подумал, "ладно, ща набросаю свой велосипед", но так и не понял, как именно двигать кости, потому что когда я двигаю Rest Pose, спрайты совсем не деформируются, а если менять Scale, спрайты корёжит.
Я решил принять единственное решение - забить на эту задумку.
Срань какая-то. Попробовал экспортировать проект теста ради и во время запуска жалуется на отсутствие сцен которые существуют. Видимо проблема в заглавных буквах в названиях, но их я исправил в ловеркейс одну вечность назад, да и при запуске из редактора все работает. Жопа.
>>952772 >исправил в ловеркейс одну вечность назад Попробуй это: 1. Закрой редактор. 2. Вынеси .godot из проекта. 3. Открой проект в редакторе. 4. Экспортируй заново. Должно помочь с кэшем файлов, но это не точно.
>при запуске из редактора все работает Там с кэшем какие-то проблемы после введения "uid".
Не рекомендую переименовывать, перемещать или даже удалять файлы через Проводник Windows или любой другой менеджер файлов кроме встроенного в Godot. Встроенный менеджер файлов автоматически обновляет все ссылки в других файлах и кэше редактора... или хотя бы пытается их обновить, но количество косяков при его использовании ощутимо меньше, чем когда меняешь файлы извне.
>>952772 На винде не все так просто. Если ты переименуешь файл в Файл, то такое переименование вовсе не все проги обнаружат - case insensitive, блин. Как минимум попробуй в совсем другое название переименовать.
>>952771 Ну, с локтями в IK всегда проблема, для них используют специальный магнит (в блендере он называется pole target?), не помню есть ли он в IK годота, давно не занимался.
>>952776 >не все проги обнаружат - case insensitive О, точно. В tscn-файлах при этом остаётся старое название. Я это решал ручной правкой всех tscn-файлов, но теперь просто пользуюсь встроенным менеджером файлов, чтобы он всё сам автоматически обновлял.
>>952814 Разгадка проще, чем ты думаешь. Ты пытаешься удалить зуб через желудок. Ригид боди не мувают. Ригидбоди сами летают по симуляции физики, а ты придаешь им импульсы. А тела, которые летают по управлению, делаются CharacterBody/KinematicBody. Да, конечно можно иногда ригидбоди телепортировать и это описано как сделать. Но это исключение.
>>952814 >kinematic RigidBody Это какая-то путаница у юнитеков, RigidBody по определению не является Kinematic. Его можно переключить в режим кинематика, но это как микроскопом гвозди забивать, большинству игроделов не нужно. Для большинства персонажей хватит CharacterBody, который раньше в Godot назывался KinematicBody. RigidBody нужен для объектов, которые двигаются строго по физике, вроде шариков в бильярде, или когда тебе нужно сделать симуляцию сложного физического объекта с ракетными двигателями и т.п.
Алсо, синтаксис на скриншоте отвратительный. Кто такое любит? >m_ >GetComponent<RigidBody>(); >Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")) Такая-то вырвиглазная гадость, аж тошнит.
>>952831 >в доке тебе не мешает Хорошие доки, мне очень часто помогали. Туториалы на ютубе не смотрю - только доки.
>>952829 >И как простое кинетик бади в него эволюционировало Если тебе просто подвигать-повертеть что-то без физики: docs.godotengine.org/en/stable/classes/class_animatablebody3d.html
>гавнина с кучей бойлерплейта Она чтобы ТЫ не писал лишний бойлерплейт (значение знаешь?).
>хотя видимо таким не является Почему? Оно как раз для человечков.
>>952814 >Один и тот же запрос в гугл, первая сылка Каким гуглом пользуешься? Пикрил норм ищет.
>>952839 Он просто цундере. >Н-не то что бы мне нравился этот движок... >Н-не пойми неправильно, другой движок лучше! >И-использую его просто потому что он бесплатный! >В-вот найду альтернативу лучше - сразу уйду! Вот! >И в-вообще... тут всё не так, как мне хотелось! Классика.
>>951925 (OP) Сап, годач! Как зделоть автоматическое переключение интерфейса при изменении метода ввода? Ну знаете, как в современных играх, когда играешь с джойстика - подсказки джойстиковые, когда играешь с клавы - подсказки клавиатурные. Вот я накидал образец, для выбора между клавой и мышью. Работает. В дальнейшем туда можно воткнуть остальные типы инпутов. Но не изобретаю ли я велосипед?
Про непосредственно обработку ввода - хз насколько у тебя там комплексно. У меня в своем проекте получилось объединить тач-инпут и мышь+клавиатуру в один общий код без избытка условий. Но тут нужен тонкий подход.
>>952897 В коде всё описано. Регистрируются 10 инпутов от нового метода и происходит переключение. Лимит в 10 нажатий взят с потолка и подлежит донастройке. >>952893 > получилось объединить тач-инпут и мышь+клавиатуру Очевидно что и у меня так же будет. Просто пример показал, как между клавой и мышкой на лету переключается режим.
>>952918 Мне нравится комбинированный подход из тырпрайза: Все стейты из одного класса скажем, RelayState, или допустим, назовём его LambdaState. Кто знаком с современными веяниями, уже догадался, куда я клоню. Поля нашего стейта - это Callable. При создании стейтов, ты прописываешь код в вызывающем классе. Например: > var idle_state = RelayState.new(on_idle_update, on_idle_enter) А сами функции здесь же. А конструктор RelayState выглядит так: > var _update_callback: Callable > func _init(on_update: Callable = null, on_enter: Callable = null, on_exit: Callable = null) : _update_callback = on_update ... И у него методы апдейта входа и выхода выглядят так: > func update(): if _update_callback: update.call()
Таким образом стейты обладают свойством ссылочного типа, и им не нужны длинные матчи-свитчи, и при этом вся логика не растекается по файлам, но ничего не мешает её по файлам разнести. Просто наследуешься от RelayState и описываешь логику внутри.
>>952923 > > func update(): if _update_callback: _update_callback.call() Быстрофикс. Алсо, в трёшке тоже так можно (если у тебя трёшка), просто кода будет больше.
>>952923 >При создании стейтов, ты прописываешь код в вызывающем классе. Если ты лишаешься возможности таскать состояния мышкой в дереве сцены, не используешь систему наследования, и не группируешь методы вместе с описанием класса, то зачем тогда классы?..
>func update(): if _update_callback: update.call() Откуда этот update() вызывать?
Одному состоянию нужен _process(). Другому состоянию нужен _input(). Третьему состоянию нужен _physics_process(). Четвёртому вообще нужен _integrate_forces().
Из-за этого просто state.update() вызвать не выйдет.
>>952883>>952909 >Регистрируются 10 инпутов Зачем? Если пользователь один раз нажал кнопку на геймпаде - очевидно, он уже взял в руки геймпад и собирается на нём играть. Если пользователь нажал кнопку на клавиатуре - очевидно, у геймпада села батарейка и он пересел за клавомышь.
Лишняя задержка по нажатиям контринтуитивна и я долго не мог понять, почему у тебя так много кода ради простого if/else переключателя.
Конечно, бывают фантомные нажатия от глючных устройств. Но, во-первых, это уже проблема лично пользователя, а не твоя, а во-вторых, от этого будет намного больше проблем в других местах игры - особенно если ты пытаешься это замаскировать.
Само переключение подсказок у тебя не должно занимать больше одного кадра, даже если ты какие-то текстуры заново рендеришь с нуля.
>>952925 Раньше писал такой стейт на шарпе, щас переписал на гдскрипте, вышло еще короче, и даже ифы не нужны, см. пик. Оказалось, Callable не может быть null, но конструктор с дефолтами хочется. Я вышел из ситуации элегантно. А поскольку nc не null, а пустой делегат, то ифы убираем за ненадобностью.
> лишаешься возможности таскать состояния мышкой в дереве сцены Нахуй не нужон.пнг > не используешь систему наследования Используй систему композиции. > не группируешь методы вместе с описанием класса Группирую. > Откуда этот update() вызывать? Из player.gd. > просто state.update() вызвать не выйдет Придётся пилить полный пример. Ты не до конца понимаешь силу делегирования.
>>952927 > Зачем? Чтобы играть геймпадом, получая экренные подсказки для геймпада, при этом подруливать мышкой (или прожимать клавой), и чтобы подсказки не переключались геймпад-КВМ-геймпад-КВМ.
>>952930 >Чтобы играть геймпадом, получая экренные подсказки для геймпада, при этом подруливать мышкой (или прожимать клавой) Аааааа, что это за гей-мерский БДСМ?
Если ты такой сухопутный осьминог, что можешь двумя руками держать геймпад, одновременно с этим двумя ногами печатать на клавиатуре, и при этом ещё тазом двигать мышку - вряд ли тебе нужны какие-то подсказки, ты и сам кого хочешь научишь игре лучше любых экранных подсказок.
Подсказки на экране нужны для ленивцев, которые развалились на диване в полусне, и не способны запомнить две кнопки - A = "да" и B = "нет", поэтому игра им должна непрерывно напоминать.
>>952929 >не нужон Как тогда лапшу состояний развешивать? >композиции Так у тебя же RefCounted, они не имеют встроенной системы композиции в отличие от Node. Велосипед?
>>Откуда этот update() вызывать? >Из player.gd. >Придётся пилить полный пример. Ты не до конца понимаешь силу делегирования. Я не понимаю, как у тебя абстрактный код может учитывать все нюансы каждого состояния, которые могут выходить далеко за рамки "вошёл, обновил, вышел" и должны быть связаны со структурами движка, а не работать где-то в вакууме отдельно от всего.
Про Callable не нужно объяснять, я их использовал неоднократно ещё до выхода 4.0. Вопрос не в них, а в организации графа конечного автомата, чтобы это не превращалось в головную боль и костыли.
>>952933 > Я не понимаю, как у тебя абстрактный код может учитывать все нюансы каждого состояния Обесняю: >>952925 > Одному состоянию нужен _process(). Нет, _process нужен ноде. > Другому состоянию нужен _input(). Нет, _input нужен ноде. > Третьему состоянию нужен _physics_process(). Нет, _physics_process нужен ноде. > Четвёртому вообще нужен _integrate_forces(). Нет, _integrate_forces нужен ноде. Понял теперь? >>952933 > Вопрос не в них, а в организации графа конечного автомата, чтобы это не превращалось в головную боль и костыли. У нод своя композиция, у стейтов своя композиция. Она же граф. Она же дерево. Между деревом нод и графом состояний есть точка, стейтмашина, которая переключает внутри себя куррент-стейт. Также стейтмашина при своем создании делегирует стейтам все необходимые данные. Ноды работают со своими коллбэками. Стейты работают со своими коллбэками. Всё логично, просто и разграниченно. Теперь понял?
Еще раз. Коллбэк наподобие _integrate_forces вызывается у ноды. А будет ли она в состоянии его вызывать - это задаётся через стейтмашину.
>>952935 Перефразирую. > Еще раз. Коллбэк наподобие _integrate_forces вызывается у ноды. А а с какими данными нода обработает код - это задаётся через стейтмашину, куррентстейтом.
>>952935 >Нет, _integrate_forces нужен ноде. Так, давай конкретнее.
Вот у меня есть RigidBody, и у него есть состояние бытия по имени FartForwardState. Это состояние должно брать state из _integrate_forces, прикладывать к нему силу fart и таким образом ускорять RigidBody вперёд. Также у этого объекта есть ещё более 9000 состояний бытия, которые я потом сделаю, но пока сфокусируемся на главном.
Ты предлагаешь сделать так: >func on_fart_forward_update(): ??? # тут нужен прямой доступ к rb_state из _integrate_forces >var current_state = RelayState.new(on_fart_forward_update) Что я должен сделать? >func _integrate_forces(rb_state): current_state.update() Это не учитывает rb_state, я не могу его передать в обработчик состояния, а обработчик состояния не может его откуда-то взять, ведь rb_state существует в актуальном состоянии только в _integrate_forces.
Хрень какая-то. Проще через match, раз уж мы не можем передвигать состояния в дереве сцены.
>>952935 Вообще, простейший конечный автомат: >func _integrate_forces(rb_state): >match current_state: >State.FartForward: блаблабла >State.DoBarrelRoll: блаблабла >State.SelfDestruct: блаблабла Здесь State - это просто enum. Правильно? Всё сгруппировано в одном месте, просто и логично, однако, это невозможно настраивать в рантайме.
Если мы создаём отдельный класс State: >func _integrate_forces(rb_state): >current_state.update(rb_state) Всё остальное - в обработчике update состояния. Позволяет нам добавить сколько угодно классов прямо в рантайме, не трогая эту строчку в коде.
Но такой подход плохо сочетается с кучей разных обработчиков нод Godot, ведь в каждом отдельном обработчике могут быть разные параметры: >_input, _unhandled_input - event: InputEvent >_process, _physics_process - delta: float >_integrate_forces - state: что-то там И т.д. Что может понадобиться завтра - я не знаю.
Я пытался прокидывать обработчики туда-сюда, но получается лютая лапша на куче костылей. Тупо некрасиво и запутывает, кто кого где вызывает.
>>952938 >>952947 Ещё очень важный момент, вот этот обработчик >_integrate_forces Доступен только на потомках RigidBody, и state его относится только к конкретной ноде. Это означает, что обработчик состояния не может быть наследником какого-то класса кроме RigidBody, и если мы хотим добавить состояние, требующее работу с _integrate_forces, мы обязаны привязать скрипт к RigidBody, объявить в нём этот обработчик и вызывать из него обработчик состояния... Что всё усложняет на порядки, особенно если у нас все остальные состояния идут через совершенно другие ноды и к физике отношения не имеют.
Ребят, ребят, а где позырить, как максимально пиздатую архитектуру игры пилить? Типа паттерны всякие, компонентно ориентированный подход... Например. Я просто только вкатываюсь в пограмирование и пока еще многого не знаю.
>>952963 В документации, в туториалах на ютубе, в демо-проектах. Но лучше всего - у себя вчерашнего, уже набившего шишки и понявшего как лучше. Опыт и рост это в основном личный путь.
>>952947 Почему бы не сделать просто как в самом годоте? У таймера и аним плеера есть выбор, когда выполнять, в idle или physics. >>952948 Утиная типизация, не обязательно, можно просто проверять есть ли метод _integrate_forces.
>>952974 Я сразу хочу научиться програсмировать правильно и годно. Начал вот пилить астероид шутанчик, но пока еще не оче понимаю что я делаю не правильно.
>>952979 >я не знаю англиского Как ты игоры делоть собрался без английского? Самые подробные и качественные материалы - на английском, зачастую совсем без перевода.
>>952980 >Как ты игоры делоть собрался без английского? Ну у меня уровень - лет ми спик фром май харт. Такого хватит? Просто я где-то на 99.9% понимаю техническуб документацию, но по всей видимости самое главное не могу понять и туплю оче много, часто из-за этого фейлю самые изичные залупки. Ээх.
>>952985 > Ну и как сделать конечный автомат без match и if? Я это делаю через коннекты и сигналы. Каждый стейт - файл-класс, в который входим одним способом и выходим несколькими возможными сигналами. В родителе подсоединяешь сигналы к следующим стейтам.
Например стейт StateFollow - внутри 2 сигнала, target_reached и target_lost. Делаю StateFollow.connect(target_reached, StateAttack) и StateFollow.connect(target_lost, StateIdle), все, теперь из следования ты переключаешься либо в атаку, либо в айдл, ни одного ифа/матча.
>>952992 Учи английский. Технический английский простой. Изначальные авторы годота испаноязычные челы, кто-то вообще из бразильских-португальских джунглей, а годот запилили и комьюнити англоязычное вокруг. Они смогли выучить, а ты нет? Кмон, брух.
>>952996 >Плюнь тому человеку в ебало. Ну не могу я анончику в ебало плюнуть чисто физически Мне совесть не позволяет, ну как ты все не поймешь
>>953000 >Учи английский. Технический английский простой. Спасибо, что посометовал.
>Изначальные авторы годота испаноязычные челы, кто-то вообще из бразильских-португальских джунглей Типа испанский еще учить? Ну хватит уже. Пожалуйста.
>>953001 >Типа испанский еще учить? Нет. Комьюнити, как я сказал, англоязычное. Я к тому что изначальным разрабам тоже пришлось учить английский чтобы прийти к тому, к чему они пришли.
>>953000 >Каждый стейт - файл-класс Ну вот я создал, например: state_walk.gd state_run.gd state_jump.gd state_fall.gd Потом ещё хотел "вприсядку" добавить, но уже с предыдущими файлами обосрался от количества непонятных переходов в своём коде и всё снёс.
А у меня таких стейтов, по идее, десятки должны получиться, из каждого в каждый несколько путей.
Т.е., например, прыгнуть можно и в ходьбе, и в беге; из прыжка можно падать, ходить и бежать; можно ходить и бегать вприсядку, и можно прыгать из ходьбы и бега вприсядку; можно сделать куворок из ходьбы и бега и из ходьбы и бега вприсядку, куворок может быть сразу после прыжка или сразу перед прыжком, или в полёте над землёй, или... Ещё тысячи вариантов. Как я буду между каждым файлом бегать и проверять все условия, кто куда вошёл и откуда вышел? Сложна, нужно что-то проще. Типа массива флагов: [✅] быстро [✅] движется [❌] в воздухе [✅] вприсядку [✅] катясь колобком [❌] с оружием в руках [❌] пытаясь подпрыгнуть [✅] блокирует входящий урон И т.д. Тут сразу видно, что происходит, и не нужно создавать стопицот отдельных классов. Но тогда получается обмазывание множеством match/if...
>>953005 >Как я буду между каждым файлом бегать и проверять все условия, кто куда вошёл и откуда вышел? Если тебе нужны длинные цепочки стейтов то ты хранишь историю переходов и смотришь на нее. Проверяешь эту историю в стейте, если она не подходит - ливаешь из стейта, передаешь контроль следующему кандидату. Но вообще тут я хз, длинные цепочки я не делал.
>>953005 Ваще изи делается. Если ты не знаешь, как такую простейшую механику реализовать, то странно, как ты вообще браузер запустить смог и зайти в этот трежд. Мда уш.
>>953005 >быстро >движется >в воздухе >вприсядку >катясь колобком >с оружием в руках >пытаясь подпрыгнуть >блокирует входящий урон Вот это уже 256 возможных состояний получается. Допустим, некоторые из них не имеют смысла, но всё равно большое количество разных состояний. Я читал про иерархические автоматы, но какая тут иерархия, если все действия примерно равны?
Для NPC такое решается через utility system... https://en.wikipedia.org/wiki/Utility_system Хммм, а если задействовать это для игрока? Игрок прожимает клавиши, а моделька реагирует на это по расчётной полезности... К примеру, игрок зажал: - W чтобы двигаться вперёд; - Ctrl для приседания; - пробел для прыжка. Но моделька уже находится в полёте и может только дрыгать ножками => по формуле выводит, что сейчас продолжаем беспомощно дрыгать ножками. Никаких десятков состояний с переходами тут уже не нужно.
>>953007 >такую простейшую механику реализовать Так это не механика, это как раз архитектура. От неё зависит гибкость дальнейшей разработки.
>>953009 >Вот это уже 256 возможных состояний получается Если делать ветвлением - то да. Поэтому существует компонентный подход:
Один компонент отвечает за движение Другой за скорость Третий за полёт Четвёртый за присядку Пятый за качение колобком Шестой за оружие Седьмой за прыжки Возьмой за блокирование урона
Итого у тебя 8 компонентов, каждый внутри себя имеет 2 простых состояния. И одно кольцо, чтобы править всеми - персонаж объединяет компоненты внутри себя. У персонажа в конечном итоге будет 256 состояний, да. Но явным образом описать надо всего 16. Это компонентный подход.
>>952985 Ты не вкурил. На самом деле у тебя на пикрилейтедах ДВЕ стейт-машины: одна отвечает за анимации и встроена в движок, другая отвечает за перемещение и написана туториалоблогером для нубов, чтобы они познавали силу стейт-машины, при этом оставаясь в рамках доступных им знаний. Я полностью поддерживаю такой подход, потому что это усложнение на один пункт. К ранее изученной базе прибавляется только машина состояний и ничего более.
Вот усложнение на два шага. Здесь мы осваиваем машину состояний и использование типа Callable. А для кого-то, возможно, сразу три шага, потому что тут ещё и словарь используется на манер луа-таблицы.
# описываем, что делают состояния, здесь func idle(delta): блабла
func walk(delta): блобло
func jump(delta): блэблэ
# словарь, в котором перечисляются все стейты var states = { idle = idle, # здесь слева именуется поле словаря, а справа ссылка на объявленную и описанную выше функцию walk = walk, # то есть, это как бы states.walk = walk jump = jump, # и даже то же самое, что states["walk"] = walk }
func _in_StateMachinePlayer_updated(state, delta): if states.has(state): # эту проверку можно убрать, если ты стопроцентно уверен, что эта функция не будет вызвана с неправильным стейтом states[state].call(delta)
>>952938 >>952947 Ладно, короче, я наверное хуйни насоветовал вчера. Делай как тебе удобнее. Вот финишный вариант моей системы. С декларативным переключением стейтов, йопт! Кому надо забирайте, а я пошёл.
>>953018 >8 компонентов Ну так это понятно. Что с ними делать непонятно. Компонентный подход не решает задачу, только изменяет организацию кода (1 файл => 9 файлов).
>на пикрилейтедах ДВЕ стейт-машины: одна отвечает за анимации и встроена в движок Не, там велосипедный аддон: https://github.com/imjp94/gd-YAFSM
>func walk(delta): А если стейту нужен PhysicsDirectBodyState3D?
>>953027 >готовое Там всё как у всех, пикрил. Где интегрейт? Верно, бери исходники и костылируй в них интегрейт... Без костылей и лапши не получается. А весь смысол конечных автоматов - упорядочить код так, чтобы в нём не осталось места для лапши. Не получается.
>>953019 >has_method Да не, нормально всё, если ты не делаешь это тыщу раз каждый кадр. Утиная типизация: >if animal.has_method("quack"): animal.quack() # утка Для ускорения можно использовать StringName: >const QUACK = &"quack" >if animal.has_method(QUACK): animal.quack() В остальном затраты как у обычных вызовов.
Не путайте этот подход с сигналами. Сигналы - это когда тебе заранее всё известно и ты связываешь несколько объектов проводами. Утиная типизация нужна, когда к тебе пришло хрен знает что, но ты должен с ним сделать что-то конкретное.
>>953037 > has_method не видит static func Он его и не должен видеть. Статик-функции это костыль всех "ООП-языков". Сам принцип ООП-языка, "всё есть объект, всё есть метод" - вреден и костылен. Потому что когда нужна просто функция, язык не позволяет без задней мысли объявить императивный модуль с простофункциями, нет, будь добр объявить класс, который тебе нахуй не нужен, а в нём объяви статический метод, который ты будешь использовать как функцию.
>>953040 >язык не позволяет без задней мысли объявить императивный модуль На Паскале вот можно, а это ООП язык: >Paradigms: Imperative, structured, object-oriented, functional, component-based, event-driven, generic
>объявить класс, который тебе нахуй не нужен Но ведь смысл статических методов - не когда тебе класс вообще не нужен, а когда тебе нужно связать метод с конкретным классом, но использовать его вне контекста конкретного экземпляра класса...
>Статик-функции это костыль >когда нужна просто функция Костыль - это анонимные функции, которые ты объявляешь где попало, потому что тебе лень стрелочки на клавиатуре нажимать лишний раз.
>"всё есть объект, всё есть метод" - вреден Почему? Ведь так оно и есть. Этот принцип отрицает существование метафизических сущностей, которые ухудшают читаемость кода (лапшичный монстр). Т.е. вместо обмазывания метафизикой, ты говоришь твёрдо и чётко - всё должно быть материальным объектом, а не больной фантазией дизайнера. И называешь эти объекты читаемыми именами, и обращаешься к ним по имени, ибо существуют. А обмазываясь анонимной лапшой из случайных функций ты только ухудшаешь читаемость кода.
Лучше ООП может быть только язык, в котором сущности не просто объекты, а субъекты, и создание программы заключается в налаживании отношений между ними, но эта парадигма пока не взлетела.
Меня больше бесит неспособность GDScript сделать наследника одного из встроенных классов: Array, Dictionary и т.п. не существуют в потомках Object, следовательно, из них нельзя сделать свой вариант. Пришлось сделать ArrayUtils со static методами - вот это уже костыль, но не из-за ООП, а из-за GDScript.
>>953052 > На Паскале вот можно, а это ООП язык: Паскаль - мультипарадигменный. О чём прямо говорит твой же гринтекст, парадигмы во мн.ч. и через запятую перечислены. К сожалению, паскаля в годоте нет.
> смысл статических методов > когда тебе нужно связать метод с конкретным классом Единственная конкретность там в том, что у тебя имя метода состоит из класс.имя() какая ещё связь-то? Поэтому смысл статических методов в ООП-языках, как я и сказал выше, в том, чтобы через пень-колоду эмулировать мультипарадигму, а именно модульность того же паскаля. Причём в том же паскале началась та же самая дрисня, зумеры забыли, что есть просто функции, просто процедуры, и сделали статик-процедуры в ФПК, и класс-процедуры в дельфи. Что это, я не понимаю. Ебашить велосипеды поверх велосипедов, лишь бы не как диды?
> Костыль - это анонимные функции Но мы сейчас не про них.
> Почему? Ведь так оно и есть. В упомянутом тобой паскале так не есть. Там можно сделать программу без единого класса вообще. Без ООП вообще. Исключительно на императивных модулях.
> Лучше ООП может быть только язык ООП не язык, ООП - парадигма. А классы это лишь одна из реализаций этой парадигмы. Существуют и другие реализации, например, на прототипах (жс), или на типажах (раст). Но в классическом паскале ООП был на типах, просто типах. Классы пришли позднее, как зумерская мода выебываться не как диды. Описываем тип. Описываем реализацию типа. Создаём экземпляры. Работаем.
> Пришлось сделать ArrayUtils со static методами - вот это уже костыль Но мы сейчас не про них.
>>953081 >паскаля в годоте нет При желании добавить можно.
>какая ещё связь-то? В GDScript нет статических полей, к сожалению, но если бы были, то можно было сделать что-то такое: >static func Enemy.spawn(): >_ if Enemy.spawn_count > 0: >_ _ Enemy.spawn_count -= 1 >_ _ return Enemy.new() >_ return null Сейчас тебе обязательно нужен экземпляр класса, чтобы провернуть подобное, или использовать баг в реализации констант, но его могли уже пофиксить.
С другой стороны, да, такой прикол лучше не делать, лучше сделать отдельный EnemySpawner, экземпляр которого имеет собственный счётчик, который удаляется вместе с экземпляром. Видишь, в чём проблема таких функций? Они засоряют глобальное пространство в памяти, что трудно контролировать. >func EnemySpawner.spawn(): >_ if spawn_count > 0: >_ _ spawn_count -= 1 >_ _ return Enemy.new() >_ queue_free() >_ return null И вот мы решили сразу несколько проблем.
>Там можно сделать программу без единого класса вообще. Без ООП вообще. Исключительно на императивных модулях. Да, можно, но ООП подразумевает дополнительный уровень защиты от (архитектурных) ошибок... Думаю, поэтому языки отказались от "бездомных" функций.
>Но в классическом паскале ООП был на типах, просто типах. Классы пришли позднее Я так и не понял, в чём разница между Object и Class кроме того, что Object передаётся целиком так же как Record, а Class всегда по ссылке. В остальном - синтаксис через точку что там, что здесь, особой разницы со стороны внешнего наблюдателя нет.
Вообще, для меня ООП - это синтаксис через точку, всё остальное - незначительные детали внутренней реализации, которые меня волновать не должны: >ссылка на кого = Категория.кто-то новый (какой) >что сделал = кто.что сделает (с чем сделает) И так далее. Вот в этом преимущество ООП - тебе не нужны бессвязные функции, потому что их некому выполнять, если они совсем-совсем ничейные: >что сделал = что сделает (с чем сделает) Кто это сделал? Непонятно. Приходится костылить: >что сделал = что сделает (кто, с чем сделает) >что сделал = кто_что сделает (с чем сделает) Но это по сути то же самое, что и через точку.
Простые модели все чаще редактирую и делаю сам, чем скачиваю, такие как двери и окна. К взаимодействию с Interactable объектами добавил возможность переключаться на привязанную к этому Interactable камеру, как в видео с постером.
Пока гулял по городу, наклевались зачатки основного сюжета. Правда религиозного, православного характера. Наверно сказались натыканные за каждом поворотом церкви и регулярный колокольный звон.
OBS почему-то начал записывать игру из Debug-режима с каким-то дерганным FPS, хз что случилось. Играется гладко.
Какой самый элегантный способ спрайту иметь несколько текстур и менять их по мере надобности? Иметь несколько спратов в одной точке, все вместе перемещать, и чтобы отображался только один из них это очевидное решение, но может есть какое-то более элегантное?
>>953154 Там есть два метода равноэлегантых, выбирай какой тебе удобнее: 1) свойство фрейма анимации, задаёшь сколько у тебя равных фреймов по горизонтали и вертикали, спрайт разрезается внутри по заданной тобой сетке, и показывает только один фрейм. Индекс ты можешь менять сам когда захочешь. 2) свойство региона. Задаёшь ручками регион спрайта, которых хочешь выводить. И всё.
>>953158 > Какой способ производительнее? Вниз по дереву - обращаешься через $; вверх по дереву - обращаешься через сигналы, которые подключает нода сверху ноде снизу. >>953159 > как лучше всего организовать обмен данными между сценами? Через шины (гуглим). В случае с деревом шина уже есть, - это сам корень дерева. Но для пущего удобства в настройках проекта можно добавить отдельную сцену в автозагрузки, она сделается прямым потомком корневого узла и будет видна всем остальным узлам, как синглтон.
>>953161 И ещё. Щас прибегут диванные безыгорники и начнут кудахтать про синглтон-антипаттерн. Не слушай их и не бойся синглтонов. В том же анриле, например, вся архитектура построена на синглтонах и никто не жалуется. > как много я еще не знаю Читай официальные доки (ссылки в шапке). Переводи автопереводчиком, если не умеешь в инглиш. Доки подробные и качественные. В треде не всегда быстро ответят, вот я щас попью кофе и сваливаю ИРЛ.
>>953162 >начнут кудахтать про синглтон-антипаттерн Но ведь сами движки используют синглтоны. Вообще, все эти рекомендации из энтерпрайза не относятся к геймдеву. Более того, они даже вредны, если им следовать.
К примеру, у тебя есть генератор звука и генератор частиц взрыва, ты можешь подключить их к событию нажатия кнопки Button.pressed и тогда по нажатию кнопки будет производиться звук и генерироваться частицы. Теперь ты решил - что-то тут не так, и перекинул соединения с кнопки на Timer.timeout, чтобы те же события происходили по происшествию времени. Код при этом никак менять не нужно, меняется только описание сцены (.tscn).
Такое соединение игровых сущностей становится наиболее выгодным, когда тебе нужно часто переиспользовать одну и ту же сцену в разных местах. Вот у нас есть Button в движке, но она не подходит для размещения на стенах в 3D играх, верно? Ты делаешь свою собственную сцену Button3D, которая объявляет свой сигнал signal pressed, и которую можно поместить в 3D мире, чтобы игрок мог с ней взаимодействовать в пространстве (press E to...). Теперь тебе достаточно закинуть эту Button3D в любое место сцены и подсоединить её сигнал к методам какого-либо другого объекта, например, гаражной двери, лампочки, радио и т.д. При этом ты можешь закинуть просто кнопку, ни с чем её не соединяя - и она по-прежнему будет работать, хоть её нажатие и не влияет ни на что (нет обработчиков).
>к ноде можно обратиться напрямую через $? Так ты связываешь код с к конкретной сценой, в случае с кнопкой у тебя будет $lamp.enable = true, но что, если теперь тебе не лампа нужна, а радиоприёмник или дверь? Ты же не будешь создавать тысячу скриптов типа button_lamp, button_door, button_radio и т.д., в каждый из которых отличается от остальных только строчкой с $.
Конечно, можно написать так: >@export var node: Node >node.do_something() Но во-первых, если мы хотим соблюдать строгую типизацию, возникают трудности с тем, что можно положить в эту переменную, а во-вторых, если ты забудешь положить туда ноду или нода по какой-то причине исчезнет из сцены, твой скрипт сломается. Конечно, можно добавить проверку if node: node.do..., но это не решает всех проблем, т.к. инвалидная ссылка не всегда null, и единственный надёжный способ проверки - через WeakRef...
>Какой способ производительнее? Тут вопрос не в производительности, а в удобстве и гибкости разработки. Но сигналы, по идее, быстрее обращения через $, потому что: - $нода - это сокращение self.get_node("нода") - строка "нода" создаёт новый объект NodePath - get_node() как-то ищет ноду в дереве нод - только потом вызывается метод ноды. С сигналами, если у тебя что-то привязано к сигналу, оно сразу выполняется, и поскольку это один из самых важных концептов движка, внутри оно наверняка очень сильно оптимизировано (сигналы буквально на всех нодах).
Ты можешь ускорить обращение через @export ноды или через @onready, заранее получив ссылку на ноду, но это не решает тех проблем, описанных выше.
>>953159 >организовать обмен данными между сценами Что ты имеешь в виду? Если ты используешь для смены сцены встроенную функцию SceneTree.change_scene, то я не рекомендую так делать - лучше заменять часть дерева целой сцены, так у тебя будет больше контроля. Если всё же хочешь заменять сцены этой функцией, то тебе придётся добавлять ноды в "автозагрузку" и передавать данные через эти ноды - они никак не затрагиваются "сменой сцены".
Если ты имеешь в виду передачу данных вроде передачи предмета из инвентаря игрока на пол или в верстак, то тут уже всё зависит от того, как у тебя игра устроена. Чего-то универсального тут не посоветуешь.
>>953171 >сами движки используют синглтоны Потому что у тебя не может быть два экземпляра Engine, два экземпляра OS. А вот для экземпляра Player, два экземпляра WorldMap и т.д. - запросто. Новички обманываются синглтонами и потом не могут понять, почему движок не даёт им создать второго Player без кучи фатальных ошибок в коде.
В большинстве игр синглтоны не нужны. Синглтон нужен только если тебе вот прям обязательно нужно выбить в граните "сцена God может быть лишь одна и обращаться к ней нужно только с большой буквы". Естественно, что это очень вредный антипаттерн.
Этого не слушай, он уверовал в Синглтон и теперь проповедует о его могуществе ньюфагам: >>953162 >Не слушай их и не бойся синглтонов. Ага, обязательно обмазывай весь код кучей лишних Имён, которые потом хрен вырежешь из кода, когда они неизбежно пукнут и обмякнут кучей ошибок.
Особенно смешно смотреть на то, как новички объявляют синглтон Global и завязывают на него всю игру, по сути высирая тонну бесполезной лапши, которую они даже сами не смогут использовать для другой своей игры, т.к. всё слишком запутано в этом божественном объекте, на который молятся все остальные скрипты игры.
Но если ты любишь трудности, тогда можешь хоть намагниченной иголкой биты в жёстком диске переворачивать, программируя игру в машинных кодах - бояться тут нечего, это просто форма БДСМ.
>В том же анриле >никто не жалуется. Это потому что: - ААА студии сами могут переделать движок; - нищих индюков никто слушать не будет, лол; - синглтоны движка != скриптолапша твоей игры.
>>953174 >перекинул соединения с кнопки на Timer.timeout >Код при этом никак менять не нужно Чёт не подумал сразу. На самом деле, у сигналов с разными аргументами должны быть разные обработчики... По крайней мере, если ты хочешь статическую типизацию... Совсем без изменений в коде можно перекинуть только сигналы с одинаковыми аргументами (особенно их количеством).
>>953160>>953162 >Через шины >отдельную сцену в автозагрузки >видна всем остальным узлам, как синглтон >не бойся синглтонов Вот тебе иллюстрации возможных архитектур игры. Какую себе возьмёшь, какую конкуренту оставишь?
>>953213 >Классная документация, кайфую. Стена текста больше чем этот тред и простого примера как прокинуть цвет и покрасить им пиксели нет. Документация хорошая, просто она не для тебя.
>>953214 Абсолютно норм. На то они и "звездные объекты". Только долбаеб будет делать синглтоном 100500 незначительных объектов. Шина тоже звездный объект.
>>953220 Как-то хуево пояснил. 1) Даже если у тебя код модульный и все круто, в программе нет глобальной области видимости. У тебя есть модуль с состоянием. Ты этот модуль импортирует в 100500 других модулей. Состояние глобальное. 2) Ты не можешь программировать без глобального состояния. Ты не можешь с помошью ивентов в шине синхронизировать 100500 состояний если тебе именно требуется одно глобальное состояние 3( Ты должен организовать какой-то протокол мутирования этого состояния юзерами этого состяния.
>>953216 >звездный объект Конкретнее давай, не выдумывай новые термины. Ты таким образом божественный объект зовёшь?
>100500 незначительных объектов Да, лучше 1 god object, который всё про всех лучше всех знает и всё на свете умеет без посторонней помощи. Зачем тебе вообще ООП, зачем тебе ноды, ресурсы и вообще какой-то там движок, если ты можешь всю игру в один скрипт уместить?
>>953220 >без глобальных переменных ни одна сложная программа не обойдется БЕЗ ВОДЫ ТЕБЕ НЕ ВЫЖИТЬ @ ВЫПИЛ 10 ЛИТРОВ ЗА ЧАС И УМЕР @ НО ГОВОРИЛИ ЖЕ ЧТО БЕЗ ВОДЫ НЕ ВЫЖИТЬ
>>953227>>953228 Понятия не имею, о чём вы теперь спорите, но я подорвался на всех этих глобальных сущностях несколько раз и больше не собираюсь.
Если что-то можно изолировать - это необходимо изолировать. В этом один из фундаментальных принципов ООП - инкапсуляция. Если у вас код хоть немного запачкан ссылками на что угодно "где-то там", то это нарушение инкапсуляции и ваш код уже начал разъезжаться в непонятную хрень.
И чем дальше - тем только хуже.
Конечно, всё относительно. API движка мы вообще не рассматриваем в этом споре - не надо про Input и прочее, ведь движок вы не каждый день меняете.
>>953231 Это я все один писал. >не выдумывай новые термины. Ты таким образом божественный объект зовёшь? Глобальный стейт. >Да, лучше 1 god object, который всё про всех лучше всех знает и всё на свете умеет без посторонней помощи. Не он обо всех знает, а все про него знают. Это две больших разницы. Я сказал что без глобального стейта программы не пишутся. Так что нет альтернативы синглтоны (или что-то другое что этот глобальный стейт хранит) или события. >В этом один из фундаментальных принципов ООП - инкапсуляция. Инкапсуляция тут не причем если тебе нужно врямя суток в игре сделать, и тобы все обекты игры на это время суток реагировали
>>953232 >без глобального стейта программы не пишутся Наличие у программы глобального состояния не значит ни что об этом состоянии должны знать все компоненты программы, ни что это состояние должны мочь модифицировать любые компоненты программы. Если у тебя где-то в глобально доступном месте есть галочка "игрок проиграл", её могут видеть и изменять любые части игры - это хорошо? Допустим, что это не плохо - но зачем так делать? Ты планируешь читать/изменять это состояние из случайной строчки кода в случайном файле? Нет? Тогда зачем она глобально всем доступна? Запакуй её куда-нибудь подальше и выдавай строго по разрешению, чтоб никто не мог тайком её дёргать. Даже если ты работаешь один - накодишь что-то в плохом настроении, а через неделю не разберёшься, что ты накодил.
>если тебе нужно время суток в игре сделать Делаю систему времени и размещаю её в игровом мире, который не является глобальной сущностью.
>и чтобы все объекты игры на это время суток реагировали Зачем всем объектам игры реагировать на время суток? У тебя в любой игре будет масса объектов, которым время суток вообще никак не нужно - а оно у тебя отовсюду доступно. Ещё меньше будет объектов которые могут как-то повлиять на течение времени - а оно у тебя кем угодно изменяется.
Если у тебя время суток доступно откуда угодно, однажды ты можешь решить на скорую руку изменить время из какого-нибудь мутного участка кода. В этот момент тебе будет казаться, что это оправданное решение и ничего плохого из этого не будет - игра ведь продолжает работать, ничего не сломалось. Пока не сломалось. Но ты уже запутал клубок и дальше он будет только затягиваться, если ты не решишь заняться рефакторингом. Потому что ты обязательно забудешь, где у тебя время реально читается и модифицируется, а где только доступно.
А ещё ты можешь захотеть сделать в игре, скажем, телевизор с фильмами - и фильмы эти "снимать" прямо в игровом мире. Вот только в игре сейчас ночь, а по телевизору фильм в полдень - ты не можешь просто разместить камеру в реальном игровом мире, тебе нужна копия. Если твой игровой мир может существовать сам по себе, обладая собственной, независимой системой времени, ты легко сделаешь независимую модель мира для телевизора - у которой будет своё время. Если же ты сделал систему времени синглтоном и связал с ним кучу других файлов, ты либо вообще не сможешь сделать задуманную фичу, либо убьёшь кучу времени на рефакторинг, спотыкаясь на непонятных ошибках, о причинах которых ты наверняка давно забыл (потому что дёргал синглтон из рандомных мест в коде).
На пикриле у системы времени строго определённое место в дереве сцены и доступ к ней регулируется. Если ты не используешь хрень вроде get_parent().get_parent() или get_node("/"), а корректно объявляешь @export в нодах, легко понять, кто получает доступ к системе времени. Тут не будет внезапных строк вида "WorldTime.time" где-то в середине 1000-строчного скрипта, в заголовке которого (и инспекторе) нет ни слова о системе времени. Ты можешь заменить систему времени на альтернативную или вообще заткнуть пустой заглушкой, чтоб исключить её из геймплея. Можешь создать несколько миров с разными системами времени, в которых будут полностью независимые ИИ, живущие по разным графикам. И если ты перетащишь свою систему ИИ в новый проект, тебе не обязательно срочно объявлять систему времени или переносить вместе с системой ИИ старую систему времени - она сможет работать и без неё (скажем, твои NPC могут жить вне времени, если данных об актуальном времени почему-то нет).
Нет, я не говорю, что все должны делать именно так. Но я на грабли синглтонов наступил несколько раз и результат мне не понравился. Это только в самом начале кажется удобно, пока о будущих проблемах ничего не знаешь.
>>953185 Во-первых, ты безыгорный шиз, который воюет с синглтонами. Во-вторых, почему шина на второй картинке не синглтон? В-третьих, что означают стрелочки?
>>953248 >ты безыгорный Есть прототипы игр, я в них играю.
>воюет с синглтонами Потому что жопа сгорела с них.
>на второй картинке не синглтон По-быстрому накидал же, долго не думал.
>что означают стрелочки Ну, типа, кто кем владеет/управляет: А -> Б А командует Б как захочет (дёргает методы и поля). Б может только просить А (излучает сигналы).
Завез отопление, продолжил меблировать комнату. Много же времени это занимает. Все думаю, поставить ПК или нет. Если ставить, то обыгрывать это дело придется. Время событий, ориентировочно - середина/конце девяностых.
Внезапно обнаружил что glTF версия моделей на скетчфабе уже имеет ao/metallic/roughness текстуры сплавленными в одну orm-текстуру. Вот бы времени сэкономил если бы удосужился посмотреть раньше.
Нашел в найстроках захвата экрана OBS параметр скорости захвата и поставил "fastest", запись снова стала гладкой. Странная фигня.
>>953260 Выглядит-то лампово, но где геймплей? Хорошо, ты продемонстрировал всем, что умеешь красиво флипать ассеты в ВСЖ-стиль. Молодец. Теперь возвращайся к блокингу и пили уже геймплей. Иначе велика вероятность, что уже напиленные тобой квартиры придётся долго и нудно переделывать.
Я в ахуе. Им говоришь, что игру делать надо, а не демку красивую с тенями и глобальной иллюминацией. Им видосы показываешь с блокингом от именитых студий (блокинг сцена из анчартеда, например). Нет, не слушают нихуя, продолжают лепить постпродакшен на стадии предпродакшена.
И да, я безыгорник, напоминаю, я диван, у меня нет имени, у меня нет авторитета.
>>953305 Я не он, но будем откровенны, своей игрой тут вряд кто-нибудь озолотится. Делонье игрочьтки - для местных больше хобби, чем способ заработка, так что надо делать то - что больше интересно.
>>953306 Заработок тут не при чём. Я бы поиграл в сх-лайк от анона, но с таким подходом, он наиграется в декорацию сценок с брождением по ним в дебаге и отыгрышем в голове. И всё. Ничего кроме видосов в треде мы не увидим.
>>951925 (OP) Уважаемые, как сделать Camera2D текущей? Раньше был чекбокс Current, которого у меня почему-то нет. Первый пик это из интернетов (чекбокс есть), второй пик это мой годот 4.2.2
>bool enabled = true >Controls whether the camera can be active or not. If true, the Camera2D will become the main camera when it enters the scene tree and there is no active camera currently (see Viewport.get_camera_2d). >When the camera is currently active and enabled is set to false, the next enabled Camera2D in the scene tree will become active.
>bool is_current ( ) >Returns true if this Camera2D is the active camera (see Viewport.get_camera_2d).
>void make_current ( ) >Forces this Camera2D to become the current active one. enabled must be true.
Перевод deepl.com для самых маленьких:
>bool enabled = true >Управляет тем, может ли камера быть активной или нет. Если значение true, то Camera2D станет основной камерой, когда она войдет в дерево сцены и в данный момент нет активной камеры (см. Viewport.get_camera_2d). >Если камера активна в данный момент, а значение enabled равно false, то активной станет следующая включенная Camera2D в дереве сцены.
>bool is_current ( ) >Возвращает true, если эта Camera2D является активной камерой (см. Viewport.get_camera_2d).
>void make_current ( ) >Принуждает эту Camera2D стать текущей активной камерой. enabled должно быть true.
>>953367 Слушай, ещё помощь нужна, поясни пожалуйста, как компонентам часть значений менять, я вижу только set. Неужели надо создавать рид онли переменные, брать из них всё, кроме того, что я хочу изменить и потом при помощи set заменять старый компонент?
Как в игру добавляют кучу мобов по спрайт-листам 2д? Смотрю всякие видеоуроки и читаю, пишут, что экспорт спрайт листа в годоте, это обычно создание сцены, добавление AnimatedSprite2d, там создание всяких idle, run, attack и т.п. анимаций через импорт спрайт-листа и выбор фреймов, скрипты. И потом добавление уже в нужную сцену. А что делать, если мобов много? Создавать для каждого сцену и настраивать в ручную?
>>953439 Если у тебя там реально сотни разных мобов, пиши скрипт для автоматического импорта и настройки. Скрипты можно выполнять прямо в редакторе. Все операции в GUI редактора можно делать из кода. https://docs.godotengine.org/en/stable/tutorials/plugins/running_code_in_the_editor.html Хранить мобов лучше отдельными сценами, если потребуется что-то исправить вручную или создать новый вариант имеющегося моба.
>>953443 Да не, тут вопрос не в отдельных компонентах а в нежелании создавать лишний раз переменные. Хотя из моего эксперимента с системами - они сами могут по менять содержимое без лишних приседаний и GetMut. Так-то у меня есть уже игра-в-разработке, но мне что-то не нравится как библиотека Arch работает, вот и решил сменить шило на мыло.
>>953439 Понимаю, что ты молодой шутливый, но я сортировкой ассетов занимаюсь свободными вечерами, сажусь под какой нибудь сериальчик или анимце. А так, поищи в ассетах по import или animation или wizard. Вот этот, например, импортирует из aseprite (там есть возможность называть промежутки кадров каким то словом). https://godotengine.org/asset-library/asset/1415 Или вот другой https://godotengine.org/asset-library/asset/1880 Может есть и для чего-то другого. Как анон выше сказал, можешь написать свой, под свою схему названий файлов.
>>952992 >Ну это же на английском, друг. Господи, дауничи ебаные, вы до сих пор не в курсе что уже давно можно переводить звуковую дорожку ютюба (да хоть порнхаба, блять!) расширением для браузера? Откудаж вы берётесь? Вы в бункере живёте?
>>953450 > расширением для браузера Оно не работает. Для хлебушков (типа меня) проще яндекс.браузер поставить и в нём всё искаропки без пердолинга работает.
А за нейминг всего говна какой то один испаноговорящий чел отвечает или "коммунити"? Почему с ним такой пиздос? Причем смотрю в мигрейшн гайд с 3 на 4 и там адекватные названия переименовывают в какой то бред.
>>953458 Потому что ты кинул проект с файлом godot.project. Годот в этом случае на всякий случай отключает папку, вдруг у тебя туда реально другой проект случайно скопировался.
Кто-нибудь видосы вставлял в свои проекты? Документация советует формат Ogg Theora, насколько оно подводно-каменистое? Не отвалится на какой-нибудь китайской мобиле?
Если мобы отличаются только косметически, т.е. условным цветом кожи - это одна сцена с опциями.
Если мобы отличаются радикально, т.е. имеют абсолютно разные способности - это разные сцены.
Если мобы отличаются, но имеют много общего между собой, т.е. их можно выстроить в некую иерархию как реальных животных - это сцены с наследованием, т.е. имеют предка и наследников.
Можно пойти путём компонентов и собирать мобов из множества кусочков прямо на ходу. Но тебе будет банально удобнее тестировать, имея набор заранее собранных сцен с наборами компонентов, чем если ты будешь их в коде соединять в дерево.
В целом - экспериментируй и смотри сам, что тебе больше нравится или лучше идёт твоим задумкам.
>>953456 >Почему с ним такой пиздос? Приведи примеры конкретных названий, тогда будем разбираться. Могу найти обсуждения на гитхабе, где переименования обсуждали (с голосованием).
Алсо, переименовать давно хотели, но ждали 4.0, чтоб соблюдать правила https://semver.org/
>>953466 Обычно да, делаю в духе MVVC, когда есть сцены под всех мобов которые сами занимаются своими анимациями, а эта сцена уже вставляется в какую-то общую сцену персонажа, который имеет управление игроком или поведение ии и переключает анимации соответствующе.
>>953463 А хрен его знает. Может, проще написать андроид плагин для такого? В 3 есть какая-то недокументированная функция OS.native_video_play. Но с ней тоже непонятно.
>>953476 Ну там все написано У типа int нет поля error. Это значит, что result - int. parse() возвращает не объект пару (error, result) Он возвращает код ошибки, не помню какой, ERR_чтото, либо OK
Проверяй не result.error, а сам result != OK. Если OK, то данные не в result.result, а в json.data.
>>953475 >подсказки для самых тугодумов >2-4 секунды видео Лучше делать скриптами из игровых ресурсов: - актуальное отображение, даже если изменятся иконки, текстуры, биндинги клавиш и т.д.; - максимальное разрешение без артефактов, при том практически не добавляет лишнего веса игре; - можно сделать интерактивным и пошаговым, чтоб игрок сам подсвеченные тобой кнопки нажимал в комфортном ему темпе, успевая читать надписи; - легче встроить в игровой процесс/мир - у игрока не будет переключения ментального контекста.
Имхо, видео-подсказки - прошлый век. Как и список портянок со скриншотами-иллюстрациями. Ты игру делаешь или википедию про игру? Обучай игрока интерактивно, иначе не поймёт или заскучает.
>>953475 Если не хочешь делать ролик на движке, то; Видео это просто быстро меняющиеся картинки. Видеофайл просто использует хиьрое сжатие, поэтому зпнимает мало места, но тормозит. Ты можешь показать просто слайдшоу из 30 пнг в секунду. Возможно они даже сожмутся в apk нормально.
func load_combinations(file_path): var file = FileAccess.open(file_path, FileAccess.READ) if file: var json_text = file.get_as_text() print("JSON Text:") print(json_text) file.close()
var json = JSON.new() var error = json.parse(json_text) if error != OK: print("Error parsing JSON: ", error) else: print("Combinations loaded successfully:") print(json.data) # Accessing parsed data from the JSON instance else: print("Combinations file not found")
>>953483 >слайдшоу из 30 пнг в секунду. Возможно они даже сожмутся в apk нормально. PNG не сожмутся, потому что они уже используют максимально эффективное сжатие без потерь. Дальнейшее сжатие возможно только если у тебя почти одинаковые PNG файлы, с большими повторяющимися блоками, что в случае геймплейного видео маловероятно.
Рекомендую не изобретать велосипед и сделать как во всех приличных мобильных играх сделано - игра блокирует все возможные пути кроме верного, игрок запоминает это на уровне мышечной памяти.
>>953475 Алсо, если геймплей такой сложный, что ты хочешь показывать летсплей, стоит ли оно вообще того? Не лучше ли будет снизить планку сложности? Игрок не станет умнее от того, что решит твой ребус.
>>953488 >Алсо, если геймплей такой сложный, что ты хочешь показывать летсплей, стоит ли оно вообще того? Не лучше ли будет снизить планку сложности? Геймплей не сложный, я просто разочаровался в способностях игроков, особенно мобильных. Мои предыдущие игры показали что механики, которые тебе и мне кажутся интуитивными, для других окажутся невыполнимыми. Текст такие игроки не читают, думать ленятся, а за ручку всю игру держать не станешь.
Вот хороший видос на эту тему: https://www.youtube.com/watch?v=ax7f3JZJHSw ^ и опять же, этот видос про взрослого человека из развитой страны, тогда как среди мобильных геймеров полно детей из задниц мира с ограниченным игровым опытом, компов они не видели, английский не знают, зато могут на изи влепить тебе 1 балл в гугл плее.
>>953499 Как посмотреть? Видеоскачиватели выдают ошибку.
>>953534 >не любит коммиблочную романтику (ВСЖ) Что это вообще за мем?
Мне вот нравится атмосфера условного Гигахруща, но однотипные игры уровня "вот комната, в ней есть ковёр, диван, шкаф, телевизор" я не понимаю. У меня ИРЛ дома точно такая же обстановка, какой смысл делать симулятор ходьбы виртуальный музей про мою квартиру в десятках игр?
>>953538 > Что это вообще за мем? Происходит от знаменитого высказывания "забыл в какой стране живёшь?" сократилось до ВСЖ. Суть ты уже сам описал: > "вот комната, в ней есть ковёр, диван, шкаф, телевизор" К сожалению, любимый тобой гигахрущ - это тоже ВСЖ, причём самый апогей.
>>953491 >Текст такие игроки не читают, думать ленятся, а за ручку всю игру держать не станешь. ПРОСТО блокируешь всё управление кроме одной единственной кнопки, которую нужно нажать, или единственного элемента, который нужно сдвинуть.
Мобильные игры так и учат: 1. Нажми сюда, чтобы открыть инвентарь. 2. Свайпом объедини два предмета в новый. 3. Нажми сюда, чтобы надеть предмет на себя. 4. Нажми сюда, чтобы повысить уровень предмета. 5. Нажми сюда, чтобы закрыть инвентарь. 6. Нажми сюда, чтобы использовать предмет. 7. Посмотри сюда, чтобы увидеть эффект предмета. 8. Ты восхитительный игрок, вот тебе лутбокс. 9. Нажми сюда, чтобы открыть лутбокс... Потом ты можешь делать что захочешь, но ты уже знаешь основные элементы управления и задачи.
>этот видос про взрослого человека Это видос про человека с явным топографическим кретинизмом (ваще не ориентируется на местности), отсутствием любопытства (не пытается нажать все возможные кнопки на геймпаде - НА ГЕЙМПАДЕ, анон, там буквально 3.5 кнопки - эти устройства специально для детей, не приученных к взрослой клавомыши) с полным отсутствием способностей к обучению (даже осознав, что мышку НЕОБХОДИМО двигать, она продолжает ходить боком как краб).
Таким людям сложные игры противопоказаны. Их предел развлечений - мять в руках мягкие игрушки.
Алсо, в видосе виден тупой геймдизайн ААА игр: налепливают кучу реалистичных декораций, но механики игры противоречат этим декорациям. Например, там, где игра требует бежать по строго определённому пути, наказывая игрока невидимой килзоной вместо ясно видных и понятных барьеров. Проблема не в игроке, а в дизайнерах и сценаристе.
Или тот же дум - заставляет играть единственным возможным способом, наказывая игрока за любое отклонение от задумки дизайнера: стрелять в лоб с дробовика вместо использования огнестрела как огнестрела, нажимать кнопку Е вместо очевидного использования игровых механик (бочки). Опять же, виноват тут только геймдизайнер, а не игрок.
>Почему я не могу сделать так? >Потому что потому)))) и ваще игры сложна делать) Нет, потому что геймдизайнер дурачок и влошил все средства в реалистичные декорации вместо базовых игровых механик и их взаимодействия друг с другом.
Так и представляю: >Тестировщик: бочки не наносят урон врагам... >Дизайнер: у нас нет времени фиксить это. >Тестировщик: игрок может пройти не тем путём. >Дизайнер: аааыыы... ну поставим килзону, лол. >Тестировщик: а сюда почему нельзя прыгнуть? >Дизайнер: так задумано, иди по стрелочке!!! >Тестировщик: залез в дом и ничего не случилось. >Дизайнер: ну что за люди, иди по стрелочке... Современные игры такие современные. Скорее бы сверхинтеллекты AGI порешали весь ААА геймдев, лишив этих дурачков контроля над дизайном игр.
>могут на изи влепить тебе 1 балл в гугл плее Оценки в Гугле давно потеряли смысл, их лепят от балды все, кому не лень. Ребёнок тебе влепит 1 балл не потому, что ему что-то не понравилось, а потому, что он может нажать кнопку голосования. Тот, кому не понравилось, скорее просто удалит и забудет.
Привет гейдевы. Вопрос - у меня есть ряд однотипных объектов (спрайтов) внутри ноды2д. На все эти спрайты должен действовать один и тот же скрипт - х.gd Могу ли я закинуть спрайты в какой-нибудь "контейнер" и назначить скрипт на него? (Чтобы спрайты наследовали скрипт от него) Или мне все еще нужно назначить этот скрипт на каждый спрайт?
И если такого контейнера не сделать, как мне назначить один и тот же скрипт на множество элементов? Если выделить их, Attach Script просто не появляется. По одному прокликивать?
>>953554 Ты скорее всего смотрел видос без перевода, со своим техническим английским на троечку. Потому что весть твой длиннопост подробно и по пунктам опрокинут в видосе.
>>953556 > Attach Script просто не появляется. По одному прокликивать? У них всё еще есть инспектор, и там всё еще есть поле "скрипт", в которое можно сразу всем скрипт назначить. Но ты верно догадался, что такие вещи лучше делать в одном вышестоящем скрипте.
>>953540 >К сожалению, любимый тобой гигахрущ - это тоже ВСЖ, причём самый апогей. Я представляю себе Гигахрущ как пикрил, но в масштабах целой планеты или всей вселенной: - хаотичная застройка на крышах соседей; - лютый срач, который просто некуда девать; - тяжёлая промышленность в одном доме со школами и развлекательными учреждениями; - внутри легко заблудиться, однако выходить из этого тесного лабиринта жильцам не нужно, у них всё своё; - натуральный киберпанк, каким он должен быть, без лишнего блеска, неона и избыточного пространства.
А в играх "ВСЖ" всё слишком чистое и просторное, как будто зашёл в музей, где экспонаты аккуратно расставили, демонстрируя жизнь древних людей.
Зачем тебе это всё нужно? Ты что-то не то делаешь.
>должен действовать один и тот же скрипт - х.gd Если я правильно понял твою проблему: 1. Создай сцену, у которой корень - Sprite2D. 2. Сохрани её как-нибудь вроде "element.tscn". 3. Дай ей один общий скрипт "element.gd". 4. Добавляя элементы в какую-то другую сцену, меняй им картинку элемента и другие параметры. ИЛИ 4. Унаследуй от element.tscn несколько новых сцен, настрой их как следует, сохрани fire.tscn, water.tscn и т.д., и уже эти сцены-потомки используй в сцене.
Использовать "контейнер" не советую, если эти твои элементы должны быть независимыми сущностями. Контейнер имеет смысл для функций, которые нужно производить над большим количеством сущностей независимо от их индивидуальных особенностей.
Т.е. тут вопрос в том, что ты реально хочешь сделать.
>Если выделить их, Attach Script не появляется Потому что это противоречит воркфлоу движка. Ты должен создавать новые сцены и использовать их, а не возиться с отдельными нодами в одной сцене.
Когда понимаешь эту концепцию, становится легче.
>получаю Спрайт2. А я хочу получать Спрайт_2 Зачем тебе это? Номер ни на что не влияет. Лучше переименуй во что-то осмысленное, чтобы цифры вообще не было в названии, иначе запутаешься.
Анон, что можно расположить в этом закутке у входной двери? У меня бы там был шкаф с инструментами, но по задумке хозяином квартиры была одинокая бабулька, так что инструментарий едва ли там возможен.
>>953588 >У меня бы там был шкаф с инструментам Лол, у меня тоже. Была фальшстена с дверью и внутри много полок да самого верха.
>одинокая бабулька Думаю, в этом случае там был бы советский столик со скатертью и фотографиями/иконками и возможно цветами, ну или комод хотя они не так были распространены.
>>953590 А, ещё у моей бабушки на таком столе стояло большое радио с часами. Но правда для этого рядом должна быть радиоточка, а она обычно на кухне вроде как.
>>953590 >Думаю, в этом случае там был бы советский столик со скатертью и фотографиями/иконками и возможно цветами, ну или комод хотя они не так были распространены.
>>953566 >объясняйте новичкам азы игр Что контрится его же примером "у игрока включается туннельное зрение, и он НЕ ВИДИТ ВАШИХ ОБЪЯСНЕНИЙ И БЬЕТСЯ ЛБОМ В СТЕНУ". Алсо, если уж ААА игры не осилили нормальное объяснение, а для ААА игр критично расширить аудиторию - отчасти поэтому туда добавляют сильных женщин, прячут кровь чтобы снизить возрастной рейтинг, льют желтую краску и прочее подобное - то странно ожидать что обскурная инди, слепленная двачером в одно ебало, справится с этим лучше.
Видишь, как кто-то в игры не играл - хватаешь за руку и начинаешь ему объяснить, что он не так играет в игры и вообще нуб полный. Он слушает и начинает осознавать суть геймерства. Становится геймером и больше не нуждается в туториалах.
В этом основной посыл видео, если отбросить затронутые проблемы с геймдизайнерами.
>>953588 >закутке у входной двери >хозяином квартиры была одинокая бабулька Навали туда всякого хлама, чтобы сложно было разобрать, что есть что. Пакеты, мешки, какие-то тряпки, ящики всех цветов и размеров, банки.
И обязательно нужно ободрать потолок, пол и стены, насрать по всем углам и нарисовать старые потёки. Обжить помещения, чтоб чувствовалась душа.
А то у тебя как будто палата в больнице. Нет, даже в больницах не бывает таких стерильных помещений.
>>953613 Слишком много времени уйдет. Было бы здорово добавить естества в виде потертостей и следов, но слишком долго. Я и так уже затрахался квартиру обставлять.
>>953613 В Питере есть такое. Идешь по улице архитектура, дорогие бутики, дефелируют модные тяночки. Окно с разбитым стеклом занавешенное грязной половой тряпкой смотрит на тротуар с прохожими и проезжающими мимо трамваями.
>>953573 Я тебя уверяю, если бы ты сделал эту игру сам, у тебя вышло бы точно такое же. А разгадка проста: хлам и срач сделать намного сложнее, чем "чистые, аккуратные" кубы с текстурами.
>>953614 > уже затрахался квартиру обставлять А зачем тебе годот? Квартиры обставлять гораздо удобнее в SweetHome3D - там и режим брождения от первого лица есть.
>>953645 Какая нахуй разница, автор ты или нет, лол? Ты одобряешь подобное, а значит сам не соблюдаешь хороший стиль (либо склонен его не соблюдать). Не удивлюсь, если ты еще босоножки с носками носишь.
Вместо делания и релиза игры за игрой за игрой и набора популярности, будем табы на пробелы и пробелы на табы заменять, шинами по синглотам друг друга дубасить и архитектуру флеппи берда в сотый раз перетряхивать. Вот что ноудев с людьми делает.
>>953646 > Ты одобряешь подобное Какое подобное? Код работает? Работает. Интерфейс в инспектор вынесен? Вынесен. Ты просто работаешь с меню, и не глядишь в код. Попустись уже.
>>953650 >Код работает? Работает. Если ты косплеишь дерево, то не надо. С самого начала понятно, что ты скорее всего не умеешь в хороший стиль (и я об этом уже писал в прошлом посте, а ты все пытаешься доказать очевидное)
>>953643 >не игру делаешь, а чужие плагины разглядываешь >>953647 >релиза игры за игрой за игрой >>953650 >Код работает? Работает >просто работаешь с меню, и не глядишь в код !!! АССЕТФЛИПЕР В ТРЕДЕ, ВСЕ В GODOT ASSET LIBRARY !!!
>>953660 >пытается выдать "писать уродливый и неконсистентный код" за "тебе просто не нравица" Иди что ли книжки почитай по прогроммизму, раз не учился нигде.
>>953664 Не, пчел, это ты тут пытаешься выдать вылизывание кода по десятому кругу за некую продуктивность, за финальный продукт, который можно пощупать и поиграть. Ты как те наивные ньюфаги с идеями на миллион. Сами по себе их идеи не стоят ничего, как ничего не стоит и твой чистый код без законченного продукта.
1. Ты взял этот скриптик с гитхаба и не глядя вставил в игру. 2. Изменил параметры через инспектор по своему вкусу. 3. Релизнул игру/апдейт с этим меню (у тебя есть игроки). 4. Игроки (лично уважаемые тобой люди) поиграли и сказали: >говно какое-то, неудобно, сделай так-то и так, будет лучше 5. Ты открываешь проект, лезешь в инспектор к этому скрипту. 6. Меняешь параметры, но не можешь добиться желаемого. 7. Решаешь всё-таки посмотреть скрипт и доработать его. 8. А там говно уровня "и так сожрут, бесплатное же".
>>953671 >а если напишут плохое! Вот когда напишут тогда и приходи. Спойлер - не напишут, потому что игры нет, и скорее всего не будет. Через год-полтора возни и байтоебства интерес иссякнет, появится новая идея, а текущая пополнит собой архив. И так по кругу у каждого второго гейдева.
Тогда как рядом сидят всякие Тоби Фоксы и на километровых портянках иф-елсов ебашут хиты с фанбазами размером со среднюю страну.
Здарова годаны, чет я прям на долго пропал, думал сразу вторую игру начать делать после релиза первой, ну собсно так и поступил, только вот муза покинула и мне максимально не интересно стало заниматься ей. Сидел я вобщемто до сия момента нихуя абсолютно не делал, ждал вдхновления, и таки вроде чето да пришло в голову, буду кликер делать, да не такой который за 5 минут на коленке собрать можно, а чуть посложнее. Ассеты напизжены, можно начинать. Ну да, буду тем самым выблядком ассетфилипером, в оправдание скажу лишь то что это в разы сокращает производство игры ибо на рисование у меня уходит львиная доля времени, а на моделирование тем более. Пикрил кстати то что заработало мое говно за время с момента релиза, 6 мая вроде дропнул. Немного обидно, да и похуй, сам виноват ибо мимо мейн аудитории яндекса умышленно стрелял. Короч в планах кликер за неделю, а дальше сидим думаем че делать дальше. Высираться итт оч редко буду, пакедава.
>>953685 Маладца, это уже больше чем у половины гд. Продолжай работать. Алсо ты не думай что 50.52р это все, что твоя игра в состоянии заработать. Площадок в интернете много - выкладывай и на другие. Я свои поделки в перерывах от работы раскидываю повсюду. Да, даже если не сможешь обойти санкции и монетизироваться на западной площадке - все равно выкладывай. И лепи ссылки на свои соцсеточки/бложеки/аккаунты.
>>953625 Пока не доделал, но этот код должен помочь. Для кругового меню нужно, как минимум: 1. Кнопки (любой Control, но лучше Button). 2. Определить позиции всех кнопок по формуле. 3. Округлить позицию курсора до позиции кнопки. Всё остальное дорабатывается по желанию и вкусу. Можно без кнопок (только _draw), но кнопки удобнее.
>>953686 Понятное дело что желательно и на другие площадки тоже лить, в планах пока только в вк и дноклы ползти. Но все равно спасибо за советы. >>953691 Пасиб :3
>>953701 Не, это отличный код. А то, что он выглядит как хуйня и что его сложно поддерживать - это вкусовщина. За чистотой кода зачем вообще в 2к25 следить, вы шизы что ли.
ЩА ПО-БЫСТРОМУ ЗАПИЛЮ ПИРОГ МЕНЮ НА BUTTON @ ВОТ ТАК, ВОТ ТАК, ГОТОВО, НЕПЛОХО ПОЛУЧИЛОСЬ @ ТАК, А ТЕПЕРЬ ДОБАВИМ КРАСИВУЮ ОБВОДОЧКУ @ А КРУТО ПОЛУЧИЛОСЬ, С АНИМАЦИЯМИ ВАЩЕ НИШТЯК @ ВСМЫСЛЕ _DRAW РИСУЕТ ПОВЕРХ СТАНДАРТНОЙ КНОПКИ? @ ТАК, ПАДАЖЖИ, ЩАС РАЗБЕРЁМСЯ, ЕСЛИ РИСОВАТЬ... @ А ЕЩЁ НУЖНО ПОВЕРНУТЬ НАДПИСИ ПОД УГЛОМ?.. @ ДА ЛАН, НАКИДАЮ LABEL, TEXTURERECT, ВОТ ЭТО ВСЁ @ А НЕ, ПОГОДИ, ЧЁТ СЛИШКОМ МНОГО ЛИШНИХ НОД @ ОЙ ВСЁ, ЩАС НАРИСУЮ ВСЁ МЕНЮ САМ В _DRAW @ АГА, РАЗОБРАЛСЯ, ВРОДЕ НЕСЛОЖНО ВРАЩАТЬ ЭТО @ В СМЫСЛЕ НЕ МОГУ ПРОСТО ЗАГНАТЬ ТЕКСТ В RECT2? @ ТАК-ТО ВРОДЕ НОРМ, НО НАСЛАИВАЕТСЯ СЛИШКОМ @ ОООООЙ ВСЁ, КАКАЯ-ТО ХРЕНЬ, ПОГУГЛЮ РЕФЕРЕНСЫ @ А ЧЁ, В СМЫСЛЕ, В БЛЕНДЕРЕ ПРЯМОУГОЛЬНЫЕ КНОПКИ? @ В НАТУРЕ! ТАК ЛУЧШЕ ПОЛУЧИТСЯ, ЧИТАБЕЛЬНО ЖЕ @ ДА И ШОРТКАТЫ У СТАНДАРТНЫХ КНОПОК ТОЖЕ ЕСТЬ @ ТАК-ТАК-ТАК, Я БЫЛ ПРАВ, ВОЗВРАЩАЕМСЯ К BUTTON @ АААААА, Я ЧТО, ЗРЯ КРАСИВУЮ ОБВОДОЧКУ ДЕЛОЛ? @ НУ ВСЁ, ЩАС БУДУ ВСЁ ПЕРЕДЕЛЫВАТЬ ЗАНОВО
>>953782 >>953786 По части форматинга кода годоту не помешал бы автоформаттер вроде автопипа из питона или гофмт из го. А то чисто в визуальном плане тут полную нех наворотить изи.
>>953823 >А что там в секторы засунуть - это мелочи. Не мелочи, это как раз база того, будет игрок им пользоваться или нет. Игроку похер как у тебя реализована тригонометрия внутри
Привет, Сосач. Подскажите, почему в Godot источники света кастующие тени так сильно сажают FPS? Что можно предпринять, чтобы избежать просадок и получить нормальную картинку?
>>953888 >>953879 Некоторое старое железо тоже ок фпс выдает по теням. Там ебанутая свистопляска какая-то, на одном древнем ноуте запускаю - 4 фпс, на другом, почти таком же древнем и хуевом - 40 фпс.
>>953879 Используй light/shadow blobs и запекай светотени как диды.
>>953903 > на одном древнем ноуте запускаю - 4 фпс, на другом, почти таком же древнем и хуевом - 40 фпс Ненене, давай спеки в студию. Древний древнему рознь. Для тебя они одинаковы, а на деле там в одном штеуд атом и штеуд графика, а на втором амд со встроенным радеоном. Вот и разница.
>>953879 >почему в Godot источники света кастующие тени так сильно сажают FPS? >Что можно предпринять, чтобы избежать просадок и получить нормальную картинку? Источники света и тени по умолчанию динамически обновляются каждый кадр, чтобы учитывать актуальное состояние сцены. Читай документацию - там всё подробно описано, как переключить источники света в статический режим. В большинстве случаев динамические источники света тебе не нужны, если ты просто размещаешь лампочку и не двигаешь её.
Источник света относительно дешёвый, а вот тень - это отдельный рендеринг почти всей видимой игроку сцены с позиции источника света, чтобы нарисовать силуэт объектов, который потом будет наложен на основную картинку как тень. Расчёт не точный, но можно прикинуть, что 1 источник света - это 1/2 от FPS без источников света, 3 источника света - это 1/4 от FPS без источников и т.д. Во-первых, избавляйся от лишних источников света, которые не играют роли, во-вторых, выключай рендеринг теней для источников света, которым тени не нужны, в-третьих, выключай отбрасывание теней у мелких объектов и прочего мусора, которым тени не нужны. Можно попробовать создать один невидимый большой объект (куб), который бросает одну огромную тень вместо тысячи мелких предметов - так рендеринг теней будет меньше нагружать видеокарту.
Также производительность зависит от качества теней. Если хочешь гладкие и чёткие тени, текстуру нужно увеличить, но падает производительность. Если хочешь быстро, уменьшаешь размер текстуры, но получаешь размытые артефакты. Если тебе нужно тени на большом расстоянии от камеры, тогда тебе нужна текстура теней большего размера или будут артефакты. Если у тебя только мелкие комнаты, ты можешь сократить расстояние и получишь красивые тени со сравнительно высокой производительностью.
Также некоторые эффекты учитывают источники света, об этом подробно в документации по этим эффектам написано, поиграв настройками можно добиться приемлемого качества с не слишком сильной потерей производительности. Или вообще убрать эффект, если он тебе не нужен в конкретном месте.
И не забудь добавить в настройки игры опции для качества теней и других эффектов. Лично я во всех играх стараюсь отключить тени или снизить их качество на минимум, потому что они всё равно мешают геймплею, делая картинку тёмной и грязной, порой скрывая важные объекты. Кому нравится - у того и компьютер мощнее, пусть ставит тени на "ультра", будешь разбираться только если на 4090 у тебя меньше 60 фпс.
>>953934 >В большинстве случаев динамические источники света тебе не нужны, если ты просто размещаешь лампочку и не двигаешь её. А что если вокруг этой лампочки движется игрок? Я хочу чтобы моделька игрока освещалась. Пусть без отбрасываемых теней.
>>953973 >А что если вокруг этой лампочки движется игрок? Там какая-то сложная система запекания... Я особо не разбирался в этом пока.
>Я хочу чтобы моделька игрока освещалась. Пусть без отбрасываемых теней. Тени (те, что падают от предмета на другие предметы) можно одной галочкой отключить без проблем. Запекание источников света имеет смысл, когда у тебя целая гирлянда разноцветных лампочек и нужно чтобы эти цветные пятна красиво отображались на окружающей гирлянду статичной геометрии. Или что-то в этом роде.
Ты лучше проверь, действительно ли проблема в источниках света или в чём-то другом.
>>953981 GLSL в машинный код видеокарты компилируется. Наверное, он прям этот машинный код и пишет под свою видеокарту, вручную, без GLSL. Зато игра не будет компилировать шейдеры. Оптимизации уровня ECS...
>>953957 >>954009 Это так не работает, братишка. Если бы мне были нужны спрайты для игры, я бы сразу спрайтщитами кочал с множества ресурсов, типа LPC-генератора. Вот например, беременная горгулья с лопатой (што?) сделано за 5 минут, пока пост писал. Полная раскадровка всех основных анимаций. И что мне твоя мазня по сравнению с генераторами? И сколько лет ты будешь мне раскадровку пилить? И сколько мозгов выебешь? А в генераторе перс уже готов.
От себя (я сам плох в этом, но всё же) рекомендую: 1. Ограничиваться только базовыми цветами, без оттенков и полутонов. Берёшь несколько контрастных цветов, которые легко отличить друг от друга, и рисуешь только ими. Сейчас у тебя всё сливается в пятна из-за недостаточной разницы между цветами. 2. Персонажей лучше всего делать с обводкой - чёрной или очень тёмной. Без обводки мелкопиксельный персонаж плохо читается даже как отдельный статичный спрайт, а в игре он легко может слиться с фоном, даже если ты подбирал цвета под конкретный тайлсет фона. Тайлсеты фона, наоборот, чаще без обводки, чтобы не бросаться в глаза, но обводка может подсвечивать интерактивные предметы, твёрдые поверхности и т.п. 3. Если делаешь спрайт для игры, то необходимо знать, в каком стиле будет игра: размер пикселей (никто не будет делать сегодня пиксельную игру 1:1, всегда пиксели умножают на какое-то число, и это число должно быть одним на всю игру), палитра (даже если нет одной палитры на всю игру, всё равно есть разница между кислотными, мрачными, серыми, пастельными и другими группами оттенков, это задаёт атмосферу игры), положение камеры (сверху, сбоку, 3/4), что персонажа чаще всего окружает (буйная тропическая зелень, городская серость, постапокалиптическая ржавчина и т.д.) и т.д. 4. Лучше тренироваться не на спрайтах, а на иллюстрациях. Чтобы не задумываться пока об анимации, спрайт-шитах и т.д. Набить руку на отдельных рисунках. 5. Знания и опыт в академическом художестве помогут в пиксель-арте, особенно если хочешь подняться над унылыми тяп-ляп 2D платформерами от школьников. 6. Изучи специальные инструменты. Да, рисовать пиксель-арт можно и в пейнте, но специальные редакторы сегодня имеют массу вспомогательных инструментов.
>А в генераторе перс уже готов. Ага, и он точно в таком же стиле, как и 99% игр на РПГ Мейкере, которые совершенно не отличаются друг от друга из-за одинаковых бесплатных тайлсетов и генераторов персонажей. Смешно смотреть на очередную инди-жРПГ в стиме, у которой скриншоты ничем не выделяются кроме аниме героини, которая тоже в стиле стандартного инди аниме и не выделяется на фоне остальных аниме героинь.
>>954028 >Того что надо никогда не будет. Придёт AGI - порядок наведёт. Будет делать игру с нуля до релиза за час на кофеварке. >Поэтому только 3D -> анимации -> рендеринг 2D Такие игры легко отличить от труЪЪЪ ручного пиксель-арта. ИМХО, лучше уж делать стилизованную 3D игру, чем пытаться попасть в и без того переполненную нишу пиксель-арта со своими кривыми 3D рендерами.
>>954033 >Ты с этим далеко не уедешь без хуйдожника 99% игр на РПГ Мейкере как-то справляются.
>>953997 Как закончу хотя бы квартиру. Я как-то выкладывал на реддит видео другой демки https://youtu.be/wpZODOlzOCg Это реворк демки одного нсфв художника. Реакция на реддит была в целом положительная, но пользы от этого было никакой. Даже художник не мотивировался вернуться к геймдеву, а жаль.
Выкладывал в r/godot, но я потом акк удалил. Вообще, поглащение и гиганты не мои фетиши, прст технически исполнил.
>>954080 >а ты уже смешарик Первую демку делал на версии 3.4, потом ничем не занимался аж до конца прошлого года. Там другую демку сделал по поням (тоже реворк чужой работы). Эта вот с квартирой - третья, первая полностью своя... на чужих ассетах, плагат популярной франшизы. Не густо.
А я нирикаменую пиксель арт как таковой. Это обман, наебка, ловушка. Он кажется обманчиво простым, но если делаешь что-то выше 12х12, то оно тебя сожрет. А потом сожрет второй раз, когда начнешь ебаться с пиксель-перфект в движке, с y-сортами и прочим геморроем. А уж анимировать его, ууу бля, сидишь как даун половину спрайта перерисовываешь, а потом понимаешь что он уехал не туда и слышь давай по-новой. Я уж лучше на primitive shapes and colors игры поделаю.
>>954086 >если делаешь что-то выше 12х12 Чем выше разрешение, тем ближе к обычному арту, а тут уже решает то, насколько ты хорош в обычном арте и его теоретической базе. Если знать теорию - у тебя будет меньше вопросов "что делать" и рисунки станут привлекательнее. Дальше всё сводится к механическому дрочу пикселей, в этом инструменты помогают. Теория - технические знания, бояться их не надо, но большинство новичков ленится читать и разбираться, потому и разочаровываются в себе - это как если бы начинающие программисты садились писать Hello World без чтения мануала по незнакомому им языку и потом плакали, что код - это не для них и больше они к нему не притронутся.
>анимировать его, ууу бля, сидишь как даун половину спрайта перерисовываешь, а потом понимаешь что он уехал не туда У тебя неправильный порядок работы. Ты сначала полностью детализировал один спрайт, а потом пытаешься кадр за кадром анимировать его, верно? На практике лучше наоборот: сначала сделать всю анимацию цветными кляксами, не заботясь о пикселях, и только когда анимация будет удовлетворять, наращивать на неё все необходимые детали вроде одежды, волос, лица, предметов, и т.д. Сначала делаешь свою супер-пупер анимацию удара ногой с разворота с подробной физикой прыгающих сисек, а потом уже натягиваешь на неё свою бимбу в микрокини. Тогда у тебя не будет "ой, чёт криво прыгают". Пикрилы в своё время открыли мне глаза на анимацию.
Метод move_and_slide() может давать ошибку instance_set_transform: Condition "!v.is_finite()" is true если я нигде не накосячил со скоростями? Как вообще пофиксить подобное без трай-кетчей если и так везде уже столько всяких проверок понатыкал, что вероятность того, что эта ошибка вылезает где-то кроме move_and_slide() стремится к нулю?
>>954131 Масло = дорого (особенно в пендостане, где нет ни молока, ни хуя) Т.е. он кичится своим богатством, которое приобрел за счет своих инди-игор. Получается, это такая ирония, мол, он говорит - ха-ха, мне так трудно быть гейдевом, что приходится жрать черную икру ложками (если адаптировать эту историю для граждан Российской Федерации).
>>954129 >instance_set_transform: Condition "!v.is_finite()" is true Ты забыл указать строчку кода в исходниках (она всегда указывается дебаггером при таких ошибках), так что придётся играть в форумного экстрасенса.
Нужно смотреть, какие значения у тебя в матрице мешей, которые закреплены за телом, которое ты пытаешься двигать. Если используешь MultiMeshInstance3D, то нужно смотреть, какие данные находятся в его буфере - там иногда могут быть ошибки, которые, похоже, пока не удалось исправить: https://github.com/godotengine/godot/issues/75485
>Как вообще пофиксить подобное Удалить меши и пересоздать их заново. Особенно если у тебя MultiMeshInstance3D.
>вероятность того, что эта ошибка вылезает где-то кроме move_and_slide() стремится к нулю С чего такая уверенность? Этот метод двигает физическое тело. Если подозреваешь, что проблема именно в нём, а не в графике, тогда удали все MeshInstance3D и оставь только CharacterBody3D с его CollisionShape3D. Включи отображение коллизий, чтобы видеть персонажа на экране без мешей, и тестируй.
>>954228 Не нравится мне его подход к чарактер контроллеру. Лучше абстрагировать инпут игрока от персонажа. Пикрил (не нашёл более подходящую картинку).
>>954235 >Ты забыл указать строчку кода в исходниках E 0:00:38:0649 instance_set_transform: Condition "!v.is_finite()" is true. <Исходный код C++>servers/rendering/renderer_scene_cull.cpp:922 @ instance_set_transform()
>С чего такая уверенность? >Суть проблемы: один из компонентов матрицы NaN или бесконечность, поэтому матрицу не удаётся применить. Ну мб я преувеличил. Я, по сути, почти совсем нюфаня. Я как раз делал везде где только можно проверки скоростей и величин, чтобы они были не нан и не бесконечность, и только после этого применял move_and_slide().
>а не в графике Я вообще не в курсе, что это тоже влияет
>удали все MeshInstance3D и оставь только CharacterBody3D с его CollisionShape3D Сделал. Та же хуйня.
>Нужно смотреть, какие значения у тебя в матрице мешей, которые закреплены за телом, которое ты пытаешься двигать. Подскажи, плс, как это сделать, и как это поможет
>Тупо обрисовка По его словам в комментариях, рисовал без этого: https://en.wikipedia.org/wiki/Rotoscoping Но даже если этой техникой, то какая разница? Главное, чтобы результат был хороший.
Дрочь на техники == дрочь на движкописание. Делайте игры на ассемблере, а то не труъ.
>>954254 ><Исходный код C++>servers/rendering/renderer_scene_cull.cpp:922 @ instance_set_transform() Да, это та самая строчка.
>>значения в матрице >как это сделать Либо через инспектор в сцене Remote в запущенном проекте, либо print(transform).
Попробуй сделать новую сцену со своим скриптом, чтобы там было минимум компонентов. Попробуй вырезать или закомментировать весь лишний код, который тебе не обязателен. В худшем случае просто сносишь вообще всё и начинаешь делать с нуля, но осознанно.
Алсо, мог бы хотя бы скриншот своего кода показать, скриншот дерева сцены и т.д.
Ты случайно не трогал масштаб CharacterBody? Сбрось его в исходное состояние.
>Ты случайно не трогал масштаб CharacterBody? Сбрось его в исходное состояние. Скейл, вроде, весь по 1
>Алсо, мог бы хотя бы скриншот своего кода показать, скриншот дерева сцены и т.д. Да я даже проект позже могу приложить, вот только надо разобраться с баном от двоща, лол (не ебу, какого хуя прилетел) Древо сцены - см. пик Код кидать смысла нет - там ща лютый говнокод, который надо разгребать. Я как раз находился в процессе, когда обнаружил баг.
Вообще, ситуация осложняется тем, что изначально код не мой. Основу кода и древо сцены делал другой чел, и он там где-то, в теории, мог накосячить - он еще больший ньюфаг, чем я
>>951925 (OP) У вас часто такое бывает, что редактируешь-редактируешь один скрипт (у него @tool и class_name), а когда пытаешься использовать его из другого скрипта, редактор почему-то не знает актуальное состояние скрипта и ругается на отсутствующие ошибки? Ничего не помогает, приходится перезагружать проект.
Пример: я объявил метод close() -> void, использовал его в другом скрипте, всё было нормально, а потом я решил, что мне нужно, чтоб этот метод возвращал какой-то результат. Я изменил скрипт, а потом попытался использовать возвращаемый результат - редактор ругается, что метод ничего не возвращает.
Нажимать "soft reload tool script" пробовал, не помогает. Также пробовал убирать метку @tool, это не влияет. Похожая проблема наблюдается при частом редактировании нескольких class_name скриптов (без @tool), редактор почему-то не может их вовремя обновить и выдаёт ошибки.
Проблема мелкая, но перезагружать весь редактор раздражает.
>>954264 Что тебе CollisionShape3D говорит? Жёлтый значок - предупреждение о каком-то косяке, как правило - твоём, кликни и прочитай. Если там сообщение с пикрила - сбрось ему масштаб. Встроенный физический движок непредсказуемо косячит с масштабированием.
>изначально код не мой >Основу кода и древо сцены делал еще больший ньюфаг, чем я Не рекомендую так делать, если ты пытаешься нахватать чужого кода и заставить его работать, толком не разбираясь в основах движка и скриптинга на нём. Лучше самостоятельно научиться с нуля, чтобы потом видеть ошибки в чужом коде/сценах, чем разбираться без опыта в чужом коде и научиться чужим ошибкам. Впрочем, во всяких туториалах и даже платных курсах часто учат говнокоду...
Алсо, рекомендую привыкать разделять сцену на отдельные самостоятельные сущности, которые сохраняются в отдельные tscn-файлы и затем используются в композиции других сцен: - Player - главный кандидат на такое выделение, он же должен забрать к себе Camera3D (исключение, если это камера локации, фиксированная на месте и следящая за игроком как ИРЛ камера). - Часто используемые звуки лучше сгруппировать в одну сцену, типа "плеер звуков", исключение - если это локальные звуки вроде открывания ящика (они принадлежат сцене ящика). - Препятствия разложить по отдельным сценам, особенно если они часто повторяются, вроде конусов на дороге, барьеров и т.д. Иначе задолбаешься расставлять/двигать их по сцене.
Тогда для тестирования Player было бы достаточно закинуть его на пустую площадку, уже с камерой и всем необходимым для его работы.
Анончики-шарписты, если в рандомные моменты я ловлю "The program '[35204] Godot_v4.2.2-stable_mono_win64.exe' has exited with code -1073741819 (0xc0000005).", то что я могу сделать? Ни указания на строку, ничего. Я конечно могу закомментить части кода, но я всё равно не узнаю, это ошибка ещё не выскочила, или действительно проблемный фрагмент закомментировал. Помогите пожалуйста...
>>954281 >0xc0000005 По-человечески это называется STATUS_ACCESS_VIOLATION.
>что я могу сделать? 1. Проверить, где ты в своём коде обращаешься туда, куда обращаться тебе запрещает ОС: скорее всего, ожидаемый тобой по ссылке объект был уже уничтожен, а ты пытаешься к нему обратиться - ОС запрещает это, чтобы программы не могли залезть в чужую память, и поэтому крашит без разбора всех, кто так делает.
2. Перейти на GDScript, на нём такого нет (дебаггер сразу указывает туда, где ты обратился куда не следует, вместо краша с ошибкой ОС, и чётко говорит, в чём проблема).
>>954302 > ошибка вылезает не в моей логике Если ты обнаружил баг движка, то можешь сделать новый проект, по шагам воспроизвести баг, убедиться, что ты обнаружил баг движка, и зарепортить на гитхаб ищью.
>>954302 >ошибка вылезает не в моей логике Если ты в этом так уверен, то иди на гитхаб и создавай issue. Желательно к описанию проблемы приложить минимальный проект, в котором гарантированно воспроизводится эта проблема. Там почитаешь, что нужно для правильного оформления (версия движка, версия ОС, что делал и т.д.).
Но я всё же думаю что проблема в твоём коде - что-то где-то некстати удаляешь.
Сам движок тут ничем не поможет, твой код (или ошибка в движке) приводит его в состояние, в котором ОС принудительно завершает процесс. Можно отследить, на каком конкретно этапе происходит остановка, если использовать внешний дебаггер, но он, наверное, будет выдавать кучу ассемблерных кодов, и ты в этом, скорее всего, ничего не разберёшь.
А, вот ещё. Если делаешь регулярные бекапы или заливаешь код в систему контроля версий, тогда попробуй открыть предыдущий бекап и проверь, есть ли там эта ошибка. Потом сравни, что ты успел налепить в коде до появления ошибки. Так сузишь область поиска проблемы. Мне пару раз помогало, когда я наговнокодил кучу всего и сам в этом запутался.
На будущее рекомендую тестировать проект после минимальных изменений. Чем меньше изменений между тестами, тем меньше мест, в которых придётся искать ошибку - чаще всего ошибка возникает из-за свежего кода.
>>954305 Я считаю более выгодным создавать абстрактного персонажа, который никем конкретным не управляется, но имеет состояния и переходы между ними, может ходить, бегать, прыгать и т.д. Создав такого персонажа, ты сможешь не только с клавиатуры его контролировать, но и через код, т.е. создать бота, который игромеханически будет равен игроку - в плане того, что он точно так же бегает, прыгает и делает все остальные действия.
Соответственно, тебе нужен скрипт, реагирующий на внешние команды, и отдельный скрипт, генерирующий эти команды от ввода с клавиатуры или от мозгов неигрового персонажа. Двух зайцев одним выстрелом, да? В туториалах об этом не говорят и чарактер контроллеры, которые я видел, прибиты гвоздями к вводу с клавиатуры...
>>954322 >косяк вылезает в месте, которое я не могу отследить Ещё раз, разбираемся: 1. Изначально твой проект был без ошибки (как минимум пустой). 2. Ты добавил код - он работал всё ещё без ошибки. 3. Ты добавил больше кода - начала выпадать ошибка. 4. Убрал добавленный код - ошибка перестала выпадать. 5. Изучаешь, что ты делаешь в коде, и понимаешь, откуда ошибка. Я в таких случаях стараюсь исполнить код в голове или в Блокноте.
>>954324 Понимаешь, проблема в том, что это > 3. Ты добавил больше кода - начала выпадать ошибка. Это смена библиотеки ECS, я знаю, что если я откачусь на версию до смены, то там этой ошибки не будет. У меня слишком много кода, чтобы выполнять его в голове и анализировать классическими методами. >>954327 Попробую, но надежды мало
>>954328 >Это смена библиотеки ECS, я знаю, что если я откачусь на версию до смены, то там этой ошибки не будет. Даже и не знаю, чем тебе помочь, если ты не можешь отказаться от багованной библиотеки, про которую ты уже знаешь, что она багованная. Попробуй написать разработчикам этой библиотеки.
>У меня слишком много кода, чтобы выполнять его в голове и анализировать классическими методами. Что значит "слишком много кода"? Ты огромную портянку лапши накидал что ли, что у тебя оперативной памяти мозга не хватает? Единственно верный подход к разработке софта - это разделять код на мелкие самостоятельные части, тестировать их по отдельности, затем тестировать композицию из уже протестированных частей и т.д. Берёшь маленький кусок кода, изучаешь его - что он делает, с чем работает, на что влияет, что возвращает. Если с ним всё в порядке, закрываешь его и больше не трогаешь. В чём проблема? Естественно, код нужно изначально писать в таком виде, но никогда не поздно произвести рефакторинг.
Вот чего я не пойму, ты ведь новичок? Судя по тому, что ты не знал про ошибку доступа, вряд ли у тебя богатый опыт программирования. Но ты взял C# (объективно сложнее GDScript, хуже поддержка движком, меньше туториалов и годотеров, способных помочь в контексте движка), в добавок взял ECS (объективно сложнее отлаживать, чем классическое ООП, а его главное преимущество играет роль только на очень большом количестве одинаковых компонентов - десятки тысяч), навалил кучу какого-то кода, который сам не можешь проанализировать (нейронкой генерировал?), а теперь бодаешься с ошибкой, которую не можешь понять. Зачем ставить себе столько палок в колёса? Ты игру хочешь сделать или что? Или у тебя какое-то задание, которое ты взял, не подумав о последствиях? Если ты сам для себя это делаешь, проще бросить проект и начать с нуля, чем распутывать клубок неудачного кода, в котором ты сам не разбираешься. Всё равно большинство инди-проектов так и остаются недоделанными - это факт.
>>954344 > Попробуй написать разработчикам этой библиотеки. Я перешёл на более популярную библиотеку. Думаю она стабильнее. > Вот чего я не пойму, ты ведь новичок? > Судя по тому, что ты не знал про ошибку доступа, > вряд ли у тебя богатый опыт программирования > который сам не можешь проанализировать (нейронкой генерировал?) > которую не можешь понять. > Извини, если что, не хочу обидеть. Не буду тратить время на расписывание, что я не дурак. Складывается впечатление что ты хочешь самоутвердиться за мой счёт. Вместо того, чтобы просто сказать "Анон, я не знаю метода как отловить ошибку доступа" ты начал предлагать мне сменить язык, принцип разработки и начал учить что такое ошибка доступа.
И так, ноды крутятся - кликер мутится. В целом основа сделана, самое сложное было понять как лучше сделать юай и скомбенировать его с игровым полем, т.к яндекс хуй пропустит игру если она не все поле окна занимает пришлось много думать чтоб что то получилось адекватное ибо саму игру рендерит 3д камера, а опыта в 3д до этого вообще небыло. Пришел крч к тому что сплитнул экран на две части, на одной юай, на другой вьюпортконтейнер, вроде неплохо выглядит, и ресайзится нормально. Сам юай и худ полностью готовы, базовые улучшения готовы, осталось только зарескинить на что то более приятное, а так же прикрутить звуки и под конец сам яндекс. В целом опыт с кликером достаточно приятный, да и вообще когда твой шизоидный высер из головы становится похожим на игру это плюс мораль и мотивация всегда. В планах пока что только отдохнуть ибо хуярил чтоб не спиздеть часов 20 подряд. А потом напиздить ассетов гуи. Такие вот дела. А ты чем щас занять анон?
>>954346 >Думаю она стабильнее. Но у тебя ошибка доступа, которую ты не можешь отловить. После смены библиотеки на "стабильную". В проекте, где у тебя уже куча кода, в котором ты не можешь просто так взять и разобраться. Сам себе приключение устроил. >что я не дурак Я не говорю, что ты дурак, но, судя по постам, ты допускаешь ошибки новичка, и я заранее предупреждаю об этом. >Анон, я не знаю метода как отловить ошибку доступа Я знаю, как её отловить, и уже писал - берёшь отладчик и смотришь, на какой инструкции процессора Godot крашится. Только это вряд ли чем-то может помочь, если ты не разбираешься в низкоуровневой отладке. Если у тебя стоит подходящий отладчик, Windows сама должна предложить открыть процесс в отладчике. >начал предлагать мне сменить язык, принцип разработки Потому что в GDScript реально легче работать. Если ты на C# с ECS только ради производительности, то это преждевременная оптимизация. Тем более что API Godot само по себе медленное, так что у тебя получается бутылочное горлышко между Godot и твоей библиотекой. Там много нюансов. На GDScript можно быстро сделать игру, а потом уже думать, что и зачем переносить на более производительный язык или в ECS. Да, сделать в первый раз всегда сложнее и дольше, чем перенести готовое куда-либо. Да и в целом, GDScript более чем достаточно для большинства задач, а код пишется легко и гибко. К табам и отступам привыкаешь очень быстро.
У тебя Microsoft Visual Studio Debugger есть? По идее, он должен помочь с поиском проблемного места.
>>954352 >>954353 Я разобрался без дебаггера. Оказалось - библиотека и ЕКС в принципе не виноваты. Какой-то подлец залил мне диверсию прямо в костыльный второй контроллер инпута. Вот что бывает когда спешишь делать что интересно, а не как по уму.
>>954397 >Какой-то подлец залил мне диверсию Это самоирония? Или проект на гитхабе? Или код - копипаста?
>спешишь делать что интересно Что интересного в InputEvent.Unreference()?
Насколько я понимаю, InputEvent нельзя уничтожать, потому что он последовательно проходит по всему дереву. Т.е. уничтожив этот объект в одном месте ты вызываешь ошибку доступа где-то дальше по дереву, где его кто-то ждёт. Хотя как это к C# относится - не знаю, разве в C# принято удалять объекты вручную? Кажется, там GC автоматически всё удаляет.
>>954397 https://docs.godotengine.org/en/stable/classes/class_refcounted.html#class-refcounted-method-unreference >bool unreference ( ) >Decrements the internal reference counter. Use this only if you really know what you are doing. >Returns true if the object should be freed after the decrement, false otherwise. Т.е. получается, что ты уменьшил счётчик ссылок, и это вызвало преждевременное удаление объекта. По-прежнему непонятно, зачем это нужно было делать в данном конкретном случае. Возможно, эту функцию нужно использовать для разрешения циклических зависимостей, когда A и B ссылаются друг на друга и поэтому не могут быть освобождены штатным путём (читал что-то об этом в документации).
>>954410 > самоирония Это > Что интересного в InputEvent.Unreference() > Decrements the internal reference counter. Use this only if you really know what you are doing. Оказалось я не знал что тогда делал. Думаю что я тогда хотел сделать так, чтобы если в одном инпуте обработал ивент, то больше его никто не мог использовать > рад за тебя Спасибо
>>954344 >ECS >главное преимущество играет роль только на очень большом количестве одинаковых компонентов - десятки тысяч Я от про слышал, что ECS в гейдеве - это единственно правильное и оптимальное решение.
Изи в рефакторинге, изи в масштабировании и реюзабельности. Да и много логичней остальных подходов.
Я только мечтаю вкатиться в геймдев и многого не знаю еще. Но просто пока искал информацию о разных подходах, то нашел, что TCS - самый топ номер 1.
>>954530 >нашел, что ECS - самый топ номер 1 Некоторые шизы будут тебе и про функциональные языки точно так же говорить, мол, иммутабельность - топ номер 1, всё должно состоять из функций, игра - это тоже одна иммутабельная функция, типа вызываешь game() и получаешь игру, если захотел нажать кнопку - выбросил старую игру и вычислил новую игру с нажатой кнопкой, и т.д. Это прекрасно работает в идеальном мире, но мы живём в реальности, а не в фантазии функциональщиков. Ты можешь, конечно, использовать .all(), .any(), .filter(), .map() и прочие полезные функции, популярные в функциональщине, но всю игру на одном этом не построишь.
>Изи в рефакторинге, изи в масштабировании и реюзабельности При условии, что ты мыслишь в стиле ECS.
Допустим, ты хочешь, чтобы твой персонаж прыгал. Ты создаёшь систему "прыганье" и компонент "прыгатель". Добавляешь этот компонент к любой сущности, которая должна уметь прыгать. Эта система получит список всех сущностей с этим компонентом и будет их "прыгать" по мере необходимости.
В чём преимущество? Допустим, у тебя 100 тысяч прыгателей. Если ты пользуешься классическим ООП, в теории процессор будет метаться по разным участкам памяти, по отдельности прыгая каждого прыгателя, и так 100 тысяч раз. Если ты обмазал код ECS, тогда в теории процессор загрузит в свой кэш все компоненты "прыгатель" одним массивом и быстро пройдётся по этому массиву кодом из "прыганья", не обращаясь к чипам оперативной памяти, потому что все данные у него уже есть в кэше (обращение к RAM - долго, именно поэтому придумали кэш и с каждым годом его увеличивают в процессорах).
На практике хрен знает что будет, процессор не только с твоей игрой работает (игра - только гость в ОС, которая всем управляет), и вообще там все эти оптимизации сложнее, чем в фантазии геймдевелоперов. Часть оптимизаций оказались уязвимы к вирусам... Но наверняка придумают что-то ещё. Короче, не всё так однозначно в процессорах.
Зато тебе, как разработчику игры, приходится разделять код на тысячи якобы (по заявлениям любителей ECS) ничем не связанных сущностей ("прыгатель", "ходитель", "предметособиратель", "стрелятель", "умиратель", "подлечатель", "подмыватель", "пенетратель", "оратель" и прочее), которые в реальности очень тесно друг с другом связаны и ты не можешь думать о них по отдельности - ты думаешь об игроке, который бегает, прыгает, стреляет, умирает и орёт, а не о кучке полностью независимых систем и компонентов. Мышление человека - основа ООП, а не наоборот, человеку намного проще думать о цельных объектах, чем о кучке ничем не связанных компонентов и систем. А комбинировать компоненты можно и на ООП, никто тебя не заставляет пользоваться наследованием (на которое обычно ругаются, аргументируя в пользу ECS) - пользуйся преимущественно композицией и агрегацией, получишь точно такую же гибкость архитектуры проекта, что и в ECS, но зато объекты будут как в твоих мыслях.
Короче, ИМХО, ООП намного лучше подходит геймдеву, и страдает только в случае если тебе нужно сто тыщ юнитов с одним и тем же кодом, что бывает крайне редко и не факт что вообще получится. Древние стратегии в реальном времени создавали и без модного ECS на медленных процессорах с крайне ограниченным кэшем. Godot, между прочим, имеет под капотом множество оптимизаций по кэшу процессора в системах, где это действительно необходимо (эти системы тут называются "серверы"). Если тебе нужно оптимизировать сто тыщ сущностей по кэшу - ты берёшь и пишешь собственный модуль движка на C++, выставляешь API и дёргаешь по необходимости из GDScript. Да и вообще, Godot не то чтобы самый эффективный, пытаться максимально оптимизировать проект на нём - это как ставить двигатель от реактивного истребителя на Запорожец - технически возможно, но результат вряд ли обрадует. Обещают сфокусироваться на оптимизациях движка, начиная с версии 4.4, тогда как версия 4.3 только вышла в бету. Однако, для освоения базы геймдева Godot сегодня подходит лучше всех, ты просто качаешь движок, создаёшь проект и начинаешь играть в разработчика игр в своё удовольствие, развлечение гарантировано на сотни часов. Можно забыть обо всяких Скретчах, Гейм Мейкерах и т.д.
>>954583 >Но я не соображаю вообще о чем речь идет, а ты меня грузишь. >Я только пытаюсь вкатиться в игродевелопмент. Англюсик знаешь ведь? Хорошо. Иди поиграй в это - онлайн, без смс и регистрации: https://www.gdquest.com/news/2022/12/learn-gdscript-app/ >Our app is designed to be accessible to people with no programming experience. It provides a step-by-step guide to learning GDScript, starting with the absolute basics and gradually introducing more concepts.
О всяких ECS пока не думай вообще, начинай с самых основ (переменная, цикл, функция и т.д.).
>>954579 База, но нужно не забывать упоминать, что ECS придумали для анчартеда на третьей плойке, в рамках оптимизации под трёшкоплойковский массив сопроцессоров. Там этот ECS давал просраться остальным игорам и выжимал из плойки весь потанцевал.
Вот мы с аноном в прошлом треде обсуждали утиную типизацию. И вот я тут подумал, что в Годоте при помощи групп и утиной типизации можно запилить аналог ЕЦС, без необходимости тащить сторонние компоненты. Есть метод get_tree().call_group("группа", "метод"). Он вызывает метод из аргумента для всех нод, состоящих в группе и присутствующих в дереве. Ноды могут состоять в любом количестве групп, вплоть до того, что ноды в течение игры могут исключаться из групп и включаться снова. Чем это не ЕЦС? Это больше чем ЕЦС. В группе могут быть непосредственные ноды-"делатели", а могут быть ноды-компоненты, прикреплённые к целевой ноде, и манипулирующие ею. В результате всё равно собирается массив и обрабатывается как в ЕЦС. Надо будет потестировать этот вариант.
>>951925 (OP) КОТОРЫЙ РАЗ СЛУЧАЙНЫМ КЛИКОМ ПО [ Х ] ЗАКРЫЛ В Е С Ь ПРОЕКТ @ ВСПОМНИЛ, ЧТО ВРОДЕ БЫЛА КАКАЯ-ТО ОПЦИЯ В НАСТРОЙКАХ @ ПОИСКАЛ @ НЕ НАШЁЛ @ ПОГУГЛИЛ @ >This seems a neverending wheel. Some people requested confirm quit, so it was added, then people said modern apps do not have this, so this was removed, and now people ask for confirm quit again...
>>954639 >Есть метод get_tree().call_group("группа", "метод"). Есть пара проблем: https://docs.godotengine.org/en/stable/classes/class_scenetree.html#method-descriptions >Calls method on each member of the given group. You can pass arguments to method by specifying them at the end of the method call. If a node doesn't have the given method or the argument list does not match (either in count or in types), it will be skipped. Т.е. ты должен реализовать этот метод везде, где хочешь его вызвать (это не метод вызывающей ноды, а метод вызываемой ноды, иначе этот аргумент был бы Callable, а не StringName). Не проблема, если в группе состоят дубликаты одной и той же сцены/ноды, но ты не можешь просто добавить рандомную ноду в группу, не реализовав в её скрипте соответствующий этой группе метод. Точнее можешь, но тогда попытка вызывать метод пропустит эту рандомную ноду без подходящего метода. >Note: call_group will call methods immediately on all members at once, which can cause stuttering if an expensive method is called on lots of members. Т.е. метод выполняется у всех нод в группе, и ты не можешь как-то легко взять и разделить этот процесс на несколько потоков или шагов (не создавая новые группы для каждого потока/шага). Нормально, если нужно всего лишь поставить галочку на сотне нод, но десятки тысяч ты так не обработаешь за один кадр. Впрочем, наверное, можно реализовать параллелизм, если забраться в исходники движка... но это может вызвать проблемы с методами, которые обращаются к каким-то внешним данным.
>Ноды могут состоять в любом количестве групп, вплоть до того, что ноды в течение игры могут исключаться из групп и включаться снова. Чем это не ЕЦС? Это больше чем ЕЦС. Группы - это всего лишь теги. Аналог компонентов из ECS - это метаданные: https://docs.godotengine.org/en/stable/classes/class_object.html#class-object-method-set-meta >Adds or changes the entry name inside the object's metadata. The metadata value can be any Variant, although some types cannot be serialized correctly. Потому что компоненты хранят в себе какие-то данные, а не просто тег. Система проходит не по массиву тегов, а по массиву конкретных данных, которые, по идее, должны всем массивом загружаться в кэш процессора.
Т.е. бесполезно вызывать метод на нодах. Пример системы в ECS: >for entry in data_array: entry.x += 1 Этот код загрузился в процессор, процессор увидел "data_array" и скачал весь массив из RAM, пробежался по этому массиву, добавляя +1 для поля x в каждом компоненте, а в конце вернул изменённый массив в RAM. При этом массив должен состоять только из данных, без ссылок (pointer), иначе весь профит теряется при попытке процессора перейти по ссылке, которая указывает в рандомное место в RAM. Конечно, современные процессоры пытаются предугадать переходы по ссылкам и запросить данные заранее, но уязвимости в этом алгоритме вроде как заставили отключить эту фичу (или другую похожую... не помню).
Собственно, без этой фичи (загрузка данных одним блоком) смысла и преимуществ у ECS нет.
Т.е. если ты делаешь так: >for object in object_array: object.x += 1 # переход по ссылке object в поисках x в RAM Или, тем более, так: >for object in object_array: object.do_work() # переход по ссылке object в поисках do_work() Это не ECS и преимуществ у этого никаких нет.
>>954673 Я не могу понять в какой момент ECS от примитивных данных на стеке (интов, флотов) переходит к сложным данным в куче (стрингов, мешей)? Когда мне рассказывают про ECS то как и ты в этом посте приводят пример как проц пробегает по массиву, состоящему из структа с интами, я полагаю из твоего же кода, но игра это же не структы с интами, и ты не сможешь избегать указателей всё время.
Считается что системы уменьшают промахи кеша процессора, типа за раз обходится массив компонентов вызывая один и тот же код системы. А сам компоненты уже плоские структуры данных без методов
>>954675 >переходит к сложным данным в куче (стрингов, мешей) >но игра это же не структы с интами, и ты не сможешь избегать указателей всё время. Вот-вот, и я о том же. ECS только в фантазии даёт твоей игре буст в 100500% скорости по сравнению с "постоянно прыгающим по ссылкам" ООП, а на практике ощутимая разница будет только в узком круге задач, и то не факт.
Зато проблемы архитектуры проекта вылезут, как только начнёшь делать что-то сложнее Hello World, потому что запутаешься в куче неявных связей между "никак (явно) не связанными" компонентами и системами.
Тут где-то был тред Katabasis - по-моему, ОП там признался, что пожалел о своём выборе ECS (на Unity).
>>954678 >>954677 Это очень интересно, но вопрос остаётся в силе. В какой момент пробегание по массиву примитивных данных в кеше процессора превращается в игру на экране? Со звуком, модельками, анимациями, геймплеем. От меня эта магия ускользает.
>>954680 Это надо гуглить насколько оправданы такие выводы. Если бенчмарки. С другой стороны основная фича ECS это замена наследования композицией. Чтобы каждая игровая сущность могла происвольную функциональность иметь.
Эта функциональность разбивается на компоненты. Каждая сущность связывается со своим набором компонент.
И тут представление копонент в виде плоских данных сильно упрощает разработку логики.
Если ты знаком с концепцией стейта, которая в вебразработке используется, например для библиотеки Redux или Vuex - должно быть понятно. Это что то похожее Набор компонентов - это стейт сущностей. Системы переводят стейт из одного состояния в другое в функциональном стиле.
Для плюсов например максимально прозрачно это делается в популярной библиотеке EnTT
>>>>954685 > С другой стороны основная фича ECS это замена наследования композицией. Не проблема для годота. К любой ноде можно прикрепить любую ноду, составив тем самым композицию. При этом, основной набор нод основан на наследовании. В итоге движок нас никак не ограничивает. Хочешь наследование - наследуйся. Хочешь композицию, цепляй ноды-компоненты к чарактербоди.
Но я не могу понять другое, как там от примитивных данных на стеке переходят к прогрузке ресурсов в игру, которые как ни крути, в стек не влезут?