>>1063674 По этому случаю, тем кто не знает сообщаю. На канале Godot Engine проводятся стримы Godot Tomorrow https://www.youtube.com/@GodotEngineOfficial/streams на которых довольно приятный Эмилио лампово рассказывает о нововведениях и отвечает на вопросы из чата, так что посещайте
Я думал что смогу упростить разработку нейронками, просто сгенерить модель и довести до ума в блендере. А я по итогу этот блендер уже видеть не могу, как же от него тошно
>>1063773 Пытаться лбом пробить стену тупая затея. Обмануть работу мозга не получится. За любой работой стоит беграунд опыта. Хочешь меньше тратить усилий на моделинг? Набей руку в этом.
>>1063773 Пересилил себя снова открыть редактор. Почти закончил ретопологию, теперь нуно скачать какую-нибудь халявную голову. Как же блять этим заниматься.
>>1063860 Судя по модельке, в которой полигонов больше чем во всей моей игре, которой понадобится скелет, куча сложных анимаций и дохуя какой контроллер - ты уже порвал штаны, братан. Снижай скоп раз в 10.
>>1063879 Пробовал. И отдельным софтом и плагином для блендера. Возни получается не меньше, а то и больше, в нейронке я хотя бы просто промт вбиваю и жду подходящий результат без ебли с ползунками для каждой титьки.
>>1063895 Чем выше детализация, тем сложнее делать. Он там голову отлепить-прилепить не может, и, скорее всего, с 3д вообще не работал, но сразу йоба-графон хочет на нейросетях.
Надо здраво оценивать уровень своих скиллов и начинать с посильного.
Окей, сделал лоуполи голову. Так же сгенерил референсы через нейронку, затем по этим референсам сгенерировал хайполи модель, вокруг которой уже строил лоуполь. В итоге основа персонажа готова. Каждый раз как сюда поныть захожу нет-нет, да что-то сделаю. Надо чаще тут ныть.
>>1063933 > сгенерил референсы через нейронку, затем по этим референсам сгенерировал хайполи модель, вокруг которой уже строил лоуполь Вот против этого я и возражал всю дорогу, пока ты приходил ныть. В мейкхумане автоматически искаропки подставляется тебе лоуполи моделька, когда тебе надо выгрузить. Затем просто в блендере доделываешь особые приметы. А с появлением блендер-адона (ссылка выше) и вовсе переезжать не надо. Сразу в блендере генеришь модельку. Нужно просто день посидеть разобраться, вместо того чтобы ебаться с нейронкой, выгадывая бесплатные токены, а то и приплачивая. Признайся, проплатил премиум, а, а?
>>1063946 Чем быстрее эти вкатунцы нажрутся говна, тем быстрее ИИ пузырь лопнет и перестав окупаться. Эти гандоны уже и так память накрутили в 8-10 раз, даже старые плашки, которые на вряд ли используют, hdd стоит как SSD ппц.
Так что все норм, пусть говно страдает. Мне потребовалось меньше дня с перебором, чтобы понять, насколько это в реале кал (правда в другой области).
>>1063967 >перестав окупаться Так там и нет окупания, каждая генИИ компания пока просто сжигает деньги инвесторов. Но нет, как бы оно не лопалось, оно здесь, с нами, навсегда, и надо приспосабливать свой воркфлоу чтобы не отстать. Я например активно перевожу свою игру на годоте с помощью ИИ. Даже откопал старую ММО, в которую когда-то гонял, и зашел спросить у еще живых испанских и португальских гильданов, насколько им перевод - сказали заебись, как нативно.
Указывать тег "ИИ" в стиме я, конечно же, не буду.
>>1063946 Какие бесплатные токены, о чем речь? Все генерится из коробки в ComfyUI на видюхе с пк который собрал в сентябре. Вся сборка 80к из которых видюха 20. Да, не 4к генерация, но 1024х1024+ тянет. Короткие видосики в малом разрешении на случай необходимости анимировать спрайт, даже с прозрачным фоном, какая-никакая музыка, надомная или на основе понравившегося тебе автора с CC0 лицензией.
Пробема с MH в том что я опять вынужден работать с художкой, от которой уже тошно. А с нейронками я превращаю прцоесс в конвейер автоматических действий.
>>1063997 > пк который собрал в сентябре Эх, а у меня не было денег на пк в сентябре. А щас и подавно нет. И в ближайшие годы не будет. Буду пилить тривряды и тетрисы на годоте, потому что зион-комплект и ПЕЧ 1060
Кто тут топит за MH, заебень мне персонажа как на пикрил. Не один в один модель, а базовую чиби которую нужно будет просто оденть. И я уверую и буду тунелить MH. Не понтов ради, сейчас серьезный вопрос во что вкладывать больше времени. Нейронки пока выигрывают.
Растапырил таки руки в Т-позу, вроде получилось окей. Закинул модельку в миксамочтобы прочекать как пойдет анимация. Думаю, результат приемлемый, смысла задрачивать модель еще больше нету, все равно не художник. Нашел модельку электро колхозника на скетчфабе, повезло. Модель курьерского рюкзака заделать будет несложно. Почистил лишнюю топологию и у него все равно 20к треугольников. Скорее всего тупо из-за колес, нужно подумать как сделать зубастый протектор менее полигональным.
Теперь надо думать как текстурить персонажа. Гляну решения от нейронки.
>>1064217 Прикольно вышло. Моя первая тня была хуже
>Теперь надо думать как текстурить персонажа. Гляну решения от нейронки. Ненад. Хуйня выйдет. Покрась сам в сабстенсе. Там никаких специфичных кистей или текстур нихуя не надо. АО, градиенты, генераторы и ручная правка. За 20 минут сделаешь.
> Где почитать-посмотреть, как делать скайбокс как на пикриле В гугле. > (смена дня и ночи, звезды, движение луны и солнца)? godot dynamic skybox with day and night, sun, moon, stars
В общем, хочу тик менеджер времени. Подобный как у игр параходов или римволд (1,2,3 скорость игры).
Идея в том что один тик - один _physics_process(). Но проблема, что при ускорении времени в 3раза, все решения предлагают прогнать tick три раза в _physics_process (в цикле). Что как бы зло и вроде как просрет всю физику (три вычисления за вызов _physics_process).
У меня вопрос, а что если сделать чтобы ускорение х3 было базовой скоростью в игре (1 tick == _physics_process), а при включение скорости 1х ты просто меняешь Engine.time_scele = 1 / 3 (соответственно тик для логики вызываешь 1 раз из 3)?
Насколько это вообще нормально сделать тик систему основываясь на замедлении Engine.time_scele?
>>1064349 >Насколько это вообще нормально сделать тик систему основываясь на замедлении Engine.time_scele? Обычный подход. У меня используется для фриз-фреймов при ударе. Time Scale это не что-то обскурное, в демках и туториалах я его регулярно встречал.
>при ускорении времени в 3раза, все решения предлагают прогнать tick три раза в _physics_process (в цикле) >(в цикле) Вот этот твой маневр я не понял. Ты хочешь сам, циклом, повторять physics_process? Чтобы что?
>>1064368 >Вот этот твой маневр я не понял. Ты хочешь сам, циклом, повторять physics_process? Чтобы что?
Нет, там реализуют так:1 тик на 1 physics_process вызов (чтобы потом делать некоторые вызовы при 250 и 2500 тиках - так в римке), но во время ускорения, например в 3 раза, они дергают tick три раза в одном вызове physics_process. Это советуют как ИИшки все, так и не которые пасты в инете. Но у меня прям душа не лежала.
В общем, я адаптировал тики совместно с Engine.time_scele и вроде все норм. Получилось даже проще.
>>1064371 > но во время ускорения, например в 3 раза, они дергают tick три раза в одном вызове physics_process Не улавливаю зачем. Римворлд на юнити, возможно какие-то её особенности.
>>1064368 >обскурное Просто я засомневался, тут реализация в том что большая часть геймплея будет на 1/2 и 1/3 скорости. Но так как это просто множитель дельты, то думаю ничего страшного.
>Не улавливаю зачем. Римворлд на юнити, возможно какие-то её особенности. Чтобы ускорить игру в 3 три раза, это обычное ускорение времени. Менеджер тиков нужен чтобы распределять нагрузку, чтобы сложные расчеты дергать реже (проблема начинается для одного тика во время ускорения).
В доке пишут, если ты ускоряешь через Engine.time_scele, нужно ускорить и physics_ticks_per_second. Возможно по производительности это выйдет даже хуже, чем просто кастомный цикл в дергать в _physics_process, но мне лень тестить, мне нужно было только замедление (сверх ускорение только для дебага).
>>1064375 >Просто я засомневался, тут реализация в том что большая часть геймплея будет на 1/2 и 1/3 скорости. Хотя я забыл про звук. Не зря засомневался.
Input.is_action_pressed Input.is_action_pressed Input.is_action_pressed Input.is_action_pressed Input.is_action_pressed Та еще мина замедленного действия. Зло во плоти.
>>1064629 Шарпиком не пользуюсь, нахуй нужен, просто имею релизнутые игры, которые надо поддерживать, плюс допиливаю еще одну большую, которую начал еще при 3.3 и поленился обновлять до 4.х.
Прекрасен будет день, когда получится взяться за новый проект на 4.х. Хотя кто знает, вдруг и 5.х успеют к тому моменту.
>>1064638 Это для художников, которые не могут в программирование. Так же как я генерирую модели и арты, так как не могу в художку.
Только когда художнику разрабатывают системы чтобы обходиться без программистов, это прекрасно и заебись, а когда программистам разрабатывают системы, чтобы обходиться без художников, это фу хуисос так нельзя и вообще воровство чужой работы на которых художники могли бы заработать.
>>1064654 >Это для художников, которые не могут в программирование Что бы не мочь в программирование нужны быть лоботомизированым не меньше, а вот >так как не могу в художку Проблема распространенная, вот вас и говнят
Что я понял о годот: сообщество годот - такое же токсичное сообщество недочеловеков которые срут друг на друга. Чего я не понял о годот: почему его сообщество на серьезных щах себя считает более дужелюбным, когда это такое же сборище выродков как и везде, а то и хуже.
>>1064713 Это в первую очередь для игроков с айсикью больше ста. Вот в чем главная проблема..
Изменить координаты UV сетки на одном меше
Аноним13/12/25 Суб 18:37:20№106472995
Всем привет. У меня в блендере есть одна и та же модель с одинаковым материалом, но с разным координатами UV сетки. Я как то могу в самом годоте задавать UV координаты для модели чтоб не засорять сцену мешами, а закинуть один и в скрепте изменять ему координаты? Может есть видео с объяснениями или такого нельзя сделать в годот? Я просто новичё и не совсем понимаю. А забив в поисковик гуг, он меня отпраляет в блендр или иной 3д редактор
В общем gdscript позволил закрыть все задачи, чутка были затыки, есть претензии немножо, но в целом всё хорошо. Самое бесячее - не совместимость PackedStringArray и Array[String] несмотря на то, что у Array есть конструктор такой var t: PackedStringArray = ["1","2","3"] var tt: Array[String] = t причём это райнтайм проверка. На второй строке будет > Trying to assign a value of type "PackedStringArray" to a variable of type "Array[String]".
Вкатываюсь в годотю, возник вопрос - как лучше отделять плеер контроллер от персонажа игрока: 1. PlayerInput как часть сцены Character (т.е., по сути компонент, который управляет персонажем). Вероятно, это нарушает принцип "signal up, call down" и плеер контроллер начинает знать о деталях имплементации родителя, что пахнет говной. 2. PlayerController как родитель над Character, который получает ссылку на Character и, соответствует, двигает персонажа как ему заблагорассудится через вызов публичных методов. 3. Забить и делать всё в одной сцене - и инпут, и всё остальное по персонажу.
>>1064903 Зачем что? Зачем на gdscript?! - Просто так. Заодно посмотреть позволяет ли он решать такие задачи + напороться на разные грабли, например что Vector2i держит int32 и ничего не говорит о потере данных. Зачем решать в принципе - чтобы стать лучше и это интересно, многие задачи так или иначе пересекаются с играми.
CharacterBody2D - главный скрипт ---Node - скрипты с импутами ---Node - скрипты с чем нибудь еще ---Node - скрипты с чем нибудь еще ---Node - скрипты с чем нибудь еще ---CollisionShape2D ---Sprite2D ---Еще ноды, много нод ------Ноды в нодах ---------Ноды в нодах в нодах
---Нода где хранятся ноды со скриптами!!! ------Node - скрипты ------Node - скрипты ------Node - еще одна "папка" c нодам, да что же он творит, остановите его!!! ------------Node - скрипты ------------Node - скрипты
Сделал на годоте подобие ренпай, так как не хотел нбаться с лицензиями. Ебало мое представили когда руками для трех локалей и структурой: основной скрипт + 4 концовки заполнял? Нет? А я вот да
Если достаточно востребовано будет: могу урезать проект без своих шейдеров и чистый билдер в безвозмездное пользование дать. Только вот зачем.
>>1064921 Основная проблема: ЕБУЧИЕ МАТРЕШКИ Да, визуально можно сделать и структуру с поинтами на концовки и вторую структуру с конкретными выборами, которые собирают финальный рут. Но изначально я думал что визуально будет проще собирать. А эта вложенность. Я её маму ебал
>>1064910 >Зачем что? Зачем мериться письками? Ну типа в промышленном программирование надо чтобы кабанчик выбрал самую красивую на конкурсе красоты олимпиаде. А тут ради чего? Мы пишем игры для себя.
> Заодно посмотреть позволяет ли он решать такие задачи Язык полный по Тьюрингу - может.
>например что Vector2i держит int32 и ничего не говорит о потере данных. Какие потери? Там между векторами нет преобразования, или зачем тогда я писал "обрезатель" без округления (пик)
>Зачем решать в принципе - чтобы стать лучше Чел, если навык не поддерживать он рассосется в голове, ты свой код через год откроешь (да какой год, месяц) - там будет как-будто другой человек писал. Это как с мышцами, они атрофируются. В геймдеве не надо продавать себя кабанчикам, просто делай игры.
>>1064910 >>1064925 А то что int в скриптах 64бит, а многое апи работает с 32бит? Это да, это ппц не только в векторе есть. Чувствуется рука питономакак.
>>1064921 > подобие ренпай >так как не хотел нбаться с лицензиями ??? Ты маладца что сделал, конечно, но ренпай - свободный и опенсорный софт, как и годот под МИТ лицензией.
>>1064926 Еще один повод читать документацию, а не бегло юзать код, ожидая одинаковое поведение.
Но я согласен, это просчёт и надо помнить. Как например что randi() возвращает unsigned int, а FastNoiseLite работает только в диапазоне signed int и в доках об этом нет инфы (забавно видеть как рисунки не совпадают но в целом все работает).
>>1064937 Какой аддон? Все руками на чистом гдскрипт
>>1064929 Был соблазн накачать всяких ассетиков и готовых решений, а ебаться с лицензиями не хотелось. Плюс остальные игры тоже на годоте. Решил сделать билдер и заодно некоторые наработки потом переиспользовать
>>1064925 >Зачем мериться письками? На AoC ты мереешься писькой только с собой, с этого года так точно, т.к. убрали таблицу лидеров, т.к. в прошлом году вот те самые меретели писькой писали автоскрипт скармливания задания АИ говну
>А тут ради чего? Я сказал уже, чтобы стать лучше, но это не поймёшь пока сам не попробуешь.
>Язык полный по Тьюрингу - может. Это не про тьюринговость, например заданного стека среды выполнения gdscriipt могло не хватать для решения с рекурсией, в общем если память не изменяет я видел ошибку что превышена рекурсия в 1000 раз, но то был мой косяк
>Какие потери? Там между векторами нет преобразования, или зачем тогда я писал "обрезатель" без округления (пик) var a:int = 999999999999 var b: Vector2i = Vector2i(a,a) print(b) простыми словами a:int это a:int64 тогда как b это Vector2i(int32, int32)
>ты свой код через год откроешь (да какой год, месяц) - там будет как-будто другой человек писал спасибо за мнение конечно, но думаю у меня опыта побольше
>>1064940 А, понял тебя. Круто. Я себе похожее делал, но проще. У меня и диалоги попроще - линейные и без выебонов. Зато саунд прикрутил к typewriter effect.
>>1064945 Да таймер это самое нежное, что из ебки тут было. Все начиналось тоже с линейных диалогов. Это сделал за вечер. Новелла как промо к основной игре. Потом мне сказали что линейная новелла на 15 минут хуета. Ну и в итоге появились и концовки, и сторипоинты и тепловизоры и шейдеры огня и ANXIETY LEVEL где сгенерированный голосом звук усиливает писк в ушах во время стресса Ебал я эту разработку короче. Надо было на Юнити из готовых ассетов хоррор бродилки с записками делать
>>1064948 Там наверное кроме как через логику инспектора и создание в схожем стиле и не сделать графический сторителлер. Думал попробовать сделать аналоги блюпринтов из анрила только для сборки диалога и эвентов через ноды. На новогодних если будет время - попробую
>>1064950 Логика инспектора - нет. Аналоги-блюпринтов - нет. ИМХО, конечно, но если делать, то только на своих виджетах, и форму выводить отдельным табом в редактор, как делают все диалоговые аддоны.
Просто на ровном месте отвалился и нихуя не хочет возвращаться. Я уже и кеш чистил, и скрипт переименовывал и лез в сцену в текстовом формате менял там пути и айдишники. Нихуя не помогает. Так же думал, что ошибка в скрипте, но проверил все 10 раз - все нормально, да и до этого все месяцами работало. Как понять произошедшее? Жиды не хотят чтобы я выпустил игру?
>>1064944 >спасибо за мнение конечно, но думаю у меня опыта побольше С этим феноменом сталкиваешься когда начинаешь сопровождать код, то есть работать программистом (или поддерживать многолетнюю разработку, пускай и свою), у меня большие вопросы по твоему опыту.
>чтобы стать лучше Судя по попыткам самоутвердиться и проблемам юношеского максимализма тебе еще 25 нет. Либо ты старше, но у тебя до сих пор не сформировалась лобная кора головного мозга, отвечающие за критическое мышление.
>убрали таблицу лидеров, И ты решил нам эту помойку из аськки графики сюда принести? Зачем? Чтобы похвалили или что? Молодец, осилил гдскрипт. Лучший.
я нихуя не понимаю, кроме if else и var. чему учиться, как вообще полировать механики, ну не все же строится на if и else и блять почему у меня такая уёбищная гравитация и рывки extends CharacterBody2D
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity") var is_dashing = false var dash_time = 0.0 var dash_direction = 0
func _physics_process(delta: float) -> void:
if not is_on_floor(): velocity.y += gravity delta
var direction := Input.get_axis("ui_left", "ui_right")
if Input.is_action_just_pressed("ui_reject") and direction != 0 and not is_dashing: is_dashing = true dash_time = MAX_DASH_TIME dash_direction = direction
>>1064983 >match он че делает? Матчит, лол. Синтаксис следующий var test: int = 3 match test: 1: return false 2: nihuya() 3: funkciya() Думаю интуитивно ясно, что он делает.
>и что такое табуляция Не пизди, ты не можешь этого не знать. Пробелы перед кодом, своего рода { }
>>1064975 >И ты решил нам эту помойку из аськки графики сюда принести? Зачем? Чтобы похвалили или что? Чтобы у тебя жопа сгорела, получается. Я её ещё в шапку треда занёс. Не видел?! Странно. Ты видимо не очень внимательный.
>Судя по попыткам самоутвердиться Попытки?! Так самоутвердился, 12 из 12. А ты на мне пытаешься самоутвердиться, рассказывая какой ты опытный и знающий и отвечая "от всего треда"?!
>С этим феноменом сталкиваешься когда начинаешь сопровождать код, то есть работать программистом (или поддерживать многолетнюю разработку, пускай и свою), у меня большие вопросы по твоему опыту. Трудовыми книжками хочешь померяться?
>>1064984 блять, я настолько тапок, что не понял match а табуляция, ты имеешь в виду эти стрелки перед текстом кода? как я понял, они разбивают отдельные действия и делают "дочерние". или устанавливают зависимости. или пошел я нахуй
>>1064969 Хз, не встречал. Удали скрипт полностью через файловый док движка (предварительно скопируй контент), и создай новый, с другим названием. Поможет - был некий баг с кешем/uid или чем-то таким. Не поможет - надо смотреть контент скрипта. В вебдеве, например, говнюки любят пихать тебе в инпут непечатаемые символы и прочие радости, которые сводят с ума начинающих макак.
>>1064985 >Я её ещё в шапку треда занёс. Не видел?! Странно. Ты видимо не очень внимательный. Ты настолько жалок, что перекатил тред со свой чепухой? Ну ты же понимаешь насколько это все плохо?
>Трудовыми книжками хочешь померяться? Чем еще будем компенсировать, ты же не покажешь? Чел ты попал в ловушку переполнения 32битного инта, зная что под капотом API на плюсах. Первое что ты должен был проверить, это стали ли они переписывать на плюсовые int64_t (нет не стали). О чем ты, джунище :)
Я не думаю, что людям интересно читать наш срачь, поэтому покормил последний раз (но трудовую жду, оператор эвм).
>>1064217 >Теперь надо думать как текстурить персонажа. Гляну решения от нейронки. Вот ето да, что нейронка могет прямо из блендера. Да, косяков навалом, но 80% работы с текстурой автоматизируется, остается только запечь и отпалировать стыки, пальцы, швы, мелкие детали.
Процесс оказался намного тривиальнее чем я думал: 1. Скрипт рендерит карту глубин с нескольких камер в разных ракурсах. 2. С каждой камеры скрип генерирует UV развертку в процекции камеры. 3. Скрипт передает каждую отрендеренную карту глубины в ComfyUI для генерации на ее основи изображения по прому. 4. Скрип строит замысловатый материал, который накладывает каждую сгенерированную картинку на персонажа и суммирует с остальными проекциями получая итоговый результат.
Собсно на пикриле тот же самый процесс только вручную, сначала отрендерил карту глубин модели в разных проекциях с разных камер, затем сгенерировал персонажа по этой карте глубин в ComfyUI, после чего можно накладывать эту картинку в Blender и запекать на модели с последующей шлифовкой. Но аддон StableGen просто автоматизирует рутину и мне остается только этам шлифовки.
>>1065019 > по сигналам даже не узнаешь что реализовано что нет Эмм.., что? Сигналы для того и нужны, чтобы им было похуй, реализованы они или нет. Если не реализовано - ничего не произойдёт. Это суть сигналов.
>>1065052 Я предпочитаю шину сигналов. Вместо того чтобы объявлять кучу разномастных сигналов в различных игровых системах и менеджерах, я один раз делаю шину и прописываю её в автозагрузках. Все могут сказать шине: > пш-пшш, йоба в эфире, я скозал, йоба в эфире 11 > bus.emit(yoba, 11) А так же все могут сказать шине: > если кто-то скажет в эфир про йобу, я выполню вот этот метод, и если в сообщении будет число, передай его мне аргументом > bus.connect(yoba, func(x): print(x)) И всё. Система непотопляема. Даже объяснять лень.
>>1065153 На самом деле, даже прописывать в автозагрузках не обязательно (ИТТ многие боятся этого), можно сделать класс, скажем, SignalBus у которого будет внутренняя переменная bus, которой присваивается ссылка на корневую ноду ($"/"), далее все операции класс производит с этой шиной. При коннекте сигналов, он лениво создаёт на шине кастомный сигнал, если того не было, и подписывает поданный коллбэк на этот кастом-сигнал. При эмите сигналов он смотрит, есть ли сигнал с указанным кодом, если есть, переизлучает этот сигнал с поданным на вход аргументом. Если сигнала нет, можно насрать в лог, я разрешил, если уровень логгирования в проекте - подробный. Элегантно же, ёпт. Мы спрятали целый синглтон на самом видном месте, цена синглтона - ноль, потому что мы его не создавали. Это корень дерева, и он создаётся самим движком.
>>1065153 Только не забывай делать единый источник истины для данных. Например глобальный кеш. События должны оповещать об изменении данных в источнике, а не передавать все что вздумается. Если ты начнешь синхонизировать локальные состояния, то это ивент говно быстро перестанет быть отлаживаемым и вообще понимаемым что в нем приосходит.
>>1065005 Вопрос решил. Рассказываю. У меня в коде упоминался мой класс. Условно if some_node is MyDegenerateClass: По какой то причине годот передумал конпилировать этот класс раньше скрипта, в котором содержится его упоминание (как я понял эту процедуру) и по этому на уровне инициализации, еще при запуске движка, игнорировал этот файл как скрипт. Решилось мягкой проверкой if some_node.get_class() == "MyDegenerateClass":
>>1065153 Потребность в шине, в микросервесной архитектуре является скорее костылем решающие проблемы этой архитектуры. Но в бэкенде там настоящие независимые сервисы. В годоте смысла вообще нет, у тебя игра это и так монолит, у тебя не будет одна игра к другой подключаться, то что у тебя полоска хп игрока в HUD как то независима от игрока, ну ок, а что это дает? Это остается частью элемента персонажа, просто вынесено отдельно для удобства (ты ее не переиспользуешь нигде).
>>1065173 Полностью подтверждаю. Это действительно так.
>>1065203 > у тебя полоска хп игрока в HUD как то независима от игрока, ну ок, а что это дает? Возможность работать над UI в отдельной сцене, настраивать и отлаживать на болванчиках, не трогая основные сущности и системы. Это удобно даже в соло-разработке.
А так же можно: Полностью заменить весь UI не трогая остальной проект. На лету менять разные отображения UI по мере игры, отражая развитие сюжета. В монолитном проекте, где зелёная нода прибита гвоздём к красной/синей ноде - это будет пиздец.
>>1065174 Ох как же годот-команда ещё обожжётся об uid-дрисню, которую они внедрили. Самый пиздец ещё впереди. Критикуя предлагаю: идентификаторы сериализованных ресурсов хранятся прямо внутри текста файлов. Поэтому и в скриптах нужно было так же сделать. Добавить первой строкой uid-коммент, который вырезается редактором из отображения скрипта, который создаётся, если отсутствует. В настройках добавить галку "отображать uid в скриптах" для любителей всё держать под контролем. Но вот эти добавочные файлы - это... это пиздец.
>>1065222 То что ты предлагаешь - пиздец куда больший, оно будет руинить файлы, не будет давать возможность открывать пнгшки внешними редакторы изза внедряемой годотом хуйни. Нормально работающие юиды - куда меньшее зло чем стандартное "путевое" решение и уж тем более если сравнивать этот вариант с твоим предложением.
>>1065222 И тут прихожу я с внешним редактором, и вижу эту дрысню в начале каждого файла в своем вскоде/зеде. А потом еще охуеваю от моих сломанных жсонов, которые я использую как дататейблы, ведь их теперь парсер не ест, сообщая мне что в их начале сидит неведомая ебаная хуйня. А еще у меня в проекте пара бинарников и файлов на питоне, которые я не дергаю напрямую из годота, а запускаю из консольки для генерации того или этого. Слышь, нафига мой бинарник сломал?
Они ну ооочень долго обсуждение вели, как и бывает у годота, рассматривая разные подходы. Но вообще не думаю что у того анона проблема из-за uid всплыла. Может регрессия какая. По-хорошему надо четко поймать как повторяемый баг и нести на гитхабю
>>1065221 >Возможность работать над UI в отдельной сцене, настраивать и отлаживать на болванчиках, не трогая основные сущности и системы. Ты это можешь и так сделать, если у тебя сцена. Плюс коннект имеет так же хардовую ссылку (что в реале плюс). Коннект в коде и зеленная ссылка - не имеют архитектурной разницы, это просто разный подход.
Дваче, не подскажете, как у label работает autowrap mode? Включаю его - выскакивает предупреждение, мол настрой минимальный размер, ибо в контейнере находится. Настраиваю, нихрена не переносится. Тупо текст улетает за границы экрана. Этот label находится в margincontainer. Как настроить ебанный перенос слов?
>>1065342 Да, кстати, есть такой форумный эффект, который на двачах тоже проявляется в полной мере. Когда расписываешь свою проблему, решение приходит само, иногда даже когда запостить не успел.
>>1065342 > Я как-то минут 10 правил не тот исходник Я как то запустил юнити и минуты ждал его прогрузку, а потом вспомнил что проект на годот и юнити я больше не использую.
А ведь в новых хардкорных по железу условиях индюки в выигрыше. ААА графон в одно ебло все равно не сделать, а нищеебов на нищесборках становится все больше и больше - как раз наша аудитория. Там уже Ларианы ноют, что им беднягам, видите ли, приходится ОПТИМИЗИРОВАТЬ под РАМ.
>>1065439 Я не силен в 3д, но тут же шейдеры какие-то, которые грани скрывают? Как-будто есть секрет или нет? Ну и сглаживание, на лопу поли без сглаживания 4х-8х будет же больно? А это убьет весь выигрыш от лоуполи?
>>1065495 Там smooth shading и современное освещение, плюс относительно HD текстуры. У Ларки тоже smooth shading, но при этом старое вертексное освещение.
>>1065499 Если исключить еблю с текстурами - 3д гораздо приятней чем 2д. А самый ебучий стиль это 2д пиксель арт, пиздос просто, три игры в нем сделал и рот его ебал, идеальная ловушка новичков нахуй.
>>1065503 Анимировать ебанись. Копья 1 и головы сверху повернуты алгоритмом, алгоритм неидеален - выглядит всрато. Копья 2 и чувак - фейковый пиксель арт, пиксельные спрайты внутри 2д (не вьюпорт) игры, как следствие пиксели не снапаются по внутренней пиксельной сетке игры и не совпадают с неповернутыми пикселями других спрайтов. Головы снизу это единственный правильный вариант, и они явно были дорисованы/исправлены руками. У них и пиксели по сетке, и артефактов нет.
Кроме самого арта еще с разрешением окна ебаться чтобы недайбох сабпиксели не вылезли, с движением камеры, с y-sort'ом, со слоями, с тенями. Если спрайт сложный, широкий-высокий-диагональный, то его скорее всего придется нарезать на куски, чтобы разные его элементы правильно сортировались, когда игрок вокруг них бегает. Тогда как в 3д это все практически нахаляву.
>>1065507 Ещё вспомнил. Пиксель арт нельзя скалировать, только перерисовывать. Проебался с масштабом? Перерисовывай. Хочешь монстру сделать младшего братана? Перерисовывай. В обычном 2д и в 3д скалируй как хочешь, и обычное дело когда в ААА десяток разных камней это, на самом деле, один и тот же камень, повернутый и отскалированный по разному.
Короче, пиксели это стиль-наебка, заманивает нюфагов и ебет их кучей подводных. Лучше уж обычный 2д.
>>1065509 В лоуполи 3д тоже не шкалируют. Деревце поменьше должно сотстоять из меньшего числа полигонов чем деревце побольше. Ты конечно можешь монстров уменьшать чисто масштабом, но это выглядит как халтура
>>1065514 В представлении быдла широких масс пиксель-арт это самая примитивная графика, которую любой школьник намалюет в пейнте. Вон недавно марвеловский пиксельный битемап выходил с охуенными анимациями с кучей кадров, а в комментах на дтф многие комменты были уровня: >ну и халтура ебаная, графон за миска рис
>>1065522 В представлении быдла и игры делать легко, залетаешь такой с гениальной идеей, и хопа, соулслайк экшон эрпоге готов. Хуево когда такие мнения раскидывают популярные ютуберы, сами ни одну игру не сделавшие. И люди им верят, а потом от тебя, индюка ебаного, требуют непомерного.
Я бы кончил радугой, будь у меня стиль с твоего пика.
>>1065526 Время вектора ещё не пришло. Ностальгия по флеш-играм (которые вовсю эксплуатировали векторную графику) ещё не вызрела. Флешеслав не в счёт, он опережает своё время.
>>1065530 Это не поможет "распилить" 1 большой пиксель на n пикселей нужного размера. Новые пиксели вектор не добавит, ты просто возьмешь первую морковку, сделаешь ей зум, и поставишь на место третьей морковки.
>>1065507 >>1065509 >>1065500 Я пробую себя в векторе/растор, пиксель арт мне тоже не по душе. 3Д слишком долго для соло (для меня). Но главная проблема 3Д - это плохая моделька или текстура сразу въедается в глаза даже если стиль лоу поли, то есть выглядит дешевым (или у меня опыта мало и надо фильтрами обмазать, хз).
>>1065553 На твоей пикче даже не понятно сразу трава это или ядерные боеголовки или охапка карандашей.
Поворачивать спрайты вокруг z координаты не всегда надо. В изометрии не нужно совсем. Там нужны 4 - 8 вариантов одной анимации. Это да. С учетом зеркальной симметрии по Y можно 3 - 5 вариантов делать.
>>1065553 >>1065560 >то есть выглядит дешевым То что у тебя щас это следующий уровень дна\дешевизны, как флешки которые в нулевых распространялись на дисках.
>>1065614 Он и веб-браузере запускается. И сам редактор и экспортированные игры. И на андроиде - современные пиздюки геймдевят прямо на телефонах. И на айосах и айпадах Мигелюшка недавно запилил.
>>1065648 Не знаю, мой зиончик по совету анончика с Али вполне справляется. Что ж у тебя за железо такое древнее, что тебе никак без 4,5 тактов не протянуть?
Какая же залупа с этими нейронками. Просто не хочет ставить персонажа в нужную позу по промту, а если добавить openpose то все сразу превращается в какую-то жопу. Для пайплайна осталось накрутить генерацию референсов в трех проекциях по которым будет генерироваться моделька в другой нейронке.
>>1065671 ДАЙ!!! использую ИИ чтобы нарисовать то, как ИИ крадет оперативную память - это ли не обещанная сингулярность в искусственном интеллекте, запланированная на 2025 год??
Кстати, на итче нашел нейроговно, иллюстрирующее подводные пиксель арта, о которых говорилось выше. Тут и пиксели разного размера, и пиксельные спрайты повернуты не по сетке, и шрифты уехали ибо не пиксельные, и сабпиксели вылезли, и пропорции похерены, и движение не по сетке.
Судя по странице, там все нейроговно - код, арт, описание, "девлоги", вообще все. Ссылку постить не буду, игра не на годоте.
>>1065673 Ну не про. художник будет тоже плохо рисовать, поэтому какая разница, сам он рисовал или ИИшкой? Ты же таскаешь код ИИ, а это тоже был труд программистов.
>>1065675 Главное что это и выглядит как дрист, и играется как дрист, и опыта дает нихуя. Такой игроподобный продукт не нужен никому, ни аудитории, ни самому разработчику.
>>1065676 >Главное что это и выглядит как дрист, и играется как дрист Ты сейчас буквально описал всю игровую индустрию. Одни пытаются развести других и за 15 лет только "обёртки" стали краше. Не верю что ты делаешь игры от души, ты просто завидуешь что кто-то сделал наглее чем ты себе позволяешь (и получает, вероятно, профиты). Дай ссылку, купим тебе назло.
>>1065678 Слопогенератор, не проецируй. А игровой продукт этот мог бы уже гуглом найти, но, видимо, привычка попрошайничать все готовое тебе мозг отбила.
>>1064638 >Он написал код на gsdcript через match. Всё правильно гугл тебе выдал. Ты что хотел? >нужна чтобы не запутаться в портянке if...else Да, именно поэтому тебе нужен match и enum.
>>1064729 >задавать UV координаты для модели https://docs.godotengine.org/en/stable/classes/class_arraymesh.html Код приблизительно так будет выглядеть: >var arrays := your_generic_mesh.surface_get_arrays(0) >arrays[Mesh.ARRAY_TEX_UV] = custom_uv_array >var custom_mesh := ArrayMesh.new() >custom_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) >$MeshInstance3D.mesh = custom_mesh Можно автоматизировать @tool-скриптами...
>>1064775 >дергается get_node("timer"), get_node(...)? Я не проверял, но по идее - да, должен дёргать это. >Это же накладно очень (в процессах) Один раз не страшно. В Unity всё точно так же.
>>1064787 >иначе оператор @onready не всрался бы никому У них совсем разное предназначение вообще-то.
"$Node" - это просто get_node("Node"). Т.е. если нода переместится в дереве, выйдет из дерева или будет переименована, эта строчка упадёт с ошибкой.
Строчка с @onready выполняется до _ready, как если присвоить ссылку переменной в обычном коде, и эта ссылка сохраняется независимо от положения или конкретного имени ноды. Эта ссылка ломается лишь после освобождения конкретной ноды (queue_free()).
>>1065681 >Всё правильно гугл тебе выдал. Ты что хотел? Зачем ты это высрал, если ты даже не знаешь что такое стейт машина?
>>1065683 >Один раз не страшно.. Будет дергаться каждый раз (Каждый кадр и каждую итерацию цикла), это просто сахар для get_node(). Используйте только так: @onready var label = $Node/Label
Не вводи людей в заблуждение своим ламерством.
GDScript код можно шарить в онлайн редакторах, а не гринтекстом.
>>1065002 >func _process_command_silent(command): >_ if command is CommandA... >_elif command is CommandB... >_elif command is CommandC... >_elif command is CommandD... Оцениваю твой код на 10 Яндере из 10 Девов.
Как это ПРАВИЛЬНО делать: >func _process_command_silent(command: Command): >_ command.process_silent() Далее реализуешь "process_silent" в каждом классе: >@abstract class_name Command >@abstract func process_silent(): pass >class_name CommandA extends Command >func process_silent(): ... >class_name CommandB extends Command >func process_silent(): ... >class_name CommandC extends Command >func process_silent(): ... >class_name CommandD extends Command >func process_silent(): ... Так код будет более читаемым и надёжным.
>>1065689 >не знаешь что такое стейт машина? Конечные автоматы не относятся к ООП, если ты намекаешь на создание сотен мелких классов. И в большинстве случаев тебе не нужны эти отдельные классы на каждое состояние автомата - хватит и единственного enum с одним match в 99% случаев.
Не делай код сложнее, чем необходимо.
>>1065689 >Используйте только так: >@onready var label = $Node/Label Это лишнее для glue кода в тестовом скрипте очень грязного прототипа (черновика), который в скором будущем выбросишь и перепишешь начисто, либо откажешься от задуманного (для того он и нужен).
Алсо, лучше всего это оформлять так: >@onready var _label := $Label as Label Для проверки и жёсткой привязки к типу.
>>1065691 Я бы кинул с пруфами, просто не хочу донатить на заблокированные сайты (я подумал в стиме есть). Забавно что ты порвался на какой-то хобби проект, возможно реально ньюфага. И в тоже время как обидно, ты художник и твой труд может повторить любой вкатун за 1 минуту?
>>1065222 >идентификаторы сериализованных ресурсов хранятся прямо внутри текста файлов. Поэтому и в скриптах нужно было так же сделать. Возможно, открою секрет, но: 1. GDScript можно хранить в формате .tres. 2. GDScript можно хранить внутри сцен .tscn. В обоих случаях UID будет внутри этого файла. В обоих случаях код сохраняет plain text формат.
>>1065690 Можно ещё через единственный прокси-класс реализовать. Так будет намного меньше мусорных классов в проекте, но читабельность на том же уровне: >func _process_command_silent(command: Command): >_ command.process_silent() Казалось бы то же самое, но кот код Command: > class_name Command > var _back: Callable = func(): pass > func process_silent(): _back.call() > func _init(process_callback: Callable = _back): _back = process_callback Таким образом мы по месту клепаем сколько хотим экземпляры-стейты нашего прокси-класса, прямо через конструктор задавая им метод, который они будут выполнять. Никакого наследования, никаких абстракций. Критикуйте.
>>1065696 Что именно ты пытаешься оспорить, по какому вопросу возразить? Я не понимаю.
При сохранении внутри ресурса, формат предусматривает необходимые поля для сохранения UID, поэтому там UID не будет писаться в специальный невидимый комментарий, а писаться будет в специальное поле.
>>1065693 Если я правильно понял его подход - то эти Command - потомки Resource и хранятся как части Resource... Т.е. теоретически они могут "выполняться" как команды: >for command in commands: command.execute() Портянка из if-else и даже match ухудшает чтение.
>>1065697 >меньше мусорных классов в проекте У него так и так должны быть потомки Resource для отображения в инспекторе, как я понял его систему (разрабатывал похожее даже несколько раз уже).
>прямо через конструктор задавая им метод Смысл в том, чтобы раздробить код на множество относительно независимых файлов, а у тебя будет идентичная портянка в одном файле, только другая.
>>1065692 >Я в Godot-тредах почти 6 лет сижу... А стоило бы в документациях.
Если с типами, то очевидно лучше (привычнее) так. @onready var label: Label = $Label
Подчёркивание не нужно если ты соло разработчик (и не пишешь либу). А если в тиме, то просто договоритесь что юзаете только геттеры и сеттеры у классов (никогда не трогаете проперти). Все остальное пахнет овер макакингом из бэкенда.
>>1065701 > Подчёркивание не нужно если ты соло разработчик У меня как у соло разработчика вся тима прямо в голове, мы посовещались и решили, что пока в гдскрипте нет приватных членов, мы маркируем подчёркиванием всё что должно быть приватно. Таким образом, через несколько лет, если тот кто будет в моей голове на тот момент откроет мой код, он без труда определит, что вот те члены публичные, а эти приватные.
>>1065703 В этом смысле хочется пожелать Хуану, чтобы он сделал как в современыых соевых языках принято: всё члены приватны по умолчанию и для них не требуется особых аннотаций, а для публичных введена аннотация @public
> @public func calculate(): pass > @onready @public var label = $Label И чтобы экспортная аннотация была публична по умолчанию, из-за своей публичной природы.
>>1065703 Я тебе как разработчик с 15 летнем стажем говорю, все свойства класса по умолчанию приватны, забудь что бывают публичные поля (и друзьям в голове скажи).
>>1065704 И ещё чтобы все переменные по умолчанию создавались иммутабельными, а если нужно в порядке исключения сделать мутабельную, то аннотация @mutable > @mutable @public var hitpoints : int = 0 В этом случае экспорты по умолчанию тоже иммутабельны и в инспекторе выглядят серыми ридонли-нередактируемыми. Чтобы их мутировать, тоже добавлять аннотацию: > @mutable @export var level: int = 1
>>1065608 >между кадрами удаляют первый элемент массива Если массив мелкий, то разница незаметна... Но для удаления начала обычно используется pop_front(): >Note: This method shifts every other element's index back, which may have a noticeable performance cost, especially on larger arrays.
>Или у годота есть какая-то оптимизация для этого (смещение/слайсы под капотом) и так можно? Я как-то пытался читать исходники на эту тему - там несколько слоёв абстракций с cow data (лол, это так сокращают copy-on-write), и понять суть кода сложно (особенно потому что я не изучал специально C++).
Самое простое - это провести эксперимент. Пишешь несколько вариантов кода и замеряешь время его выполнения. Разница обычно заметна от 1000-10000 элементов массива, так что делай цикл for побольше.
Когда-то уже замеряли всем тредом и кидали логи...
В теории, для навигации по точкам массив лучше развернуть, а потом удалять точки с хвоста. Тогда под капотом лишь сокращается размер массива на месте. Однако, операция разворота тоже дорого стоит...
>>1065710 > Когда-то уже замеряли всем тредом и кидали логи... Именно так. Я там был. И пришли к выводу, что самое быстрое и эффективное решение - инвертировать массив, после чего фронты превращаются в бэки, удаляешь сколько нужно, затем повторно инвертируешь.
>>1065710 >В теории, для навигации по точкам массив лучше развернуть, а потом удалять точки с хвоста. Тогда под капотом лишь сокращается размер массива на месте. Однако, операция разворота тоже дорого стоит...
Поэтому стоит использовать подход как с чтением файлов. Завести проперти seek - в которой хранится текущее положение. И вместо удаления seek += 1 (проверив переполнение) Как плюс, можно шаг назад сделать (например если рисуешь линию пути)
>>1065710 > замеряли всем тредом и кидали логи... Я был одним из тех, кто кидал результаты измерений. > Однако, операция разворота тоже дорого стоит... Да нет же, она стоила дёшево.
>>1065709 >А разработчики Годота постарше тебя будут. Стаж исчисляется двадцатилетиями! Поэтому завезли геттеры и сеттеры. Потому что опытные разработчики проперти напрямую не трогают (только для отладки, но никогда в качестве API). А вот для приватных методов надо. Хотя можно придумать свою замануху типа p_my_private(), p_other_private() но не надо :)
>>1065702 >Вся портянка в одну строчку Но словарь-то ты будешь протянкой объявлять...
>>1065701 >@onready var label: Label = $Label Поясняю проблемы по пунктам: 1. $ - это get_node(), он даёт только Node. 2. ...: Label = - это мягкий/неявный тайпкаст. 3. @onready label - это не стоит трогать извне.
Если мы делаем так: >get_node("Label") as Label или $Label as Label Мы явно требуем класс Label, иначе будет null. >:= Это просто сокращение, т.к. тип явно заявлен. >_label Скрывает свойство из выпадающего списка.
>Подчёркивание не нужно если ты соло >просто договоритесь что юзаете только А можно ещё просто на ассемблере писать...
>>1065714 >Поэтому завезли геттеры и сеттеры Наоборот, Godot переходит с get/set на свойства. Раньше почти все API были через тупые get/set...
>>1065714 > Поэтому завезли геттеры и сеттеры. После того как их джва года просили. Сами то они додумались именно что заманухи p_my_private(), p_other_private() в апи выкинуть, как пишет вот этот даунинг-крюгер ниже >>1065715 > Наоборот, Godot переходит с get/set на свойства. > Раньше почти все API были через тупые get/set...
>>1065715 >Но словарь-то ты будешь протянкой объявлять... Лямбды лучше чем лес пустых Классов.
>>1065715 > Label = - это мягкий/неявный тайпкаст. Что еще за мягкие касты? Сам придумал? Нам нужен Label, мы его получаем. Пофиг полиморфно или напрямую (или null).
>>1065715 >Скрывает свойство из выпадающего списка. Какого списка? Автокомплита? Он же нам в коде как раз и нужен.
>>1065715 >Наоборот, Godot переходит с get/set на свойства. Свойства это тупо сахар над геттерами и сеттерами.
Ты вроде и разбираешься, но иногда такую неграмотную шляпу пишешь.
>>1065717 >додумались именно что заманухи в апи выкинуть Ты любишь писать код в таком стиле? >var text := label.get_text() >text += ", hello!" >label.set_text(text) Или всё-таки предпочитаешь делать так? >label.text += ", hello!" По-моему, ответ очевиден, а ты троллишь нубов...
>>1065718 >Лямбды лучше чем лес пустых Классов. Если тебя устраивает портянка в одном месте. >пустых А если потребуется добавить побольше опций? >class_name CommandShowPic extends Command >@export_tool_button("Enlarge") var ebtn := enlarge >@export_tool_button("Shrink") var sbtn := shrink >@export var pic: Texture >@export var dick: bool >@export var lenght: float >@export var girth: float >func enlarge(): ... >func shrink(): ... >func process_silently(): ... >func process_sloppy(): ... И это должно настраиваться на панели инспектора.
>Что еще за мягкие касты? Ладно, перепутал, там просто падение с ошибкой. >Автокомплита? И это перепутал - сейчас они там отображаются... Но всё равно, намного удобнее начинать с "_"... >Он же нам в коде как раз и нужен. Приватные нужны только в скрипте, где объявлены.
>Свойства это тупо сахар над геттерами и сеттерами. Но иногда свойству не нужно ни то, ни другое...
Ну вот объект читает своё свойство ИЗРЕДКА. >var rarely_used_data: ... Зачем вызывать МЕТОД для его обновления? А если ВДРУГ понадобится, то потом напишешь: >var rarely_used_data: ...: >_ set(v): ... И всё. Не нужно сеттеры вызывать вручную.
>>1065719 >все бы писали $node если бы не было смысла Если ты переименуешь ноду, $node сломается. Удобнее иметь уязвимое место в одной точке...
Я обычно в своём коде делаю так: 1. Накидываю новую ноду, скажем, Timer. 2. Обращаюсь к нему тупо через $Timer. 3. ЕСЛИ она мне окажется очень нужна: 3.1. ЕСЛИ она прибита гвоздями: @onready 3.2. ИНАЧЕ нужно больше гибкости: @export 4. ИНАЧЕ удаляю ноду Timer вместе $Timer.
Обычно я предпочитаю @export: >@export var timer: Timer + Godot сам следит за этой нодой + видное поле в инспекторе + более читаемый код + модульность + гибкость
Раздражает, что редактор сам вставляет строчки, которые помечает серыми номерами...
ЭЙ, GODOT, ВСТАВЬ МНЕ ССЫЛКУ НА НОДУ ИЗ ДЕРЕВА, МНЕ ЛЕНЬ @ ОКЕЙ, БОСС, ВОТ @ONREADY VAR NODE: NODE = $NODE @ НО, БОСС, ЭТО БУДЕТ НЕТИПОБЕЗОПАСНО... @ И Я НЕ ЗНАЮ КАКИЕ ТАМ СВОЙСТВА... @ А ПОЧЕМУ БЫ НЕ ЗАЮЗАТЬ "AS"? @ АААА, ТЕПЕРЬ ВИЖУ!!!
>>1065730 Когда ты пишешь код ты для автокомплита пишешь текст, а не начинаешь с подчеркивания (чтобы тебе высрали все полсотни имен начинающихся с подчеркивания).
То, что есть разница автокомплита между объявлением типа и приведением типа - это недоработка редактора (или в плохом LSP). Как видишь в нормальном редакторе (пик с vscode) все нормально. да, у меня проблемы я часть кода пишу по привычке в camelCase Дефолтный редактор очень убогий для серьезной разработки (зачем они вообще его высрали?)
Фатальная ошибка годота, что он за основу взял псевдо-язык вместо сишарпа. Сразу бы пласт проблем по языку, IDE и API пропал бы. Причем что современный шарпы 10 лет как MIT (и очень близки к С++ чем квази-питон).
>>1065730 >Если тебя устраивает портянка в одном месте. Тебе так и так описывать команды, пусть хотя бы они будут там где им место (в модели (бизнес-логики), а не в контроллере)
>А если потребуется добавить побольше опций? У тебя лямбда, внутри нее ты можешь делать все что угодно и работать с любыми данными.
>Но всё равно, намного удобнее начинать с "_"... Так никто не делает кроме ньюфагов. Все начинают с ключевых слов, в норм редакторе можно даже не по порядку начинать
>Но иногда свойству не нужно ни то, ни другое... Ой все, ппц ты ламерище, я больше не могу.
>>1065758 >Ньюфаг узнал слово "ламер" Мы рады за тебя. А еще ты сегодня узнал что ноды надо присваивать в поля класса в _ready/@onready и не удалять начальный элемент массива, чтобы избежать лишних аллокаций в "циклодробилках" (и просесть по O(n)).
>>1065760 > ты сегодня узнал Только в твоем ограниченном мирке. Ты молод, у тебя прогрессирует юношеский максимализм и еще не до конца сформировалось лобная доля ответственная за критическое мышление. Твой мир крайне прост и примитивен, ты словно молоток, а весь мир у тебя гвозди. Мир намного сложнее чем тебе кажется.
В ветке 4.6 немного поломали кнопку Make Unique: https://github.com/godotengine/godot/pull/113869 Будьте внимательны: если создаёте ресурс отдельно от сцены или он ещё не сохранился внутри сцены, то кнопка Make Unique будет недоступна для суб-ресурсов. Ресурс по-прежнему можно сделать уникальным, если перетаскивать с зажатым Ctrl, но на кнопку нажать нельзя. Чтобы стало работать и чтобы новая фича (кнопка с цепочкой + счётчиком) стала отображаться, нужно создавать ресурс внутри сцены и сразу делать его локальным... Или ждать, когда вернут старое поведение в мастере. Я потратил много времени из-за этого бага, т.к. создал новый ресурс отдельно от сцены и не сразу загуглил эту проблему. Ну, ничего страшного в общем-то, да и сам виноват, что решил пораньше перекатиться на предрелизную 4.6...
>>1065746 >ошибка годота, что он за основу взял псевдо-язык >редактор очень убогий для серьезной разработки Ошибка в тебе - у тебя синдром утёнка. Большинство перекатывающихся с Unity также перекатились с C# на GDScript и довольно урчат в чатах о том, насколько GDScript лучше мерзкого клона Java от Microsoft, и насколько хорош встроенный редактор со встроенной справкой по сравнению с еле-еле пропёрживающимися внешними редакторами на мерзком Electron. Да, есть шероховатые углы, бывают баги, но здесь всё намного более поправимо по сравнению с исправлением ошибок C#/"больших" IDE. Я вообще сомневаюсь, что обычный инди-игродел сможет пропатчить основные библиотеки C# для своей игры, а с GDScript ты можешь что хочешь делать, потому что он целиком внутри Godot живёт.
>а не начинаешь с подчеркивания (чтобы тебе высрали все полсотни имен Сразу видно ньюфага, создающего God Object на 5000 строк и сваливающего эту проблему на окружающих.
>>1065747 Я не понимаю, что пытаешься показать. На твоём же скриншоте подтверждение моих утверждений выше.
>>1065748 >в модели (бизнес-логики), а не в контроллере База Godot - это event-driven architecture, а не MVC/MVP. Пытался делить ноды по MVC, но выходит та ещё лапша. Godot больше всего располагает к тому, что каждая нода и каждый ресурс - это вещь в себе, что и данными, и поведением обладает. Если ты относишься к ним как-то иначе, ты сильно себя ограничиваешь, наслаивая несколько слоёв абстрактной лапши, усложняя структуру твоих сцен и т.д.
>лямбда, внутри нее ты можешь делать все что угодно Функция по определению не может иметь состояния.
>начинают с ключевых слов Да, но удобнее начать с "_", когда тебе нужно что-то приватное.
>>Но иногда свойству не нужно ни то, ни другое... >Ой все, ппц ты ламерище, я больше не могу. Иногда коробка с апельсинами - это просто коробка с апельсинами, и никакой Чебурашка в ней не прячется, обрабатывая каждый входящий и исходящий апельсин по отдельности на каждое открытие/закрытие крышки. Понимаешь? Существование паттерна в ООП не значит, что его нужно лепить везде, куда его можно прилепить. Ньюфаги часто обнаруживают интересный паттерн и начинают искать способы его применить там, где ему не место, и в результате получают трудночитаемый код, который тяжело изменять...
>>1065822 >Игры лучше бы делали и показывали в треде. Так тут все делают неебацца ебу, допилят в лучшем случае в следующей жизни. Единственный чувак, что принес показать, сделал те два хоррора симулятора ходьбы с записками, потому что как настоящий гений избежал всех таймсинков.
>>1065822 >Unity также перекатились с C# на GDScript Без с# мне годот нахуй не упал, до сих пор сижу на тройке только потому что там нормально пашет с# на всех платформах, даже готов терпеть 7.3 и неотлаживаемые tool скрипты, перевел кучу либ на 7.3, абы только кайфовать на шарпе. >База Godot - это event-driven architecture event-driven это тебе не в тапки срать. Гарантия доставки(и правильности обработки), индемпонентность операций, валидация, хранение событий - покажи мне где эти куски event-driven в годоте? А их в нем нет, а если начать их пилить - все плюсы event-driven по пизде пойдут, особенно на гдс с еще прекрасной производительностью. >Игры лучше бы делали и показывали в треде. А показывать готовое или пилящееся тоже можно? Есть только пилящееся.
> Большинство перекатывающихся с Unity также перекатились с C# на GDScript и довольно урчат в чатах о том, Мы говорим про программистов, а не дизайнеров. Во первых никаких проблем с IDE нет, а есть несколько мощных редакторов, в том числе бесплатный Rider (ты даже не нюхал их). Твой же псевдоредактор не может в банальный рефакторинг.
Во вторых статическая типизация, а не хинты. Ты не насеришь себе в штаны если int64 засунешь в Vector2i где есть поддержка только диапазона int32 (неопределенное поведение в динамикодресне, ппц). А рандом вообще возвращает uint. Просто бардак в api, потому что хотели скопировать питон.
В третьих автокомплит серит прям в руки, или не работает или вываливает все кишки. Енамы просто смех. В общем, мне лень перечислять, но 99% проблем решилось бы, взяв любой настоящий язык (даже, простите, javascript).
>а с GDScript ты можешь что хочешь делать, потому что он целиком внутри Godot живёт. Вплоть до полного декомпиляции с сохранением имен переменных? Захотел игру, скачал со стима, декомпилировал - теперь это твоя игра, не забудь поменять ассеты.
>>1065822 >База Godot - это event-driven architecture, а не MVC/MVP У тебя всегда есть исполнитель и исполняемый, какие бы ты базворды не написал. Просто для понимая всегда упоминают контроллер/модель (потому что это знают все).
>>1065822 >Функция по определению не может иметь состояния. Во первых упоминалась лямбда и лямбда по определению может иметь состояние ламерище. Во вторых никто не говорил о состояние, лямбда упоминалась как процедура содержащая в себе код (в котором можешь дергать любые объекты).
>Да, но удобнее начать с "_", когда тебе нужно что-то приватное. Если бы ты реально писал код, ты бы знал что подчеркивание соберет все слова в которых есть подчеркивание (в любой позиции). Во вторых, на практике ты печатаешь сразу слово, даже встроенный редактор годота ищет по неточному совпадению (с любой позиции, пик). Ну и 10-20 полей и методов в классе, уже превращают твою идею в цирк (а это далеко не God Object)
Ты пылишься тем, что у тебя отсутствует опыт работы с автокомплитом даже встроенного редактора. Все, покормил тебя последний раз, теперь точно.
>>1065822 > База Godot - это event-driven architecture, а не MVC/MVP. Пытался делить ноды по MVC, но выходит та ещё лапша. Godot больше всего располагает к тому, что каждая нода и каждый ресурс - это вещь в себе, что и данными, и поведением обладает. Если ты относишься к ним как-то иначе, ты сильно себя ограничиваешь, наслаивая несколько слоёв абстрактной лапши, усложняя структуру твоих сцен и т.д. В шапку!
>>1065889 >У тебя есть в /gd тред? Нет, думаю создать на первую альфу (надеюсь на новогодние успею) >Бэкенд самописный? Да, c# бэк >Я так понял у тебя 3 годот Всё так
>>1065885 >нода.сигнал.коннект(лол) Ты хотя бы раз Godot открывал?
Ты можешь создать какое-то осмысленное поведение в сцене, вообще не создавая ни одного нового скрипта ни на каком языке (кроме tscn-сцены) - просто связывая сигналы через редактор сцен с методами нод. Полезный пример такой связи: >BaseButton.toggled(bool) -> CanvasItem.set_visible(bool) Это создаст в коде tscn такую строчку: >[connection signal="toggled" from="нода-кнопка" to="нода-цель" method="set_visible"] Сохраняешь, запускаешь, нажимаешь кнопку - нода-цель исчезает и появляется. Фантастика! При этом ты можешь двигать связанные ноды по дереву в пределах этой сцены, переименовывать их, даже менять класс - Godot сохраняет соединение, пока у ноды-источника есть сигнал, а у ноды-цели есть обработчик с заданным тобой именем. "Сломанные" сигналы не отключаются сами и не пропадают, а выдают ошибку в консоли, так что можно легко заметить, если что-то нечаянно удалил или неправильно поменял.
И так можно делать с любыми нодами. Можно расширить встроенную ноду на GDScript, на C#, на любом из языков для GDExtension, на C++ в модуле кастомного форка движка и т.д. Всё это будет работать идентично встроенным нодам.
Да, конечно, следить за связями не очень удобно... и даже есть плагины, которые пытаются решить эту проблему, создав визуализацию сигналов на отдельной вкладке (не пробовал). Но если подходить к дизайну сцен рационально, и вовремя делать декомпозицию сцены на меньшие компоненты, количество сигналов в отдельно взятой сцене не будет таким уж большим, чтобы в этом можно было запутаться. Всё должно быть очевидно по именам твоих нод.
Кроме того, если сильно хочется отвязаться от конкретных классов объектов в коде, есть методы Object: >Object.has_signal(StringName) >Object.connect(StringName) И т.д. Позволяют использовать duck typing - т.е. работать с любыми классами, у которых есть заданный сигнал.
Если пойти ещё глубже, у того же Object есть методы для создания, обнаружения и удаления сигналов: >Object.add_user_signal(String, Array) Которые можно излучать стандартным emit_signal(StringName). То есть при желании можно обвязаться очень густой динамической лапшой, которая создаётся целиком во время выполнения кода, даже из строчек, набранных юзером в поля ввода в интерфейсе игры. Хотя, в этом нет чего-то особенного - ведь GDScript можно прямо в игре писать, т.е. создать, например, игру-головоломку, где нужно написать реальный компьютерный код для решения задачи. Таким образом создали, например, тренировочную программу для обучению программированию на GDScript. И это всё здесь доступно из коробки, а не каким-то отдельным костылём, как в большинстве других движков/инструментов. Но конкретно с сигналами главный прикол в том, что их можно создавать через собственные плагины, например, если ты делаешь удобный визуальный язык программирования для своих дизайнеров или что-то подобное.
Так что это реально основа всего Godot (на равных с нодами, ресурсами и сценами) и пренебрегать ею глупо.
По терминам: я погуглил, "event-driven architecture/programming" используется в довольно широких пределах и имеет массу разнообразных реализаций/интерпретаций, прямо как ООП, но если у ООП есть доминирующая на сегодняшний день интерпретация, задавившая все альтернативы (все эти class и т.п.), то у EDA/EDP такого нет. Так что не вижу проблемы считать Godot и то, как он подталкивает структурировать игры "событийно-ориентированным".
>>1065843 На оф сайте написано, что гдскрипт такой по скорости в большинстве задач, но, при работе с массивами он не настолько быстрый, что для большинства колеров не критично
>>1065842 Я тут подумал, и мне кажется, у тебя слишком ригидное мышление: >У тебя всегда есть исполнитель и исполняемый Т.е. ты воспринимаешь команду "signal.emit()" как команду получателю сигнала исполнить нечто определённое, я правильно тебя понял? Но факт в том, что получателя может и не существовать. Или получатель может существовать, но он может проигнорировать твой сигнал. Или вообще сделать что-то, чего ты от него не ожидаешь. А всё потому, что ты не запрашиваешь исполнение какой-то работы, а просто уведомляешь о том, что что-то произошло внутри тебя или рядом. Т.е. это в первую очередь оповещение о том, что уже произошло (внутри/в источнике), а не о том, что должно произойти (снаружи/у получателя).
Это очень удобная точка зрения для создания новых компонентов. Когда ты создаёшь компонент, ты описываешь события, что происходят внутри компонента, но не знаешь, как они будут использоваться - и будут ли вообще. Потом, когда ты используешь компонент, ты можешь связать сигналы с каким-то кодом, который как-то реагирует на происходящие события, а можешь и не связывать. Суть в том, что код, построенный вокруг компонента с сигналами, не является обязательным для работы компонента. Когда таких компонентов несколько - ты можешь связать их друг с другом на одном уровне абстракции или добавить несколько ступенек абстракции, но в любом случае эти компоненты не будут ничего знать друг о друге, потому что связи строятся на совершенно другом уровне по сравнению с компонентами. Компоненты чем-то занимаются, оповещают о событиях и реагируют на команды, но они не завязаны друг на друга, хоть и взаимодействуют. Т.е. их отношения не "жёсткие", не прописаны заранее.
Иногда такая гибкость избыточна и только вредит. Но тут как всегда - любое лекарство ядовито, если не знать меры. Нужно самостоятельно оценивать, какие компоненты должны быть независимыми, а каким следует заранее знать друг о друге.
>>1065893 >Т.е. ты воспринимаешь команду "signal.emit()" Я воспринимаю всю систему сигналов просто как каллбэк обертку, она сделана наглядно для удобства и чтобы юзеры руками не начинали делать свой каллбэк хел в коде (передергивая между сценами).
Сигналы в годоте хардовые (те что кодом) - они хорошие, используйте на здоровье для простых решений. Но называть каллбэчную обертку - EDA, не стоит.
Пик Если нет планов ре-использовать код между разными проектами, то сразу же воспринимаем код как монолит и начинаем пилить дедовские сервисы/менджеры которые координируют взаимодействия между нодами (ой, снова контроллеры и модели)
>>1065925 Шина это pipeline (поток, который получает и доставляет, работает с порядком и прочим), а тут сервис, который отвечает за ХП. Ты можешь потерять хп, ты можешь восполнить, у тебя может быть отравление или от еды постепенное восполнение.
Суть в том, что когда тебе нужно разобраться как работает та или иная сложная система, ты не распутываешь вереницу событий бегая от сигнала к сигналу у всех нод, а просто заходишь в менеджер и смотришь основную бизнес логику (и упрощенное api).
>>1065927 > ты не распутываешь вереницу событий бегая от сигнала к сигналу у всех нод, а просто заходишь в менеджер и смотришь основную бизнес логику Ну да, так я и делаю. Если есть шина событий сигналов, я просто говорю ей > йоба наносит удар по площади, по координатам х,у, диаметр n Подключённые к шине агенты, которые могут получить, подписаны на этот сигнал. Получают.
Не надо ничего распутывать. Всё предельно просто и понятно. Не понимаю, о какой лапше тут полтреда уже говорят.
>>1065931 >Подключённые к шине агенты, которые могут получить, подписаны на этот сигнал. Получают. Веселье начинается, когда цепочка сигналов почему-то то идет то не идёт, то сигнал возникает, то не возникает. Любой отрыв от стека невалидированных данных и их перенос в другое место - это геморрой, при чем если сигнал можно послать несколькими способами из разных мест по разным причинам - геморрой начинает расти в монстра, который не будет давать уснуть. Я уже писал выше, eda, observer, у них у всех одна проблема - они требуют такого же пристального внимания, как сишные сырые указатели. А желательно всё обмазать валидациями, гарантиями, всем чем себе может позволить обмазываться бэкендер но не геймдевелопер. А иначе - этот пулемет у ноги только и готов будет ждать когда кодер на секунду расслабится и допустит ошибку. И пощады(нормального стека в логе) не жди.
>>1065931 Ну тут тебе и шина не нужна. У тебя есть какие-то гига агенты которые отвечают за все. Люди не впихивают все в одно место (UI, юнита, разрушаемость, пасфаендеры, карту итд).
1) Сигнал урон 2) Объект уничтожен: сигнал для пересчёта кэша пасфаендера 3) Измените кэша пасфаендера: сигнал ВСЕМ у кого сейчас есть расчет пасфаендера - сбросить и пересчитать пути занова.
И БАБАХА!!! (не только на экране) у тебя 10.000 юнитов в текущую секунду делают запрос поиска пути, кругом кровь, сопли, пропуки!!! ГОДОТИЩЕ ПРЕКРАТИ!!! ВСЕ УХОЖУ НА УРИНУ!!
Как об этом узнать? Как оптимизировать? Мог бы сервис по тикам размазать вычисления? Отложить? Мог бы решить по зонам кому делать перерасчет? Конечно мог. Но у вы у тебя лапки шина.
>>1065835 >Гарантия доставки... хранение событий... >>1065885 >Нет никакой шины или сервиса >>1065901 >называть коллбек обертку - EDA не стоит >пилить дедовские сервисы/менджеры >>1065927 >поток, который получает и доставляет Я понял, из-за чего у нас в треде произошло недопонимание: существует т.н. Message-Driven Architecture (MDA), которая отличается от Event-Driven Architecture (EDA) существованием специального "почтового сервиса", который асинхронно передаёт "почтовые конверты" от конкретного отправителя конкретному получателю, гарантируя доставку и обработку, даже получатель или канал связи нестабилен (высокий пинг, плохая/перегруженная сеть и т.п.). Организовывать MDA в пределах одного приложения на одном компьютере имеет смысл исключительно в рамках событий ОС, как в случае с InputEvent в Godot. В то время как система сигналов в Godot - это кристально чистая EDA, а не MDA. Сигналы обрабатываются мгновенно, отвязывая отправителей и получателей, но их обработка не гарантированна, зато их можно наращивать динамически и легко менять по ходу эволюции проекта. В данном случае EDA - единственное разумное решение. MDA больше подходит для веб-сервисов всяких, ну, скажем, отдельные сервисы ММОРПГ (авторизация, новости, чат, торговля, локации, ивенты и т.д. в зависимости от систем конкретной игры) наверняка должны полагаться на MDA из-за того, что они могут работать на отдельных физических серверах и не всегда доступны друг другу.
Ещё раз: EDA - это EDA, а не MDA. MDA сложна и требовательна, EDA лёгкая и гибкая. У EDA есть проблемы, если ты обвязываешься огромным числом событий и обработчиков на одном уровне абстракции (внутри одной сцены), но преимущества EDA перекрывают этот недостаток, да и он не является особенным для неё (это то же самое, как 100500 функций в одном файле, как 9000 строк в одной функции, как множество ответственностей у одного God Object и так далее - все эти проблемы решаются рациональной декомпозицией).
>>1065935 >когда цепочка сигналов почему-то то идет то не идёт Ты выдумываешь проблемы на ровном месте. Отлаженный компонент так вести себя не будет. >геморрой начинает расти в монстра Распили его на органы декомпозицией. Отладь каждый орган по отдельности. Собери обратно.
>>1065937 >Мог бы сервис по тикам размазать >Но у вы у тебя лапки шина. А в чём проблема-то, лол. Делаешь так: >EventBus.broadcast(signal_name: StringName) Под капотом спрятано что-то вроде: >func broadcast(signal_name: StringName) -> void: >_ broadcast_queue.append(signal_name, receivers[signal_name]) >func _physics_process(_delta: float) -> void: >_ if broadcast_queue... # блаблабла Впрочем, это будет уже ближе к MDA, чем к чистой EDA.
Но вообще, >Объект уничтожен: сигнал для пересчёта >Измените кэша пасфаендера: сигнал ВСЕМ Ты когда в магазин у дома идёшь и кто-то в 10 километрах от тебя ВНЕЗАПНО сбивает маленький заборчик вокруг газона тоже РЕЗКО начинаешь обновлять карту города в своей голове и строить новый маршрут к магазину, который у тебя уже прямо перед носом? Даже если на твой путь этот заборчик как-то может повлиять, будет намного проще пройти по старому пути и, если ты по какой-то причине не достиг цели, развернуться и попробовать другой путь. Кэш тебе нужен специально для этого - чтобы не парить мозги построением пути из-за каждого пука на карте.
>>1065958 > будет намного проще пройти по старому пути Что значит по старому пути? У тебя данные не валидны уже. Старого пути больше нет. Заборчик/осколок/яма, юнит просто заколбасит об коллайдер. Или проверять каждый шаг на заборчик? Тогда зачем нам поиск пути. Вот если бы ты игры писал, мы бы обсудили.
Насшет шины. Как только ты начинаешь бизнес-логику в шину совать, тогда приходит тимлид и дилдаком тебя бьет по голове. Больно, очень, отучаешься быстро.
>>1065958 >>1065968 Кто не понял, суть примера в том, чтобы показать что ивенты не детерминированы и могу вызвать неявное (и даже каскадное) поведение, или наоборот по фазе луны отрабатывать не всегда (и даже не узнаешь что у тебя вообще есть проблема и где ее искать). Если у тебя игра по сложно три в ряд, то вообще пофиг, делай как нравится, пока рогом не упрешься в проблему.
Шина нужна, чтобы объединить разные независимые системы. Если у тебя монолит, так радуйся этому (у шины много проблем).
>>1065958 > Впрочем, это будет уже ближе к MDA, чем к чистой EDA. > Организовывать MDA в пределах одного приложения на одном компьютере имеет смысл исключительно в рамках событий ОС, как в случае с InputEvent в Godot Воот. В предыдущих тредах обсуждали, как сделать шину ивентов поверх Input. Вот под капот можно запихнуть кастомный инпут-ивент.
>>1065968 >У тебя данные не валидны уже. Как ты можешь сломать Vector2/Vector3? >Или проверять каждый шаг на заборчик? А ты предлагаешь NPC вслепую двигать? >Тогда зачем нам поиск пути. Чтоб прикинуть маршрут(ы) до цели.
>>1065969 >ивенты не детерминированы Нет, в Godot с ними всё в порядке. >Если у тебя монолит Что в твоём понимании "монолит"?
>>1065987 >какие ты игры разрабатываешь В треде несколько человек вообще-то.
>>1066015 Шина никогда не работает нормально, если она не обеспечена средствами устойчивости. Сама идея о том что на твое событие могут реагировать а могут не реагировать те для кого оно предназначено - ломает детерминизм поведения, а в рамках приложения появляется генератор хаоса, который работает только если хорошо молишься духу машины. Если уж так хочется слабой связности - лучше ecs или любой другой вид компонентов/композитов. В идеале - события не должны вылазить за пределы инпута пользователя и за пределы rpc, не иметь в рамках 1 события больше 1 отправителя и 1 получателя, тогда хаоса никогда не случится. Если общение между системами сводить к посылке через шину из точки а в точку б сообщений отвечающих правилу выше и имеющую гарантию доставки - без вопросов, такая шина приемлема, просто как средство дробления и связывания систем(но компоненты все равно лучше)
>>1066015 Там был пример каскада неконтролируемого кода, чел написал типа урон по площади, я вот и адаптировал пример. Мы не решали там проблемы поиска пути, это просто был пример.
Типа - пишешь себе ивентики, пишешь, в ус не дуешь, а потом бабаха какая-то случается, да еще циклическая и потом разбери как онот там все прыгает.
По поиску пути (раз затронули). Регионы нужны когда у тебя оч большая динамичная карта (много точек, тайтлов). Астар сходит с ума когда много тайлов (больше 50-80К) со сложной открытой местностью и с весом плиток. В расчет длинного пути может достигать 75% времени, как от полного прохождения по всем тайтлам.
Почему-то многие думаю, если лабиринты, раз человеку сложно, то и астару будет сложно, на самом деле нет, ему будет легче (если специально не мудрить), игровые РПГ уровни для астара наоборот облегчение.
Если у тебя 10к юнитов, ты вообще регионы не трогаешь там решается по другому (да, по массовому поиску, вроде ты это и написал).
>>1066017 >ломает детерминизм поведения Не используй слов, значения которых не знаешь, чел. Код либо реагирует на эвент, либо не реагирует, и любой из этих вариантов поведения "детерминирован" и контролируется лично тобой, а не магией из космоса. Если же ты имел в виду, что хочешь использовать эвент, чтобы приказать другому коду что-то делать, то это просто использование подхода не по назначению, тут не эвенты нужны, а команды или просто прямой вызов этого кода, и ничто тебе не мешает это совмещать с эвентами.
>>1066032 >Не используй слов, значения которых не знаешь, чел. Скорее ты не понимаешь характер детерминизма о котором я написал. >Код либо реагирует на эвент, либо не реагирует, и любой из этих вариантов поведения "детерминирован" Нет, потому что у тебя связующее звено + множество получателей и отправителей это каскадный генератор хаоса, который детерминирован разве что в модульном тестировании >Если же ты имел в виду, что хочешь использовать эвент, чтобы приказать другому коду что-то делать, то это просто использование подхода не по назначению, тут не эвенты нужны, а команды или просто прямой вызов этого кода Ты скозал? Вызов напрямую может быть невозможен по ряду причин, например мне нужно накопиться или подружить мои приказы с активным состоянием другой системы, не вмешиваясь в ее работу, собственно для этого шина нужна при обмене информацией система<->система. >ничто тебе не мешает это совмещать с эвентами. Ну я и внедряю эвенты только в вышеописанных случаях, например клиент с сервером у меня общаются через шину (а сервер роллбечит но это уже совсем другая история), все остальное - это задел на геморрой, особенно если все взамодействие бизнеслогики оборачивать в это говнецо
>>1066036 >ты не понимаешь характер детерминизма о котором я написал. То, о чем ты написал, не имеет ни малейшего отношения к не-детерминизму, это просто нытье про "сложна, многа эвентов, нипанимаю". Хоть там десять миллиардов эвентов, спавнящях друг друга, система все равно при одном и том же инпуте окажется в одинаковом конечном стейте, т.е она детерминирована. >Вызов напрямую может быть невозможен по ряду причин Ну так используй команду или другой подобный паттерн. Эвенты это просто механизм для объявления "со мной произошла вот такая хуйня", там не должно быть ни слова про то, кто и что обязан с этой хуйней делать, ты буквально пытаешься использовать молоток для закручивания шурупов и удивляешься, хули он такой плохой.
>>1066043 Он нихуя не поймёт. Я ему уже джва треда пытаюсь то же самое обьяснять. Он себе навыдумывал какойто хуйни про "хардовые сигналы" и лепечет почём зря.
>>1066045 Мы два разных анона. Он видимо тоже нахлебался в бэке. В реале eventbus это костыль над изолированными системами. И когда ты приходишь в геймдев и тут местные дизайнеры и вайб-кодеры говорят - шина это будущее, шина наше все, ты ощущаешь фрустрацию и боль.
Но на самом деле тут даже не понимают что такое eventbus и лепят просто общий менеджер над сигнали, думая что это та самая шина (нет).
Если 20 лет назад на форумах были ники и за ламерство можно было поймать, то тут вообще безумие какое-то. Он отмоется и завтра будет опять сидеть самоутверждаться через гугл/ИИ. Какой смысл?
>>1066048 Так ото надо игоры делать, а не похваляться своими достижениями (никому не интересными) бесконечно в треде. Стоит на полчаса отвернуться, уже 333 поста насрали ни о чём, шина-хуишина, навигация-нахуяция, чанки-хуянки. Игоры где?
>>1066052 >субшота А я по субботам не выкладываю. Проанализировал статы своих и чужих постов - в субшоту они дают охват хуже, чем в любой другой день, задевая только индидев баббл. Будто кто-то когда-то подумал "вот бы загнать весь индиспам в один день и под один тег, чтобы удобно их блокнуть всех разом".
>>1066059 У них форма прокрастинации. Как снова и снова ждать новую версию нового софта, так и тут, бесконечно код вылизывать-переписывать, чтобы по факту ничего не сделать.
За этот тред я больше всего проиграл с маньки, которая трясется что его код декомпилирют и спиздят. Тем временем в стиме 50% игр 2025 года имеют меньше 10 отзывов. И это игры, которые были доведены до стим-релиза, куда свою игру не каждый доведет. Всем настолько похуй, что выкладывай они эти игры на гитхаб со всем исходниками, всем было бы все так же похуй.
Но уж его-то сырой код несуществующей игры вторичной идеи сразу же всем понадобится.
>>1066064 >За этот тред я больше всего проиграл с маньки, которая трясется что его код декомпилирют и спиздят. Тем временем в стиме 50% игр 2025 года имеют меньше 10 отзывов.
У меня был случай оч давно, я был маленьким сайтиком и запили очень интересную фишку. Крупный сайт слямзил эту идею и монетизировал. Самое смешное, через несколько лет мне писали, что я украл идею у того сайта.
Нечто похожее было с 3D принтерами, люди выкладывали алгоритмы в опенсорс и ушлые (не буду говорить откуда) патентовали их алгоритмы и потом судились (попросту отбирали теху).
Понятно что твой платформер или новвела никому не всралась, но для индюшника есть большой шанс что его уникальный геймплей уведут быстрее чем он отобьет слот. Есть достаточно прошаренные, которые могут увидеть перспективу того или иного геймплея.
Правда зачастую быстрее повторить самому, чем разобраться в говнокоде чужого.
>>1066086 >уникальный геймплей Геймплей, а не код. Смекаешь? >>1066089 Олсо, опубликованное на гитхабе считается опубликованным, так что если кто-то полезет с этим в стим, то ему можно смело насовать копирайтных хуёв.
>>1066017 >>1066029 >чел написал типа урон по площади if node.has_method("deal_damage"): node.deal_damage(amount) Для ЛЮБОГО урона. Весь спор из-за того, что кто-то тут пытается использовать шину событий не по назначению. Она не для того, чтобы вешать на неё событие, зависящее от события, зависящего от события. Вообще так делать не надо, шина там или прямые вызовы (а шина в такой ситуации даёт лишь ненужную прослойку и раздувает стек). Такие системы в принципе трудно контролировать. Нельзя их назвать не детерминированными, конечно, но баги там искать заебёшься. А они точно будут, если мозгов хватило нагородить такое.
>>1066092 >Геймплей, а не код. Смекаешь? За геймплеем может лежать сложный математический алгоритм в 100-200 строчек, на исследование которого ушло не один месяц.
>>1066092 >Олсо, опубликованное на гитхабе считается опубликованным, так что если кто-то полезет с этим в стим, то ему можно смело насовать копирайтных хуёв. Останется только приехать в ту страну и нанять юристов. Потому что без решения суда контора ничем не обязана. Тем более разбираться что этот билд из сорцев гитхаба (а если ассеты изменены, то вообще можно идти лесом).
>>1066015>>1066017>>1066029>>1066036>>1066048 >...шина то, шина сё, шина пятое, шина десятое... Да кто это ваша "шина" нахрен? Я знаю только "шину данных" на материнской плате. Суть шины данных в том, чтобы передавать данные множеству устройств через узкое горлышко - всего лишь несколько дорожек на плате благодаря шине способны передавать данные десяткам независимых устройств благодаря специальным кодам, которые как-то помечают отправителя и получателя. Это является узким местом архитектуры фон Неймана и в будущем, возможно, мы будем вынуждены перейти к компьютерам, у которых ячейки памяти являются одновременно ядрами процессора.
Но всё это не имеет никакого отношения к программному коду, потому что с точки зрения кода нам доступна любая ячейка памяти в любой момент времени без каких-либо "шин". Да. ОС даёт нашей программе участок памяти и разрешает творить любую дичь, лишь бы мы не залезали в защищённые участки памяти (память других программ, драйверов, ядра ОС и т.д.). Если бы мы запускали игру без ОС (т.е. в роли ОС), мы могли бы иметь доступ вообще ко всей физической памяти компьютера одновременно, из любого места в программе.
Но насколько свободный доступ к памяти вреден, потому что человеческий мозг не способен анализировать поведение программы, в которой миллион ячеек памяти меняет значение в произвольном порядке - компьютер выполнить сможет, а человек понять - нет. Поэтому программисты (скорее, учёные-информатики) ещё в середине прошлого века начали выдумывать разные вымышленные конструкции, которые призваны ограничить доступ кода к данным. Самое базовое и часто встречающееся ограничение - это деление кода на процедуры или функции: внутри могут быть выделены участки памяти, которые недоступны для внешнего кода. ООП делит память на кусочки с ограниченной видимостью так, чтобы одна коллекция из функций имела доступ только к своей области памяти. И так далее, тысячи выдумок было.
Я это к чему: если эта ваша "шина" является своего рода "глобальной переменной" (даёт свободный доступ кому угодно откуда угодно) - то нахрен эту конструкцию, она буквально откатывает научно-технический прогресс в информатике на 70 лет назад. Зачем вам эта глобальная сущность, которая буквально сносит аккуратно выстроенные границы в вашей программе, нарушая чётко отлаженную структуру и ухудшая понимание кода вашим мозгом?
Тем не менее, никакая "шина" не имеет отношения к "событийной ориентированности", с которой начался этот спор. События не являются глобальной сущностью сами по себе - вы их своими руками делаете глобальными, если вы этого хотите. Но вы этого не должны хотеть, потому что если хотите, вы ломаете чёткую структуру и создаёте непонятную лапшу в коде.
Ещё раз: события существуют независимо от какой-либо "шины", это разные концепции и не нужно их спутывать в одну. Событие - это уведомление о том, что что-то произошло. Событие позволяет узнать о чём-то, не притрагиваясь к деталям реализации, не трогая скрытые где-то локальные переменные. Событие улучшает структуру программы, потому что ограничивает доступ произвольного кода к произвольным данным. Другой вопрос, как их использовать?
Об этом уже много раз писали: "call down, signal up" - обращайтесь напрямую к подчинённым компонентам (нодам и ресурсам), но сообщайте об изменениях своим предкам только через создание события (сигнала). Вас не должно волновать, чем там занимается предок, который создал вас и/или управляет вами. Его может вообще не существовать - но вас это не касается. Сообщаете о событиях внутри компонента наружу и всё - никаких "шин" никогда не требуется. Управление компонентами со стороны владельца - это отдельная тема и событий она тоже не касается. Владелец (предок) может нажимать любые кнопки, рычаги, тумблеры и т.д., это его дело. Дело компонента - корректно отреагировать на эти нажатия и сообщить о событиях. Всё.
>>1066138 > Ещё раз: события существуют независимо от какой-либо "шины", это разные концепции и не нужно их спутывать в одну. Событие - это уведомление о том, что что-то произошло. Уведомление кого, кем, через что? Вот тут-то ты и пойман за хуй, как дешёвка. Для передачи взаимодействий нужна среда. Эфир. И этим эфиром являются всевозможные шины данных.
>>1066137 Сколько своих протыков ты ещё собираешься перебирать? Я никого не протыкал, так что на меня ты не выйдешь. Или ты только что проткнулся и придумаешь мне личную кличку за протыкание?
>>1066139 У тебя нормальные контраргументы закончились что ли? >Уведомление кого, кем, через что? "Родителей" (parent) "детьми" (child) через "сигналы" (signal) Godot. Понял? >Для передачи взаимодействий нужна среда. В Godot она реализована и доступна из коробки, ничего не нужно изобретать: https://docs.godotengine.org/en/stable/getting_started/step_by_step/signals.html >И этим эфиром являются всевозможные шины данных. Не неси чепухи, "шина" - это глобальный "autoload" по мнению годотеров. Они предлагают весь проект завязывать на вот такой выстрел себе в жопу: >EventBus.something_happened.connect(_on_something_happened) >EventBus.something_happened.emit(payload) А внутри этого "EventBus" портянка на миллион строк с "signal"... И этот антипаттерн собирает кучи лайков на Reddit...
>>1066138 >call down, signal up Ну так-то у меня серьёзные вопросики к такому подходу. Потому что обычно точно известно, кто у ноды родитель; а вот кто дети - вот это хз. И приходится делать типа for child in get_children(): _ if child.has_method("my_method"): _ _ child.my_method() А ведь можно просто эмитить сигнал, а чайлд пусть сам подписывается. И наоборот, get_parent().my_method() выглядит чище, тем более что родитель гарантированно всего один, а сигналы предполагают неопределённое число подписчиков. Да и как родитель на сигнал подпишется, если он не знает, кто его дети и какие у них сигналы? И даже если тип родителя заранее не известен, проверить через has_method его одного не так накладно, как проверять топу детей.
Я вот сколько это "call down, signal up" встречаю, всегда такой: ага, ну да, наверное, что-то в этом есть. А на практике сама реальность против такого пайплайна. У меня сигналы используются чаще для общения каких-нибудь совсем уж далёких нод - например, персонажа с гуём.
Ппц шиза, дергать родителей или детей через сигналы.
Одно из преимуществ инди разработки, ты никогда не будешь сопровождать чужой говнокод. Так что вообще нет смысла спорить.
Мы пишем разные игры, у кого-то сложная механика и много кода, у кого-то платформер/FPS/беги стреляй.
Если у первого уже начинаются проблема с организаций сигналов, то второму все еще удобно и он вообще не понимает в чем у вас тут проблема. И как только у второго начнутся проблемы, он навернет управляющую конструкцию сверху и назовет ее, почему-то, Шиной тут должна быть шумная вставка мема Джона Сина.
Лучше бы AStarGrid2D для гексов сделали, чем спорили у кого шина длиннее.
>>1066164 В геймдеве они идеальны, пока не начнешь писать юнит тесты или масштабировать игру по нескольким пк никогда[/poiler]. Одна нода, это по сути синглетон в на сцене.
>>1066173 Главное авторов с европейскими именами бери. Потому что у индийцев в основном книги-справочники, а не что-то годное. Сколько раз не смотрел книги индийских авторов ни разу не попалась полезная. Может я невезучий просто..
>обычно точно известно, кто у ноды родитель Только если ты пишешь одноразовый скрипт для ноды в одной конкретной сцене. Когда ты пишешь универсальный скрипт, который будет использоваться во множестве разных сцен, ты не можешь заранее знать, где он будет использоваться - часто даже в собственном проекте, т.к. он в процессе разработки и ничего заранее не предопределено кроме смутной идеи будущей игры, но скрипты для использования в разных сценах тебе уже требуются для чего-нибудь.
>а вот кто дети - вот это хз Только если ты вставляешь детей в рантайме (во время выполнения игры) к произвольным нодам, которые в принципе не рассчитывают получить в себе в потомки какого-то подкидыша. Когда ты создаёшь конкретную сцену в десигнтайме (в визуальном редакторе Godot), ты видишь все ноды в дереве этой сцены - все их имена и классы, и можешь свободно связывать нужное с главным скриптом сцены (или даже второстепенными скриптами сцены, если они одноразовые - используются только тут). Если тебе нужно добавлять ноды в рантайме, то принимающей стороне следует объявить специальный интерфейс, который будет фильтровать то, что ей не нужно: >func add_useful_node(node: UsefulNode) -> void: >_ add_child(node) # в простейшем случае В противном случае тебе вообще не нужно как-то следить за добавлением потомков.
>И приходится делать типа >for child in get_children(): Такое случается очень редко, когда требуется работать с коллекцией однотипных нод. В актуальных версиях Godot можно объявить класс ноды в переменной-счётчике такого цикла: >for child: UsefulNode in get_children(): Тогда игра упадёт с ошибкой, если ты где-то случайно вставил сюда ноду неправильного класса.
>просто эмитить сигнал, а чайлд пусть сам подписывается На кого из всех теоретически возможных предков он подпишется? Тогда следует делать так: >if get_parent().has_signal("this"): get_parent.connect("this", _on_this). Но такой код приведёт к куче проблем, когда ты добавишь эту ноду не туда, куда следовало... >get_parent().my_method() выглядит чище Наоборот, такой код грязнее, ведь "get_parent()" не имеет конкретного имени и может быть абсолютно любой нодой из тех, что в твоём проекте объявлены (встроенные + твои личные). Если тебе очень сильно нужен такой подход "задом наперёд", то пиши примерно такой код: >var useful_parent: ParentNode >func _enter_tree() -> void: >_ useful_parent = get_parent() as ParentNode >_ assert(useful_parent, "%s placed under wrong parent. Place it under ParentNode." % name) >func _get_configuration_warnings(): >_ if not useful_parent: >_ _ return ["This node must be a child of a ParentNode or else it won't function properly."] >_ else: >_ _ return [] # всё ок, работаем Тогда ты будешь иметь в коде чёткое имя родителя и предупреждения о своей ошибке.
>на практике сама реальность против такого пайплайна В какой реальности ты находишься? Где Godot не имеет GUI и используется через CLI?
>>1066152 >никогда не будешь сопровождать чужой говнокод Ты не планируешь поддерживать свою игру спустя год? А если она будет успешной? Многие успешные инди-игры поддерживаются не то, что год, а десятки лет. И под поддержкой игроки подразумевают добавление новых фич и исправление багов, а не создание новых багов...
>Если у первого уже начинаются проблема с организаций сигналов >управляющую конструкцию сверху и назовет ее, почему-то, Шиной А можно изначально нормально делать и никаких проблем не будет.
>>1066164 >А срачи про синглтоны уже не в моде? Не беспокойся, шина - это синглтон.
>>1066178 Как же ты дефаешь свою сигнальную лапшичную, я хуею просто. Да, да, архитектура на сигналах заебись, только из палаты не выползай больше, ну или вместе с очередной простыней пости свои лапшичные игры мимокрокодильный годотер противник сигнального говна
>>1066202 Теперь это звезда игровой ру годот сцены. Кто из вас сможет записать видео про разработку своей новой игры на Годоте с 3 плакатами своих игр на Годоте из Стима на стене за спиной? Думаю даже никто из годот гуру с уроками по Годоту на ютубе, не имеет такой возможности.
>>1066205 Зачем завидовать? Человек популяризирует годот, это же круто. А вот твой высер про зависть как раз показывает, что ты зачем-то ему завидуешь и тебе реально печёт.
>Hexes vs Squares Неожиданно, оказалось, у днд задротов целые срачи на эту тему есть. Никогда не думал что попаду к ним. Я просто хотел услышать подводные для пошаговой стратежки.
>>1066214 >в игры про животных только животные играют Так и есть. Вообще мало кто кроме животных играет в игры. Сходу даже ни одного примера не вспомню. А, нет, вспомнил. Ещё ИИ играет в игры. Он не животное.
>>1066178 >универсальный скрипт, который будет использоваться во множестве разных сцен Ну как бы да, но нет. Конечности всегда дети тела. Коллижоншейп всегда ребёнок коллижонобжекта. Но в обратную сторону это не работает: у тела детьми могут быть не только конечности, но ещё джоинты, абилки, инвентарь и анимация. У коллижонобжекта зачастую ребёнком может быть спрайт, а ещё какая-нибудь партикля и звук. Конечность чисто в теории могла бы быть отдельным переиспользуемым объектом, но на практике им не является. А вот тело иногда должно сообщать конечностям, например, что оно умерло, и пора бы обрести физику, чтобы превратиться в рэгдолл. Физический объект сообщает, что в него попала пуля; тогда партикля плюётся частичками, звук проигрывается, а спрайт ничего не делает; но их всех может и не быть, ничего страшного.
Универсализация и разбиение на отдельные объекты, каждый из которых можно протестировать как отдельную сцену, это отличная фича. Но не следует слишком упарываться. Некоторые вещи просто не имеют смысла по отдельности.
>Когда ты создаёшь конкретную сцену в десигнтайме (в визуальном редакторе Godot), ты видишь все ноды в дереве этой сцены - все их имена и классы, и можешь свободно связывать нужное с главным скриптом сцены А если главный скрипт этой сцены у меня универсальный и переиспользуемый? И не знает, какие конкретно ноды будут туда добавлены?
>>1066218 Вообще странно, обычно про годот говорят, что он ближе к 2D, но инструментов для гексов не очень (хотя гексы такая же база как квадраты). Но хотя бы ручками в TileMapLayer можно будет "порисовать" (вроде).
PS я еще не решился с конечным геймплеем. Гексы хорошо демонстрируют местность и цива-лайк города, но данжи или строения (где есть прямые) - не очень (пик2 с половинными гексами).
>>1066236 >>1066237 Хотя это глина (как только юнит остановится), мы же не ДнД задроты, лучше придерживаться симметрии (кто вообще делает данжи на гексах??), ссори за флуд.
>Как правильно делать Честно говоря, мне похуй как правильно. Мне главное чтобы работало. Игра уже через две недели будет релизнута. Ноль багов, ноль проблем. Захардкодил локали через файлы .tres а не годотню. Типо Scenario_ru Scanerio_en
Ты наверняка больше меня понимаешь в коде, я не спорю, но мне на чистоту кода и прочие вещи, честно сказать, безразлично. Игра работает? Да. Игра вышла в стиме? Да. Че там под капотом ебать никого не должно. Запускается даже на макбуках 2012 года. А большего мне и не надо.
>>1066252 В общем, кто такой же нубас как я, лечиться это только добавлением толщины +2 пикселя по Y (128х130). Проблема сглаживания (полупрозрачные пиксели, которые еще снизу усиливают толщину полупрозрачности). Всем спасибо, вы лучшие 🫶😍😻
>>1066218 >>1066258 А теперь вопрос, нужны ли мне равносторонние шестиугольники? Мне чет понравились блоки 128х128 (центр всегда целочисленный, отступы тоже). А равносторонние смотрятся как в старых Героях.
>>1066262 Ладно, там слишком много готовых вычислений, чтобы я еще математику потом дрочил. хотя мне не особо много надо. Как вариант потом попробовать слегка сдвинуть угл обзора (в 3д унести, хз)
Тут с физикой немножко играюсь. Попробовал физику Rapier ещё, но так и не смог добиться аналогичного поведения. Тамошние джоинты почему-то не убирали коллизию между колёсами и тележкой. Ну и хрен с ним, я в этом проекте вряд ли вылезу за ограничения годотовской физики.
Анонче, вопрос на подумать. У реальных моторов есть две важные характеристики - скорость и крутящий момент. Допустим, тележка очень тяжёлая, и слабый мотор не сможет её сдвинуть, зато он умеет разгоняться до больших скоростей, если тележка лёгкая; и наоборот, сильный мотор не умеет быстро разгоняться, зато сдвинет даже тяжёлую тележку. Но у пинджоинтов есть только один параметр - motor_target_velocity. Как сымитировать разные виды моторов? Я чота пока ничего путного не придумал.
>>1066265 >Тамошние джоинты почему-то не убирали коллизию между колёсами и тележкой Неправильно слои настроил? Земля 1 маска 1 Тележка 2 маска 1 Колесо 3 маска 1 >Как сымитировать разные виды моторов? Я чота пока ничего путного не придумал. Всего навсего спросить нейродебила def calculate_acceleration(mass, torque, engine_power): """ mass: вес объекта torque: базовый крутящий момент engine_power: сила двигателя от 0.0 до 1.0 """
# Константы баланса K1_TORQUE_BONUS = 3.0 # Насколько резвее слабый мотор (множитель) K2_MASS_DRAG = 0.005 # Насколько сильно масса убивает слабый мотор
# 1. Рассчитываем множитель момента # Чем меньше Power, тем больше бонус к моменту torque_multiplier = 1 + (K1_TORQUE_BONUS (1.0 - engine_power))
# 2. Рассчитываем "чистую" тягу по Ньютону (F = ma -> a = F/m) base_acceleration = (torque torque_multiplier) / mass
# 3. Рассчитываем штраф за массу для слабых двигателей # Чем меньше Power, тем сильнее влияет масса mass_penalty = K2_MASS_DRAG mass ((1.0 - engine_power) 2)
>>1066267 Портянки кода в тред не выкладываем. Юзаем сервисы вставки кода. Потому что знак умножения - часть разметки, а табуляция вырезается. Тег [code] администрация отказывается добавлять несмотря на все просьбы.
>>1065671 Окей, разобрался. Видимо проблема была в самой модели генерации картинок, SDXL и его производные плохо понимают openpose, перешел на Qwen и все заработало, да еще и качество деталей намного выше. Таким образом фундамент пайплайна генерации ассетов для годот завершен, скины для персонажа можно будет генерить инпейном. Даже если stablegen в блендер заглючит на генерации текстур, картинки настолько качественные что можно разукрашивать модель прямо с них.
Теперь пойду смотреть ассеты города чтобы не пришлось улицы и столбы самому моделить.
>>1066267 Надо законодательно запретить пользоваться нейронками людям с айсикью меньше единицы. 1. Какие нахуй слои, когда речь про пикрил галочку? А на сложные рэгдоллы никаких слоёв не напасёшься. 2. Нейронка выдала какие-то свои вольные фантазии на тему, не врубившись в вопрос. Потому что ты тоже не врубился.
>>1066291 >Спрашивает помощь >Кроет хуями в ответ, потому что слабо описал вопрос >Все еще ждет помощи Иди нахуй кстати >Какие нахуй слои, когда речь про пикрил галочку? Так бы сразу >Нейронка выдала какие-то свои вольные фантазии на тему, не врубившись в вопрос. Там формула зависимости мощность мотора<->крутящий момент<->масса
>>1066265 >У реальных моторов есть две важные характеристики Если я правильно понимаю, это характеристики не у самого двигателя, а у коробки передач, которую можно прикрутить к любой крутящей штуке, включая человека (на современных велосипедах куча шестерёнок возле педалей и на заднем колесе - это как раз оно). Когда ты передаёшь вращение с большой шестерни на маленькую, маленькая начинает очень быстро вращаться, но легко останавливается от любого сопротивления и останавливает большую. Если ты передаёшь с маленькой на большую, то большая вращается медленно, но при этом преодолевает большее сопротивление вращению. То есть мотор вращает свою шестерню с одинаковой скоростью и одинаковым усилием, но в зависимости от второй шестерни будет увеличиваться скорость и уменьшаться сила или увеличиваться сила и уменьшаться скорость.
Исходя из этой логики, можно сделать симуляцию по формулам, но...
...но проблема в том, что ты хочешь использовать нестабильный физический движок реального времени, в котором куча упрощений и заплаток-костылей для того, чтобы это хоть немного работало. Полагаться на Godot Physics2D для чего-то близкого к реальности не стоит. Кроме свойств двигателя и коробки передач тебя должно волновать сцепление с поверхностью (сила трения), а в этом любой игровой физический движок сильно тупит.
Вообще, зачем тебе это нужно? Для "гоночной" игры с видом сбоку лучше не возиться с физикой и тем более не использовать никакие Joint'ы, а использовать CharacterBody2D и кучу рейкастов - тогда и двигатель симулировать сможешь независимо от любой тряски у физического движка. Если же ты хочешь сделать что-то вроде "Bad Piggies", то я сильно сомневаюсь, что у них там настолько продвинутая симуляция реальных движков. Скорее наоборот, там сделано всё примитивно-мультяшно, лишь бы не тормозило на мобилках. Нужно выбирать инструменты под конкретную задачу, а не подстраивать задачу под инструменты.
>>1066224 >Коллижоншейп всегда ребёнок коллижонобжекта Это одно из немногих исключений из правила, и специально для него в API есть это: >func _get_configuration_warnings(): Чтобы ньюфаги-геймдизайнеры не засовывали эту ноду туда, куда ей не надо. Сам должен понимать, это - костыль, и база - это наоборот (родитель -> потомки).
>у тела детьми могут быть не только конечности Все эти другие дети определяются главной нодой сцены лишь при необходимости. Например, если ты ленточку прицепил, но она "просто есть" - о ней не нужно знать.
>сообщать конечностям, например, что оно умерло, и пора бы обрести физику Отделение от тела - это обязанность тела, а не конечности. Например, тело: >func rest_in_pieces(): # прямой запрос извне или реакция на критический урон >_ for body_part: BodyPart in body_parts: # перебираем известные нам части тела >_ _ body_part.reparent(get_parent()) # отправляем части в свободный полёт Сама конечность может проверить, кем является её предок при отделении: >func _enter_tree(): >_ if get_parent() is not Body # если "рабочее" тело отсутствует... >_ _ var body := RigidBody3D.new() # ...тогда делаем себе пустышку >_ _ add_sibling(body) # сажаем пустышку в дерево рядом с нами... >_ _ body.global_transform = global_transform # ...и с той же позицией >_ _ reparent(body) # насаживаемся на твёрдое тело и засыпаем После чего конечность больше ничего не делает со своим предком. А если нужно отделить только одну повреждённую конечность, тогда: >func _on_body_part_took_critical_damage(body_part: BodyPart): >_ body_part.reparent(get_parent()) # дальше это не наша забота Естественно, что это делает тело (см. пикрил), а не сама конечность.
>Физический объект сообщает, что в него попала пуля Не нужно ему никому об этом сообщать, если это не RTSина какая... >тогда партикля плюётся частичками, звук проигрывается К ним тело обращается напрямую через вызовы их методов по имени. >но их всех может и не быть, ничего страшного Как это - ничего? У тебя тело сломалось, а тебе ничего страшного? "Вылетание частиц" и "проигрывание звуков" - это часть свойств тела.
>Некоторые вещи просто не имеют смысла по отдельности. Именно поэтому тело не имеет смысла без "частей тела", "частиц", "звуков" и т.д. Именно поэтому тело имеет прямой контроль над всеми этими компонентами. Но компоненты по-прежнему могут существовать независимо от этого тела. Ты просто делаешь сложную вещь из множества более простых вещей. Это как конструктор Лего: делаешь по частям и собираешь в целое.
>А если главный скрипт этой сцены у меня универсальный и переиспользуемый? Делаешь базовый скрипт "UniversalClass" и потом делаешь: >class_name SpecificSceneA extends UniversalClass >@export var specific_thing_a: NodeA >class_name SpecificSceneB extends UniversalClass >@export var specific_thing_b: NodeB И т.д. Это же очевидно. Это же ООП движок всё-таки.
>>1066318 >Ушестерите ваши проблемы с гексами Для передвижения юнитов (теста проходимости клетки, поиска координат, построения пути), всяких построек внутри клеточек и т.п. ты используешь обычную шестиугольную сетку. Но каждый шестиугольник можно представить как состоящий из шести треугольников, которые он использует вместе с соседями - эти треугольники используются только для размещения визуальных тайлов (земли, воды и т.п.). Нужно это для того, чтобы уменьшить количество необходимых тебе визуальных тайлов-шестиугольников для отображения изгибов ландшафта.
По сути тебе нужно всего 3 спрайта-треугольника, которые ты вращаешь, создавая свои шестиугольники: 0. Пустой треугольник (прозрачный - не используется). 1. Один краешек земли (накладывается поверх фона). 2. Два краешка земли. 3. Полностью заполненный землёй. Вращаешь с шагом 60 градусов и получаешь всё что нужно...
Хотя, для пиксель-арта может потребоваться больше спрайтов.
>>1066323 Аааа, я тут облажался с подходом: >Сама конечность может проверить, кем является её предок при отделении... >>_ if get_parent() is not Body Конечность не должна тестить предка, т.к. это завязывает её на класс предка.
Правильный код будет выглядеть примерно так - в скрипте тела: >func detach(limb: Limb) -> void: >_ var empty := RigidBody3D.new() >_ add_sibling(empty) >_ empty.global_transform = limb.global_transform >_ limb.reparent(empty) Тогда конечностям совсем не нужно будет взаимодействовать с предками. Ну и используем этот метод для последовательного разделения на части: >func rest_in_pieces(): >_ for limb in limbs: >_ _ detach(limb) >_ queue_free() Так будет лучше.
>>1066325 Мне не сильно нужно в текущем концепте, но я учту когда начну плейсхолдеры заменять.
Я бы лучше услышал как фикситься эта проблема: У гексов есть проблема сглаживания диагональной линии в местах соединения граней (я пытался насиловать png, но это выглядит как фундаментальная проблема). Пришлось увеличить края на 2 пикселя и итоге получился числовой адок для перфекциониста (как в атласе, пик3, так и в векторе)
Возможно этому есть решение, но нифига ничего не гуглится (до шейдеров мне далеко).
>>1066340 На самом деле, равносторонние гексы кривые и так, так что париться ради 2 пикселей звучит как фигня. Я вообще по итогу сетку добавил, с ней лоу-плейсхолдеры еще лучше смотреться.
>>1066252>>1066257>>1066258>>1066340 Проблема возникает из-за формата PNG, в котором прозрачные пиксели вроде бы вообще не сохраняют цветные каналы (RGB), что обеспечивает лучшее сжатие, но создаёт такие вот артефакты на текстурах. Это одна из причин, по которой многие старые и даже новые игры используют формат TGA - он хранит все 4 канала (RGBA) без потери информации. Формат простой и поддерживается Godot, но он толстый. Можешь попробовать зумеркий WEBP - он поддерживает lossless сжатие как PNG, подробностей не знаю.
От себя рекомендую просто сделать чёрную обводку вокруг каждого шестиугольника. По крайней мере сейчас твоя карта выглядит так, что ей не помешала бы видимая обводка шестиугольников - хотя бы для тестирования. Когда игрок фокусируется на одной клетке, делай обводку белой. Тогда эти "серые" переходы на границах не будут такими заметными, если они вообще будут. Сфокусируйся пока на геймплее, а уже когда будешь делать нормальную графику, тогда разберёшься с тем, как это сделать без артефактов.
>>1066314 >Если я правильно понимаю, это характеристики не у самого двигателя, а у коробки передач Не важно в данном контексте, на самом деле. Я не разделяю мотор и передачу; скорее всего, вообще будут единые мотор-колёса. И так боюсь переусложнить. >Вообще, зачем тебе это нужно? Что-то типа Вангеров, только в 2д, и игрок сам конструирует свой мехос из говна и палок. Может взять моторчик с хорошей тягой, чтобы было легче забираться в горку, а может взять более шустрый, и тогда на ровной поверхности будет быстрее. >сцепление с поверхностью (сила трения) Имеется в годотовской физике. >использовать CharacterBody2D и кучу рейкастов Заебусь реализовывать физику, тем более зависящую от кучи заменяемых деталей. >...но проблема в том, что ты хочешь использовать нестабильный физический движок реального времени, в котором куча упрощений и заплаток-костылей для того, чтобы это хоть немного работало. Вся идея вообще возникла от "у меня есть движок, в нём можно сделать штуку", а не "хочу сделать штуку, нужен движок". В конце концов, есть ещё Rapier и Box2D, если годототфизикс будет не хватать. Но пока что хватает, и надо только понять, как реализовать фичу. А у тех движков есть свои проблемы, которые к тому же не очень понятно как решать (и вообще надо ли, или это просто баги, и надо просто взять другую версию). И да, кстати: они тоже движки реального времени с кучей компромиссов.
>>1066299 >Там формула зависимости мощность мотора<->крутящий момент<->масса Хуйня твоя формула. Точнее, не твоя, а нейронки. Ты её спросил про зависимость скорости от массы, она тебе это и выдала. А проблема-то в чём: зависит оно НЕ от массы. Мотор вообще не знает ничего о массе. Он крутит колесо, а колесо как-то сопротивляется - и вот это сопротивление мотор и преодолевает. Конечно, в простейшем случае, когда машина стоит на горизонтальной твёрдой поверхности, сопротивление колеса зависит от массы; но она же может стоять на горке, может подпрыгивать, может быть плохое сцепление с поверхностью - во всех этих случаях сопротивление колеса будет уменьшаться, и для слабого мотора это даст прирост к скорости.
В общем, я пока что придумал только вот что. У мотора есть максимальная скорость и есть коэффициент мощности. Он знает текущую скорость вращения. При нулевой скорости вращения motor_target_velocity будет равно максимальной скорости умноженной на коэффициент мощности; при достижении максимальной скорости motor_target_velocity равно этой самой максимальной скорости; ну а при превышении вообще становится меньше её. Таким образом, чем меньше скорость колеса, тем шустрее мотор пытается его раскрутить. Можно ещё эту характеристику сделать нелинейной, прогоняя её через Curve2D, и тогда некоторые моторы будут особенно хороши лишь в определённом диапазоне скоростей; но я не уверен, что хочу такую глубину симуляции.
>>1066473 Толку что-то делать если ты ничего не умеешь. Ты сможешь только повторить, а сделать что-то свое уникальное и стилизованное не получится никогда.
>>1066450 Та ну, это какой то пердолинг, комменты не для этого придуманы. Обо будет отвлекать на себя внимание вместо реальной задачи, каждый рас смотря в скрипт будешь смотреть на эту радугу.
>>1066514 А в целом надо код смотреть, если не хочешь показывать то должно быть примерно так > var p: Vector2D # Точка в глобальных координатах > line2D.add_point(line2D.to_local(p))
>>1066527 В общем, кому интересно, можно пофиксить (оставив в локальном дереве) установив set_as_top_level(true) НО теперь полоска над юнитом и фиксить это только z-индексом (насколько я понял).
>>1066535 в глобальных координатах* в любом случае если line2d - дочерняя то координаты меняются Если твоя концепция предусматривает 1 путь, то на мой взгляд надо глобально хранить, если будут ещё пути то завести Node2D внутрь которых добавлять Line2D с путями для каждого
>>1066323 >Все эти другие дети определяются главной нодой сцены лишь при необходимости. Фу, брось, выкинь каку! Расширяемость через компонентный подход - вот база. Животное не должно ограничиваться капибарой, макакой и лошадью, потому что в какой-то момент может понадобиться сделать лосося и голубя, не вмешиваясь в класс животного. И такой ноде не нужно даже заводить отдельную сцену (но при желании сделать это в два клика): просто создать ноду нужного класса и накидать в неё детей. >Как это - ничего? У тебя тело сломалось, а тебе ничего страшного? Ничего не сломалось. Если у какого-то объекта нет спрайта, значит он невидимый; нет звука - беззвучный. Он не обязан иметь ничего из этого. Каждый компонент отвечает сам за свои функции; задача родителя - лишь объединить всех под общей крышей. >Делаешь базовый скрипт "UniversalClass" и потом делаешь: Фунахуй. Скрипты раздувать на каждый новый предмет, когда этот предмет можно было бы собрать просто мышкой накидав в него компоненты? Нет пути. >Отделение от тела - это обязанность тела, а не конечности. Конечности важно знать, находится она в составе анимированного тела или же болтается оторванная в виде физического объекта. А телу что? Ну, анимации могут поменяться, чтобы соответствовать; но это вообще не про конечности, а про дамаг, и тут информация "я четырёхногое" или "я гуманоид" никак не связана с наличием или отсутствием конечностей. Зачем вообще телу знать, какие у него есть части? Что изменилось для твоего пикрил краба? У него даже анимация ходьбы осталась прежняя.
Я, кажется, понял, откуда у этого CDSU ноги растут. Когда у тебя не ноды в дереве, но всё ещё есть чёткая иерархия, где одни классы являются полями других. На плюсах, например: class Hui { //blablabla }; class Man { public: Hui hui; }; Вот тут вообще без вопросов - действительно из объекта класса Hui достучаться до содержащего его объекта класса Man можно только либо сигналами (если существуют в используемом фреймворке, например они есть qt), либо коллбэками; на те и другие Man всё равно должен сначала подписаться. Но у Годота же мать его дерево нод! Оно осуществляет менеджмент иерархии, и все ноды равноправны. Иерархия здесь - условность для разных удобств, типа автоматической трансформации и гарантированного порядка вызовов. В дереве для каждой нода доступна каждая нода, что означает - ВСЕ вызовы от ноды к ноде проходят через дерево (оно тут выступает шиной, если угодно, ну или менеджером, ну или СИНГЛТОНОМ), и нет никакой принципиальной разницы между вызовом вверх, вниз или горизонтально. Все get_node, get_parent, get_child - это всё равно обращения к дереву. Так смысл тогда этих брачных игр?
>>1066531 Жора там для отладки поиска пути. Это будет смесь цивы-лайк с моей больной фантазией частично натянуть hoi4 (где юнит в гексе - это одна дивизия).
>>1066535 >>1066537 Там по коду и так глобальные координаты. Такое ощущение, что там в какой-то момент не происходит перерисовки и все линии смещаются с движением юнита, а потом перерисовка случается и происходит дерганье.
>>1066541 Line2D считает добавленные в себя точки в локальных координатах, это необходимо, например ты нарисовал треугольник и переносишь line2D в другое место, если координаты локальные - треугольник переносится, если глобальные - стоит на месте, у тебя персонаж двигается, соответственно линия двигается вместе с ним, это дуобно если ты рисуешь например лазерный указатель в координаты мыши, но для пути надо делать по другому
>>1066542 Я не соображу, но т.к. это происходит для всех линий это может быть 1) настройки проекта - Окно - Scale стоит Integer а не Fractional 2) Твоя ошибка в округлении
>>1066558 Вроде понял (или нужно еще накатить - чаю :)).
1) обновляешь поинты из глобального в локальные двигаешь - поинты смешаются по каким-то рандомным числам --рисовка кадра с битыми поинтами (пока еще не дернуло)-- обновляешь поинты из глобального в локальные двигаешь - поинты смешаются по каким-то рандомным числам --рисовка кадра с битыми поинтами (тут уже дергает)--
2) двигаешь все. обновляешь поинты из глобального в локальные --рисовка кадра с точными поинтами-- двигаешь все (поинты изменились/испортились). обновляешь поинты из глобального в локальные --рисовка кадра с точными поинтами--
>>1066559 Отсюда следует - что все что связанно с координатами для отрисовки, нужно всегда делать в конце всяких преобразований. наверное это где-то прописано кровью, но кто читает полностью документацию?
>>1066550 А где речь про перебор вообще? Наоборот же: мы детей НЕ перебираем, а позволяем им самим подписаться на сигнал, если хотят. А родитель всего один, к нему можно и напрямую обратиться. Можно даже как к уточке, через has_method и has_signal, и это даже не будет накладно, потому что он один и только один. Конечно, есть ситуации, когда родителя вообще нет, но в этом случае не будет также вызвано и большинство коллбэков, в которых мы что-либо делаем, типа _process. Ну разве что _ready вызывается до появления родителя, но про это мы все в курсе и там его не трогаем. А кто полезет во все остальные коллбэки не разобравшись с внутренним устройством движка, тот ССЗБ: во все места, не описанные в видеотуторах для чайников, грязными ручонками можно лезть только когда уже не чайник и понимаешь что делаешь.
>>1066560 Я не очень понимаю зачем ты каждый кадр перерисовываешь путь. 1) Твой персонаж получает команду на движение из гекса А в кекс Б. 2) Ты вызываешь поискпути из А в Б 3) Создаёшь линии согласно найденного пути добавлением точек в Line2D 4) Персонаж дошел до конца - очищаешь путь
Твоя функция __debug_drawPath должна контролировать только исполнение пунктов 3 и 4, её вообще можно заменить на bool переменную или сделать универсальную функцию которая сама создаст Line2D, добавит точки и как-то узнает о конце пути чтобы удалить Line2D из дерева.
И кстати про >>1066518 Проблема в global_position, кака я понимаю это позиция персонажа, а её нужно сконвертировать в координаты центра хекса примерно так ->в локальные координаты для карты -> в локальные координаты карты т.е. гекса теперь обратно -> гекс в локальные координаты карты -> локальные координаты в глобальные так получится центр гекса > map.to_global(map.map_to_local(map.local_to_map(map.to_local(global_position))))
Удобно сделать 2 функции для конвертации: > func vec2hex(p_vec: Vector2, p_map: TileMapLayer)-> Vector2i:return p_map.local_to_map(p_map.to_local(p_vec)) > func hex2vec(p_hex: Vector2i, p_map: TileMapLayer)-> Vector2:return p_map.to_global(p_map.map_to_local(p_hex))
тогда можно сделать: > hex2vec(vec2hex(global_position, map), map)
>>1066563 > мы детей НЕ перебираем Когда ты вызываешь методы дерева - дерево перебирает ноды, чтобы этот метод выполнить. Да, ты ничего не перебираешь, у тебя джаст воркс.
>>1066574 >дерево перебирает ноды диалог ваш не читал, но скорее всего не перебирает, ему не нужно, при добавлении в дерево происходит взятие ссылки из словаря который заполняется при добавлении детей в дерево
>>1066581 могу но не буду, не собираюсь ковыряться в каловом с++ говне обезьян и хуана, разбираясь кто чей наследник, где перегруженным оператором прокидывается операция += в операцию + и написано ли это в .cpp файле или .h
можешь дать ссылочку на строку, если такой >У нас опенсорц
>>1066585 >с перебором, аж с двумя которые происходят только если get_node_or_null не вернула ничего но всё равно не ясно что за subname чьё количество возвращается, я бы сказал что всё что после if(!node) касается уже свойств найденной ноды и ресурсов типа шейдера или скрипта
>>1066573 >Я не очень понимаю зачем ты каждый кадр перерисовываешь путь
Это дебаг линия. Это нужно чтобы визуализировать движения юнита относительно его центра и увидеть его центр вообще. Например при повторном клике в другое место, мы не хотим чтобы юнит пошел по краю, а центрировал себя (если новый путь не совпадает со старым).
Не нужно центрировать по global_position, линия исходит из персонажа (трогать ее не нужно), поиск пути уже центрирован и так. Но да, апи там веселое пик2, приходится обертки писать.
>>1066594 > Но да, апи там веселое пик2, приходится обертки писать. Бедненький. Не предусмотрели создатели движка твои шизозапросы. >>1066596 > Поэтому нужна строгая типизация Тебе нужно нахуй свалить, блядь в свой срачезагон, откуда ты выкатился, мразь.
>>1066597 Можно только представить насколько твоя желчность разрушает тебе жизнь. По-любому там уже багаж нервозов и депрессии, будь осторожнее с этим, оно тебя сожрет.
>>1066596 К сожалению в случае с Vector2 -> Vector2i не поможет, там просто происходит конвертация даже со всеми включенными ворнингами, я на это ишью создавал ещё летом 2024, но они не смогли решить нужно ли им создавать новый тип варнинга или использовать существующие, потом ишью потонуло и я его сам удалил через пол года потому что пошли они нахуй
>>1066594 > Например при повторном клике в другое место, мы не хотим чтобы юнит пошел по краю, а центрировал себя. При этом ему нужно будет вернуться, что смотрится не очень. Это, кстати, объясняет почему Парадоксы не делали анимации между переходами (только относительно недавно они улучшили этот момент)
Вот почему прототипирование важно. В "голове" я этого даже не увидел
>>1066594 >Например при повторном клике в другое место, Так а концепция такая, что юнита можно передвигать в любой момент? Не помню где такое было, обычно кликнул куда-то и всё, ну в крайнем случает есть кнопка отменить ход которая просто телепортирует его обратно.
>>1066610 Реалтайм движение как в играх Paradox. Типа армия перемещается медленно как между больших регионов (в HOI4 регион это вообще реальная область), в данным момент армия движется в лес (пехота очень любит прятаться в лесу). Гекс может быть селом, или несколько гексов образует целый город. Такой масштаб.
Я пока пробую реалтайм боевку. Возможно вернусь к пошаговой. вся рисовка плейсхолдеры, потому что если реалтайм не зайдет я уйду в фэнтэзи по толкину, а потом возможно и лайтовое 3Д
>>1066614 Я уже решил проблему >>1066559 Годот, вероятно, при line2D.to_local() не вычисляет новые координаты сразу, а хранит отдельно и когда наступает время рисовать, он вычисляет уже с другим оффсетом и рисует по испорченным координатам. Ну я так понял, пускай С++ гуру подтвердят.
Мне понравился твой пасфаендер. Я бы назвал его "новогодний поиск пути".
>>1066539 >Расширяемость через компоненты >в какой-то момент [[ВНЕЗАПНО]] может понадобиться Ты избыточно жертвуешь удобством и надёжностью ради "гибкости" в будущем. Это ECS головного мозга. В ООП есть два основных типа ассоциаций между классами: агрегация и композиция. Агрегация - это мягкая зависимость, когда один объект получает ссылку на другой объект на ограниченное время пользования. Агрегация позволяет объектам существовать полностью независимо друг от друга и иметь множество пользователей. Композиция - это жёсткая зависимость, когда объект полностью владеет другим объектом, от начала и до конца. Композиция создаёт связь "родитель - потомок", которую мы можем легко наблюдать в любых сценах Godot при создании новых нод.
Итак, когда предпочитать агрегацию, а когда - композицию? На мой взгляд, по умолчанию все ноды в дереве сцен Godot взаимодействуют по принципам композиции: они имеют строго одного предка и существуют столько же, сколько существует их предок, и предок имеет полный контроль над ними. Однако, в некоторых случаях нам может требоваться агрегация, например, когда мы создаём что-то в реальном времени из разрушаемых по отдельности частей, которые должны существовать сами по себе, независимо друг от друга. С агрегацией намного сложнее работать, чем с композицией, потому что требуется учитывать все приходы-уходы объектов и их классы. С композицией объекты жёстко связаны и поэтому с ними намного проще работать, чем в случае агрегации.
А если тебе в будущем ВНЕЗАПНО потребуется агрегация там, где сейчас композиция - ну, что же, ничего, отрефакторишь часть кода, сложно что ли? Ты должен заранее знать, где тебе совершенно точно потребуется агрегация, и, значит, нужно наворачивать дополнительные методы для управления объектами, а где тебе будет достаточно простой композиции объектов.
Пользуйся бритвой Оккама в разработке - не множь проблемы без крайней на то необходимости.
>Если у какого-то объекта нет спрайта, значит он невидимый; нет звука - беззвучный. Если это поведение не было прописано в спецификации на объект, то он - сломанный. >задача родителя - лишь объединить всех под общей крышей Нафига? Сри своими компонентами прямо под Root-ноду в рантайме. Слишком сложно? >когда этот предмет можно было бы собрать просто мышкой накидав в него компоненты? И как ты с ним работаешь, если у него никаких методов и свойств нет, только "компоненты"?
>Конечности важно знать, находится она в составе Не нужно ей ничего знать. У неё два состояния: 1. Нет тела - поведение по умолчанию (или нет поведения). 2. Есть тело - тело управляет конечностью как-то по-своему.
>Что изменилось для твоего пикрил краба? У краба есть нервный узел (мозг), который управляет всеми его конечностями: 8 ног, 2 руки, ещё несколько жевательных конечностей в пасти... Если какая-то конечность критически повреждена, мозг краба ощущает неполадку в подчинённой ему системе и отрывает повреждённую конечность, а затем адаптируется к движению на оставшихся конечностях до следующей линьки (когда тело отрастит новую конечность на место старой). Сама конечность только следует приказам мозга.
Можно также рассмотреть осьминогов. У осьминогов 9 нервных узлов-мозгов, по 1 на каждое из 8 двигательных щупалец и ещё 1 центральный в головном отделе. Поэтому отделённые от туловища щупальца продолжают активно двигаться, пытаясь что-то сделать - у них есть своё поведение. Но осьминог в целом управляет всеми 8-ю щупальцами через свой 9-й мозг, а не наоборот. То есть щупальце может сообщать центральную мозгу "я что-то нащупало, двигаем сюда", а потом этот центральный мозг приказывает 7-ми остальным мозгам "двигайте в том направлении".
Суть в том, что мозги осьминога не смогут управиться с телом краба, а мозги краба не смогут управиться с телом осьминога - они заточены под строго конкретную конфигурацию тела и вся их гибкость ограничена возможностью потерять несколько конечностей. Хотя человеческий мозг способен адаптироваться к подключению дополнительных конечностей, но это другое...
Так и в ООП. У тебя объекты заточены под конкретную конфигурацию, чтобы оптимальным образом работать именно в ней - ты не создаёшь супер-монстра, способного работать с абсолютно любыми конечностями и абсолютно любыми мозгами, а создаёшь специфично ограниченную конфигурацию, решающую твою конкретную задачу в конкретной ситуации, а не "что угодно, как угодно, где угодно".
>Когда у тебя не ноды в дереве, но... одни классы являются полями других Ты не поверишь, но "ноды в дереве" - это на самом деле "классы в полях других классов". >у Годота же дерево нод! Оно осуществляет менеджмент иерархии, и все ноды равноправны Слишком большая свобода в коде - источник проблем. Тысячу раз объясняли в этом треде... >Иерархия здесь - условность для разных удобств Да. И ты жертвуешь этими удобствами. Зачем? >Так смысл тогда этих брачных игр? В чём смысл предохранителя в пистолете, который ты в кобуре на ноге носишь?
Пока глубокое прототипирование, пошаговые проще. Вот как быть если два юнита двигаются в одну точку. Или на юнита напали, он остановился раньше положенного, но в ту позицию двигался другой юнит (и раньше гейкс был помечен как свободный). Тебе же не хочется обнаружить, что подкрепление перестало идти еще игровую неделю назад.
1) Надо хранить все пути и запрещать вторичную конечную точку, а так же пересчитывать в случае форс-мажора (привет еще один слой абстракции).
2) В момент конфликта, возвращать опоздавшего назад (а если там много? Пешка улетит в никуда).
3) Разрешить объединяться - другой геймплей, да и если есть ограничение на стак - проблема остается.
>>1066656 >dict[hash(Vector2i(x, y))] Зачем ты вызываешь hash()? Можно намного проще и быстрее: >dict[Vector2i(x, y)] Также рекомендую использовать типизацию словарей вот так: >var dict: Dictionary[Vector2i, int] Тогда ключом сможет быть лишь Vector2i, а значением - int.
>>1066660 Привыкай использовать строгую типизацию.
>>1066663 Я думал это встроенная функция по типу как str() вместо obj.toString(), так и hash() вместо obj.hashCode() А оказалось это вообще хер пойми что (отдельная фигня).
>>1066663 >Привыкай использовать строгую типизацию. Какой же ты токсичный. Я говорю про коллизию хэшей, а он говорит учись типы использовать.
Ты в курсе что ключи в словаре это не векторы/строки, а хэш код этих типов? Наверное человек, который понимает как устроена хэш-таблица - как-то разбирается уже типизации?
>>1066667 >А оказалось это вообще хер пойми что (отдельная фигня). Это для хэширования данных перед сохранением на диск, например, или для интернета...
>>1066673 >Я говорю про коллизию хэшей Коллизия происходит в hash() и ты её суёшь в Dictionary. Т.е. это только твоя ошибка.
>человек, который понимает как устроена хэш-таблица Кто, я? Я понимаю. Хэш-таблица использует хэши только для ускорения доступа к значениям - чтобы отдавать значения по индексу, как обычный массив. Если при создании нового ключа хэш-таблица замечает коллизию хэшей, она использует специальный алгоритм для исправления коллизии перед сохранением новой записи - и этот алгоритм является самым главным элементом любой хэш-таблицы, без которого она бесполезна (из-за коллизий). То есть хэш-таблица по определению не подвержена коллизиям, если ты используешь её по прямому назначению (т.е. отдаёшь ей свои реальные ключи, а не какие-то хэши этих ключей). Но ты её использовал неправильно, потому что ты не разбираешься в хэш-таблицах.
>ключи в словаре это не векторы/строки, а хэш код этих типов Нет, ключи - это вообще любой Variant. Хэши - это механизм ускорения доступа по ключам. Отправляешь совершенно любой Variant и получаешь связанное с ним значение - и получаешь быстро благодаря алгоритму хэширования. Чем больше коллизий, тем медленнее скорость доступа, но при этом все данные надёжно доступны по заданному ключу, потому что используются именно эти ключи, а не их хэши. Надеюсь, понял?
>как-то разбирается уже типизации Если бы ты разбирался в типизации, ты бы уже юзал Dictionary[Vector2i, int] и не парился...
>Какой же ты токсичный. Я просто пытаюсь помочь понять и разобраться новичкам в треде.
Так что ты можешь хоть жопу туда положить, если твой тип не представляет хэш, он никак не сможет нормально храниться в хэш-таблице. На самом деле это проблема появляется именно в статическом типизируемом языке, потому что в динамическом есть возможность средствами языка как-то еще посчитать (в статическом только через рефлексию, если она есть и никто этого делать не будет). Так что еще большой вопрос кто у нас тут на статике пишет.
Было бы классно если бы ты трипкодом подписывался, мы бы не спорили больше никогда
>>1066681 >И пошла ставка из нейронки. Это аргумент к человеку, знаешь такой? Нет, мне не нужно спрашивать нейронку для ответов тебе.
>Ты же понимаешь что по итогу никакого вектора в словаре не лежит? >Знаешь что в реале лежит в качестве ключа? Вот этот хэш Ты решил позориться до конца? Лучше изучи код самой хэш-таблицы, которую ты якобы "понимаешь": https://github.com/godotengine/godot/blob/63227bbc8ae5300319f14f8253c8158b846f355b/core/templates/hash_map.h Тебе там даже в комментариях разработчики Godot простым языком объяснили, как оно работает: >A HashMap implementation that uses open addressing with Robin Hood hashing. Robin Hood hashing swaps out entries that have a smaller probing distance than the to-be-inserted entry, that evens out the average probing distance and enables faster lookups. Backward shift deletion is employed to further improve the performance and to avoid infinite loops in rare cases. >Keys and values are stored in a double linked list by insertion order. This has a slight performance overhead on lookup, which can be mostly compensated using a paged allocator if required. >The assignment operator copy the pairs from one map to the other. А потом ещё почитай статью в Википедии, если не веришь моим словам и словам разработчиков: https://ru.wikipedia.org/wiki/Хеш-таблица >Поэтому механизм разрешения коллизий — важная составляющая любой хеш-таблицы. https://en.wikipedia.org/wiki/Hash_table >Hash collisions, where the hash function generates the same index for more than one key, therefore typically must be accommodated in some way. >Storing the key alongside the value ensures that lookups can verify the key at the index to retrieve the correct value, even in the presence of collisions. Конкретно в Godot хэш-таблица хранит пары ключ-значение - HashMapElement<TKey, TValue>.
>Было бы классно если бы ты трипкодом подписывался Опять аргумент к человеку. У тебя снова аргументы кончились? Ты понимаешь, как низко ты падаешь?
>>1066683 Метаморфоза. Сначала не понимает как работает хэш таблица, рекомендует типизацией лечить, НО спустя два часа приходит и закидывает ссылками с вики, да еще запутался, одну кинул в ру-переводе (бывает, я тоже в ру читаю, не переживай). Поздравляю с просвещением, оказывается хэш таблице похер на тип вообще? Главное чтобы сам объект мог нести в себе информацию хэше? Да? Что хэш не берётся из воздуха. Ты же это понял, надеюсь?
Я сначала хотел задать, почему вектор вычисляет свой хэш по мурмур3, если хэш-таблица прекрасно справляется с коллизией, но увы нейронка спокойно на это отвечает.
>Конкретно в Godot хэш-таблица хранит пары ключ-значение - HashMapElement<TKey, TValue>. >Ты решил позориться до конца? Ниче что это только единичный бакет HashMap? У тебя буквально ниже настоящий класс. Че, трудно читать сорцы без нейронки? Списки бакетов и их распределение и есть хэш-таблица. Кто еще позориться.
Зачем ты это делаешь? Зачем ты пытаешься отвечать не зная тем? Решение коллизий в хэш-таблице это затычка от потери данных, которая роняет производительность, именно поэтому вся задача по коллизии ложится на типы. Как это было реализовано в GDSript, который соткан на коленке, у которого есть кривая функция hash(), которая вводит в заблуждение - было вообще непонятно. Но теперь мы знаем что благодаря мурмуру можно держать Vector2i в качестве ключа в любых размерах "i32". И МОЖНО ДАЖЕ НЕ ТИПИЗИРОВАТЬ - хэштаблице насрать на это (не насрать только С++ коду, который будет разворачивать Variant из value)
>>1066686 >>1066701 Я ошибся и не правильно сказал, а ламер зацепился за слово. Ну хоть просветился.
В общем, коллизия ложится на типы, но хэшмапа может решать самостоятельно (иначе смысла в ней не было бы), но смысл в том что лучше этого избегать.
Вчера мы узнали что отсебятины у них в коде нет и там все норм (как минимум у Vector2i нормальная и быстрая хэш-функция)
Так что можно смело использовать сложные типы данных в качестве ключей, сложность будет держаться на уровне O(1) (ассоциативные массивы очень эффективны).
Я бы еще поспорил за статическую типизацию, которой нет. Многие воспринимаю хинты типов как настоящую статическую типизацию (в статических языках). Даже документация вводит в заблуждение, называя хинтинг статической типизацией.
Я не говорю что статическая типизация это плохо (сейчас набегут), ни в коем случае, я говорю, что гдскрипт все еще динамический язык и хинты это не исправляют.
нытье Вместо того чтобы сделать JIT, они проводят замеры как функция запускается быстрее на 75% быстрее. Спасибо за 100 наносекунд, но за типизацию мы бы хотели увидеть сравните уже с С++.
PS А вот взяли бы шарпы не пришлось бы страдать и из говна конфетку делать. (Да даже бы V8 взяли, уже получили бы ультра производительность и у людей был бы typescript)
>>1066712 >Вместо того чтобы сделать JIT Над jit работают >А вот взяли бы шарпы В данный момент шарпа нет в вебе потому что блазоровский компилятор - это ебучий пасынок который не умеет собираться в длл и ради него приходится весь движок превращать в библиотеку, чтобы эта говнина заработала. Вот наглядно ответ почему шарп никогда не займет место гдс. Гдс любят, у него есть мейнтейнеры и полная любовь с с++ ядром, какой бы говниной он не был сам по себе.
>>1066743 Один из самых живых тредов, юнити за неделю максимум пукнет пост. Даже детвора с движкосрача не дотягивают (экзамены перед каникулами, с понимаем).
>>1066748 Телепатией сложно, ты блокируешь третью чакру, поэтому давай код (только не копипастом сюда, хотя бы картинкой или хост-тест-сервисом, хз может сюда https://gdscript-online.github.io/)
>>1066750 ну вот кусок кода за это отвечающий - func process_physics(delta: float) -> void: # ДВИЖЕНИЕ - РАБОТАЕТ ВСЕГДА (кроме некоторых состояний) if not stunned and currentState != state.BOUNCING: var dir = 0
# Ключевое изменение: правильно определяем момент отпускания джойстика var joystick_just_released = joystick_was_active and not joystick_active
# Движение работает если джойстик активен И имеет горизонтальную составляющую # НО: если мы заряжаем прыжок, ограничиваем горизонтальное движение if joystick_active and abs(joystick_direction.x) > joystick_deadzone: if is_charging_jump: # Во время зарядки движение замедлено dir = sign(joystick_direction.x) 0.3 else: dir = sign(joystick_direction.x)
# Используем текущую скорость с учётом апгрейдов var current_speed = moveSpeed speed_multiplier
if dir != 0: # ЕСТЬ ВВОД - ДВИГАЕМСЯ var target_speed = dir current_speed if not grounded: target_speed = jumpHMultiplier # В воздухе быстрее
if onIce and grounded: # На льду: плавное ускорение/замедление var ice_speed = target_speed moveSpeedIceMultiplier velocity.x = lerp(velocity.x, ice_speed, iceInertia) else: # На обычной поверхности: мгновенное изменение скорости velocity.x = target_speed
facing_right = (dir > 0) else: # НЕТ ВВОДА - ОСТАНОВКА if joystick_just_released: # Джойстик ТОЛЬКО ЧТО отпущен - мгновенная остановка velocity.x = 0.0 print("Джойстик отпущен - мгновенная остановка") elif onIce and grounded: # На льду и джойстик просто не двигается - плавное замедление velocity.x = lerp(velocity.x, 0.0, iceInertia)
# Если скорость стала очень маленькой, обнуляем её if abs(velocity.x) < 5.0: velocity.x = 0.0 else: # На обычной поверхности и джойстик просто не двигается - мгновенная остановка velocity.x = 0.0
# Гравитация if not is_on_floor(): velocity.y += gravity delta
# Отскоки if bounce_timer > 0: bounce_timer -= delta if bounce_timer <= 0 and currentState == state.BOUNCING: currentState = state.FALLING
>>1066763 Там к ссылке слеш и скобочка в конце прилипли.
>>1066679 >Как, по-твоему, должно работать такое меню с анимациями? Не понял вопроса. Вариантов куча, в целом как тебе нравится, так и должно. Не?
Хм, пока я работал на работе, вы тут на хэши переключили срачик, ок.
>>1066619 >Ты избыточно жертвуешь удобством и надёжностью ради "гибкости" в будущем. Я ничем не жертвую, мне супер удобно. И гибкость у меня не в будущем, а здесь и сейчас. >Это ECS головного мозга. Только без E и без S, лол. >В ООП На ООП свет клином не сошёлся.
Ты относишься к дереву так, будто это иерархия в ООП. Но это не так. Дерево состоит из нод, каждая из которых самостоятельна, и связи/зависимости между ними выстраивает разработчик сам. Никто не обязывает делать это подобно ООП.
>Нафига? Сри своими компонентами прямо под Root-ноду в рантайме. Слишком сложно? Хуан дал мне дерево, я оценил этот инструмент как очень удобный и пользуюсь. Зачем я буду создавать мешанину в корне, когда могу удобненько разделить всё по ветвям?
>И как ты с ним работаешь, если у него никаких методов и свойств нет, только "компоненты"? Кто сказал, что никаких нет? Есть абстрактные, есть направленные на менджмент компонентов. Есть такие, которые должны быть общими для разных компонентов.
>Не нужно ей ничего знать. У неё два состояния: Да. Именно. В этом и заключается всё "знание".
>мозги осьминога не смогут управиться с телом краба, а мозги краба не смогут управиться с телом осьминога Ты этого не знаешь наверняка. Я думаю, что смогут, потому что нейропластичность. Шо то нейронка, шо это. Кажется, даже попадалась инфа про какие-то такие эксперименты, но не схоронил, так ччто стопроцентно утверждать не буду.
>>1066721 Насколько я понимаю, написание компилятора (не важно jit или aot) - задачка повышенной сложности, которая к тому же не особо пересекается с написанием графического движка. Нужно глубоко знать теорию компиляции и шарить в ассемблере. Сверху ещё и заставить его работать на всех поддерживаемых платформах. Сверху усложнение в виде jitовости. Кароч это СИЛЬНО сложнее, чем интерпретируемый язык. Надо быть спецом уровня Ритчи.
>>1066756 ># Ключевое изменение: правильно определяем момент отпускания джойстика >>1066748 >Спасайте парни Ты нейронкой код нагенерил, а теперь побежал к нам этот говнокод разгребать?
>персонаж двигается даж когда кнопку отпусакешь Я в твоём коде не вижу вызова move_and_slide(). Без него velocity ничего не делает.
Принцип работы с CharacterBody(2D/3D): 1. Меняем velocity как хотим. 2. Вызываем move_and_slide(). После вызова move_and_slide() в velocity будет обновленное значение.
>>1066712 >гдскрипт все еще динамический язык и хинты это не исправляют. И это хорошо, потому что на динамическом проще прототипировать новые игры. >за типизацию мы бы хотели увидеть сравните уже с С++ Если тебе нужна скорость C++, то и пиши на C++, а не на каком-то другом языке. >А вот взяли бы шарпы не пришлось бы страдать Так они и поддерживаются для таких, как ты. Только таких как ты меньшинство. >V8 взяли, уже получили бы ультра производительность Тогда почему веб-браузеры всегда тормозят? Когда отключаю JS - всё летает. >и у людей был бы typescript Это огромный костыль-заплатка поверх кучи тупого легаси в ECMAScript.
>>1066783 >написание компилятора - задачка повышенной сложности На самом деле нет, просто разрабы Godot долго не могли договориться...
>>1066791 >Или взять готовое Ну так бери, чего ты ждёшь? Потом отпишешься об ощущениях: https://github.com/godotjs/GodotJS >Add TypeScript/JavaScript Support for Godot 4.x with v8...
>>1066823 >И это хорошо, потому что на динамическом проще прототипировать новые игры. Как раз таки нет. Сидишь как сыч без автокомплита и лбом ловишь банальные ошибки. Сейчас современные языки с автовыводом типов, пишешь как динамическом языке, а сигнатурки методов ты всегда хочешь ограничить, даже в динамическом языке, чтобы не ловить вектор, там где инт нужен был.
>>1066823 >Тогда почему веб-браузеры всегда тормозят? Когда отключаю JS - всё летает. Потому же что и windows 2000 хватало 128 мегабайт оперативной памяти.
>>1066823 >На самом деле нет, просто разрабы Godot долго не могли договориться... Не могли договориться кто будет писать :).
>>1066823 >Ну так бери, чего ты ждёшь? Потом отпишешься об ощущениях: Ожидаемо что все эти языки будут гражданином второго сорта как и сишарп
>>1066823 >Это огромный костыль-заплатка поверх кучи тупого легаси в ECMAScript. Во-первых не при сравнении с гдскриптом такое говорить. Во-вторых легаси только в браузерном апи, в самом жс нечему легаси быть, за исключением мелочей типа typeof null == "object" Браузерное апи живет и развивается от жс отдельно
>>1066823 >https://github.com/godotjs/GodotJS А это не расширение, а форк движка? Ну тут есть проблема, насколько он не отстает и что будет когда детворе надоест? Мне потом ts подтереться?
>>1066834 Будь мужиком. Поддерживай сам и делись с другими. Ну и маловероятно что некому будет поддерживать, потому что сейчас жсеров как собак бездомных
>>1066840 Ну а второй пик. Явный импорт во всех взрослых языках. жава сишорп тайпскрипт даже в питухоне. Толко в детских языках типа голанга и дарта хуй знаешь что импортируешь
>>1066840 Это был ts, лень все смотреть, это видимо касается только экспорта (у js нет int типа, только number и bigInt)
>>1066841 >Ну а второй пик. Явный импорт во всех взрослых языках. жава сишорп тайпскрипт даже в питухоне. Если по честному да, тут просто автоимпортом вставлялось в момент кодинга. С одной стороны модульность, с другой можно было базовые классы добавить в глобальное пространство.
>>1066829 >чтобы не ловить вектор, там где инт нужен был Там, где скомпилированный код крашится с непонятной ошибкой доступа к недоступной области памяти совершенно без намёков на то, что пошло не так, и заставляет перезапускать всю игру с чистого листа (а в большом проекте это может занимать минуты), интерпретируемый сценарный язык позволяет проигнорировать подобные мелочи и нестись на всех порах через любые некорректные команды как скоростной поезд, перезагружая участки кода игры прямо в процессе её выполнения без компиляции.
В этом и есть преимущество динамического языка: да, будет куча ошибок и предупреждений о том, что где-то что-то пошло "не так", но в худшем случае игра встанет на паузу и легко может быть продолжена, наплевав на все исключения - потому что тебе главное протестировать идею, которая пришла в голову, а не следовать всем правилам. Это очень круто для быстрого прототипирования любых новых идей.
>Потому же что и windows 2000 хватало 128 мегабайт Почему-то на GDScript не тормозит код, который тормозит на JS в браузере на том же компьютере. Вот бывает напишу от балды какой-то говнокод, который я даже не рассчитываю выполнить с первой же попытки, а он раз - и не просто запускается, но и работает быстро и чётко. Как так? С каждым разом убеждаюсь, что ставка на будущее Godot/GDScript - единственно правильная (хотя бы в опенсурсе). А игрушки в веб-браузере всегда были извращением и чем-то вроде репостов в соцсетях (постыдное).
>все эти языки будут гражданином второго сорта Это естественно - ведь GDScript делается для Godot, а остальные языки делались не для Godot.
>>1066834 >А это не расширение, а форк движка? Не форк, а модуль. Модуль подключается в процессе сборки оригинальной (совместимой) версии движка из исходников. Под "форком Godot" обычно подразумевают такие сборки, которые меняют что-то в ядре движка, делая его несовместимым с оригинальными исходниками. То есть ты можешь подключить несколько сторонних модулей в оригинальную версию и они должны будут без проблем работать, но в случае "форка Godot" совместимость со сторонними модулями не гарантирована.
>>1066838 Вот поэтому мы все и сидим на GDScript, в котором такие бойлерплейты писать не нужно...
>>1066844 >Почему-то на GDScript не тормозит код, который тормозит на JS в браузере на том же компьютере. Жс один из самых оптимизированых скриптовых языком. Только это зависит от рантайма. V8 очень быстрый. Ты сравниваешь инженеров гугла со школотой делающй годот
>>1066679 Пофиксил анимации и раскрытие панельки с информацией.
>>1066682 >Красивое. Анимация всплытия это твинками? Спасибо. Конечно - без Tween было бы намного сложнее.
>>1066779 >Не понял вопроса. Вариантов куча Ну, было интересно твоё мнение: "call down, signal up", наоборот, или как-то ещё?
>в целом как тебе нравится, так и должно Я уже много вариантов перебрал, всё время что-то мешало. Сейчас вроде получше.
>Никто не обязывает делать это подобно ООП. Не обязывает, но в таких цепочках иерархии что-то точно есть. У меня сейчас так:
0) Этот уровень пока не существует, но планируется: нужно абстрагировать заполнение контейнера с тегами. Каждый тег будет иметь свой цвет, надпись и, возможно, иконку. Сначала я думал сделать "один предмет = один тип", но мне захотелось сделать так, что один предмет может иметь несколько тегов-свойств, и эти теги нужно показывать игроку в какой-то стандартизированной (узнаваемой с первого взгляда) форме - и не только в этом меню (столы для крафта, скорее всего, будут принимать предметы по тегам). Так что получается капсула-тег и контейнер с такими капсулами, принимающий массив тегов.
1) Меню для просмотра информации о предмете. Это весьма сложная композиция из стандартных Control-нод, главный скрипт которой принимает на вход ресурс предмета, и обновляет состояние своих потомков в соответствии с полями этого ресурса. Его можно свернуть в иконку и развернуть на весь размер. Я долго раздумывал о том, стоит ли делать это меню единственным на весь инвентарь или нет, и в итоге решил, что пока игра не начнёт тормозить из-за огромного числа таких меню - буду размножать их... Размножать эти меню легко, а единственное меню может оказаться менее отзывчивым в плане быстрого переключения в круглом меню. С другой стороны, создание десятков таких менюшек на каждое открытие внешнего контейнера было бы слишком затратно...
2) Обобщённый RadialMenuItem, который я уже несколько раз делал и удалял в разных вариациях, т.к. не мог определиться, нужен он мне или нет. Сейчас склоняюсь к тому, что нужен. Буквально несколько часов назад перенёс в его код анимацию перемещения и фокусировки, т.к. этот объект способен прыгать между разными круглыми меню и поэтому должен самостоятельно руководить своими анимациями. "Меню просмотра информации о предмете" наследуется от него... хотя, это вроде как не обязательно.
3) Собственно RadialMenu, который следит за вхождением новых RadialMenuItem и удалением имеющихся, задаёт им позиции через их методы, рисует круг, отслеживает положение мышки и сигналит наружу о произошедших событиях ввода. На этом уровне я лишь недавно смог достичь гармонии, выбросив кучу лишнего хлама. Раньше я пытался нагрузить этот уровень множеством состояний, функций, "фишек" меню - всё это было большой ошибкой - данным состояниям и функциям самое место на следующем уровне абстракции. Сейчас RadialMenu просто делает свою работу, где бы они ни был размещён, какого бы размера он ни был, и т.д. Хотя ощущается как даунгрейд, к сожалению...
4) Наконец, инвентарь - это сборка из двух RadialMenu на панелях с надписями, которые управляются главным скриптом. Этот скрипт отвечает за своё открытие и закрытие и за переброску RadialMenuItem между двумя RadialMenu, он же будет отвечать за новые RadialMenuItem. Теперь мне самому это кажется немного странным, но это всё ещё прототип и я не хотел писать отдельные методы для добавления-удаления кнопок. В будущем я хочу на этом уровне синхронизировать RadialMenuItem с конкретными предметами в двух ресурсах-инвентарях: инвентаре игрока и "внешнем". Это меню открывается в режиме "только инвентарь" или "свой и внешний" - второй режим должен активироваться только при наличии доступа ко второму ресурсу-инвентарю. Наверное, некоторое количество RadialMenuItem должно находиться в пуле вне дерева сцены...
5) Потом инвентарь подключается к сцене игрока, где сейчас полнейший хаос и нужно рефакторить всё... Сцена игрока пока что уникальна и эти меню нужны только для неё, но, наверное, было бы лучше их абстрагировать... Короче, всё сложно. Но менюшка точно ничего не знает об игроке - это игрок управляет менюшкой, т.е. будет натравливать её на конкретный второй/внешний инвентарь для операций обмена. Тестировать пока не на чём, но я планирую нацепить первый внешний инвентарь на сундуки.
В общем... Мне кажется, я приблизился к идеальной схеме, разбросав все обязанности по независимым слоям абстракции так, чтобы нижние слои управлялись верхними слоями, о которых они ничего не знают и знать не должны. До этого я уже несколько раз пытался сделать круглое меню, каждый раз наматываясь на хаотичный клубок взаимосвязей, а сейчас его пока что нет: приказы идут строго сверху вниз, отклики - снизу вверх.
Но, может, я что-то упускаю и нужно было организовывать по-другому?.. Вот ты тут расписывал, что тебе удобнее делать полностью наоборот - приказами снизу вверх и откликами сверху вниз - у меня такое в голове вообще не укладывается, если честно. Может, потом снова буду вынужден переделывать все эти меню с нуля - кто знает...
Отфильтруй сначала весь шлак из движков и сравни потом. Подели на разность 2026(чего откладывать) и года создания движка. Выходящие цифры - это частота создания хороших(Или что останется после твоего фильтра шлака) за время существования. Примечание: усредняется значения начала разработки, когда о каком-либо движке никто ничего не знал и высшего пика популярности, приблизительно сегодня. Или ты считаешь за игры только крупные 3D-проекты, которые занимают четверть диска твоего компа?
>>1066848 Этот прав, у js иногда выходят такие показатели, что выглядит как волшебство (типа как вообще возможно такое на динамикодресне). Но реакто-вундеркинды все равно съели весь проц и память.
>>1066844 Но я согласен что хороший хотрелоад важнее этого всего. Хороший хотрелоад в глубокой позиции буквально "экономит тестовые сцены" (которые пришлось бы создавать при других условиях, а так налету потестил, подергал, понюхал, полизал).
>>1066850 >Ну, было интересно твоё мнение: "call down, signal up", наоборот, или как-то ещё? Так мнение таково: если мы не знаем, кто будет отвечать на вызов, то сигнал; в противном случае калл. А даун там или ап - не важно, этих понятий не существует на уровне отдельной ноды.
Олсо я щас в процессе создания своего меню предметов (правда, это не совсем инвентарь с точки зрения геймплея, скорее склад говна для крафта в хабе). Как сделаю - расскажу. В любом случае, разница уже начинается: у меня предметы это ноды, а не ресурсы. И ещё терпеть не могу радиальную консольную дрисню, но это чистейшая вкусовщина, ноу оффенс. Хотя даже у тебя на видриле видно очевидный минус такого подхода: слишком много в радиальное меню не впихнёшь.
>>1066850 >Но, может, я что-то упускаю и нужно было организовывать по-другому?.. Вот ты тут расписывал, что тебе удобнее делать полностью наоборот - приказами снизу вверх и откликами сверху вниз - у меня такое в голове вообще не укладывается, если честно. Бро. Ты это ты, я это я. Если для тебя твой подход работает - значит ты всё правильно делаешь. У любого подхода есть свои плюсы и минусы, единственно правильного не существует.
Увидимся в перекате.
У меня выходной, я выспался и с утра сел делать игру. Вот.