Заказал УЖАСНЫЙ код у фрилансера за 500 рублей. Unity + C# рефакторинг
HTML-код
- Опубликовано: 6 июн 2024
- Сидел, никого не трогал и заказал код у фрилансера за 500 рублей час. Знатно офигев от результатов решил переписать его во что-то более вменяемое. :)
Обучение с нуля с гарантией трудоустройства - ijunior.ru/unity-start?...
МОЯ КНИГА - csharpbook.sakutin.ru
Я В VK - rsakutin
ЯЮниор:
Группа - holymonkey_sandbox
Канал с уроками - / @user-wq2dk1kn2v
ЧАТ В ТЕЛЕГЕ - t.me/csharp_faggots_fan_club
Discord - / discord
INSTA - / sakutinhuytin
00:00 - Введение
02:40 - Обзор решения
07:22 - Рефакторинг класса Cube
14:13 - Рефакторинг CubeManager
30:43 - Играемся с методами расширения
В видео намётки по рефакторингу, после 2000 лайков выпущу отдельный видос где уже более комплексно пройдёмся по коду и решим многие проблемы на корню.
Также при записи я совершил пару ошибок, предлагаю внимательным их все найти
Дистанция считается от одного и того же объекта
to может быть null
where вынести из цикла дабы не создавать коллекции при каждой итерации
Забыл поменять 0.1f на _speed
Кстати, ты видел видео у S0ER`a, где он разбирает почему предусловия на валидность это плохо
Что скажешь?
ruclips.net/video/5Od1VaDL090/видео.html
@@user-cx1vt1kp1j У него другая ситуация, в его примере предусловия не приводят к ошибке. В моём случае предусловия уточняют ошибку. Т.е у него с предусловием будет мусор на выходе (undefined) а без будет явная ошибка. У нас же и так и так будет ошибка, только с предусловием мы можем точно сказать что пошло не так.
@@rsakutin предусловия хороши для создания фреймворков и утилит, но для сквозной логики, да еще и в циклах - это смерть производительности
Однажды Билла Гейтса спросили как ему удалось достичь таких успехов в программировании операционных систем на что он ответил:
Если код работает, значит не надо его трогать
жиза
Пацаны! У Романа хороший и честный курс!!! Я прошел его и меня устроили на работу, я мою полы у них в офисе, всем советую, полов на всех хватит)
за 54000 рублей в месяц?
Тебе повезло, я унитазы чищу 😥
@@dimonser7663 ну и хули ты ноешь, я вообще пылинки сметаю
@@Disappeared... тебе больше повезло, пылинки не все в говне
Блин, эта ниша уже занята, я опоздал... 😢
Я просто хотел посмотреть как дерутся кубики :(
я время от времени захожу, но кубики до сих пор не дерутся. Меня это несколько расстраивает.
Брат, все будет хорошо, ты не один такой!!!
@@DarkW1zard Я тоже ждал
я думаю перфоманс просел в разы, столько замыканий с переборами в замыканиях с переборами с linq да еще и в апдейте, что ну его нафиг )
в TransformExtensions в 29-30 строке ошибка (нарушена логика, поломан код)
и лучше завести переменную для closestDistance что бы её каждый раз не пересчитывать
конечно смотрится эстетически красиво, но между говнокодом вначале и перегибом получившимся в результате где-то лежит истина
Джва года ждал подобный разбор, если не больше. Спасибо! Давай ещё.
Ура. Вот сейчас честно. Если бы все последние ролики были бы такими, критика - объяснение - показал решение, претензий бы не было. И сейчас их(претензий) нет. Адекватно.
Очень интересно наблюдать, как у него в цикле сочетается три условия с разной стилистикой, это шикарно)
Спасибо, что ты есть!
Благодаря тебе начал копать документации по неймингу и стилистике кода
Видео просто супер, намного лучше когда рефакторишь в прямом эфире, думаю со мной согласятся...
Лучше как раз так. Стримы обычно нудные и растянутые выходят
Кстати, почему бы не выкладывать заранее какой-нибудь код и предлагать подписчикам его отрефакторить, а потом их закидывать говном (ну или говорить, что они молодцы)? А?
А какова была точная формулировка задачи для фрилансера? Если чтобы работало, то задача выполнена :) Я как-то оооочень давно на 1-м курсе писал софтинку для анализа геометрии GPS-карт для работы. Сейчас я в ужасе от написанного мной тогда кода, однако софтина работает и используется уже 13 лет и никто не жалуется, т.к. она закончена и расширение и развитие её не планировалось изначально. имхо расширяемость и поддерживаемость КОДА должны быть в постановке задачи, иначе тратить время на соблюдение всех принципов ООП просто незачем.
Тратить время? Зачем его тратить если все должно быть и так на автомате чтобы писать код правильно и умно а не написывать лишних строк так еще и непонятных... Имею ввиду под непонятные строки те что не понятны первое время а код должен читаться легко
@@owattara160 На автомате? Ты думаешь все сразу сеньорами после написания Hello World становятся? Есть задача, новичок может ее решить, точно так как описано в ТЗ. В чем проблема? Было бы написано нужна расширяемость и поддерживаемость, новичок бы за такое не взялся, если не умеет. А если бы взялся и не выполнил, тогда уже другой разговор. Для каждой задачи свои уровни навыков. Если вы ждете со старта сеньоров, которые идеально все знают и пишут идеальный код, то будет как минимум нехватка специалистов. Будет условно 500 задротов душных до чистоты, оптимизации и т.д. кода на всю Россию работать.
Очень классно разобрал и собрал код)) Жду следующего ролика
Еще вопрос, можно ли было вместо event Action использовать event Func, для того, чтобы сигнатура подходила под метод Remove? Там же возвращаемое значение имеет тип bool.
Роман)) не знаю куда еще написать, но можно ли у вас попросить демо доступ или подробное описание вашего курса?)
Мое перфекто выдавило мне глаза после того как Роман так и не применил поле _speed с магическим числом 0.1f в классе cube. Это как минимум попахивает дилдом в глаз
Классный выпуск, спасибо!
Во-первых, я бы прикопалась к твоей оценке денег фрилансеров. В отличии от офисных работяг, они также занимаются поиском заказов
Во-вторых, если есть конкретная КОНЕЧНАЯ цель, то в чём смысл тратить время на качественный код и расширяемость? Если дальше над ним работать не нужно, то расширяемость не имеет смысла, за которую ты очень сильно цепляешься
В третьих, я, как и многие другие люди, ждала, что хотя бы продемонстрируется работа этого кода, но хрен там плавал
В четвёртых, многие комментаторы жалуются на ошибки в коде, и это выглядит вдвойне нелепо, что "плохой" код работает, в отличии от "хорошего"
В пятых, нафига в методе TakeDamage было кидать исключение, если значение полученного урона меньше нуля? Почему бы не написать просто return? Это в юнити считается нормальной практикой, или во всём шарпе? Исключения - это отличный способ ловить серьёзные ошибки, но... тут же её нет. К тому же, если и происходит какая-то такая ситуация, то ловить её нужно здесь и сейчас, а не где-то извне
Это вроде от взлома было сделано
Нельзя умалчивать ошибки. Если сделать просто return, то после вызова метода может ничего не происходить, и не будет ясно почему. Это используется как в Unity, так и в C# в целом.
А насчёт расширяемости, возможно заказчику нужно будет расширять этот код, так что он должен быть расширяемым по идее. Конечно 500 рублей возможно не так уж и много, однако даже за такие деньги код не должен быть настолько плохим.
@@glazyrik6923 Нет, это просто принципы хорошего кода.
Полностью согласен
@@ram-1919 ну чет ты переоцениваешь важность ошибки при TakeDamage меньше нуля. Если делать хилки то один хрен код в видео придется частично переделать
Можно ли в приложение добавить ролик с Ютюб или др.видеоресурса? Не прилетит после публикации своего софта в плеймаркет бан за автор.права роликов?
Может уже писали, а в методе Closest если мы нашли элемент, не лучше break ставить, что бы остановить перебор обьектов??
Уже не помню всего кода, но суть в том, что ближайшим кубом может оказаться и последний из списка.
Поэтому break здесь использовать не имеет смысла.
На мой взгляд, подобные ролики это лучшая реклама ваших курсов. Наглядно видно чему можно научиться и как у вас пишут.
На кого ваш курс рассчитан? На нулей, начинающих?
36:00 метод Transform Closest
1. почему сначала поиск element == to, а следующей проверкой уже Count() == 0? Разве не логичнее наоборот, если в списке ничего нет то и элементов там не будет
2. почему не использовать вместо x.Count() == 0 !x.Any() ?
Не совсем понял для чего использовался IEnumerable в параметре метода FindClosest... Чтобы List с кубами протащить? А почему просто List в параметре не прописать? (вопрос от нуба, если что... камнями прошу не забрасывать).
Посмотрел 15 минут, ожидая увидеть какой-то реально криповый код уровня самых тайных и закрытых индийских школ кодинга. А увидел просто обычный код, который РАБОТАЕТ, и ЧСВ-шного школьника, который кукарекает. Было ли в ТЗ написано про стиль кода? Публичные поля ему не нравятся? Смешно видеть начинавшихся книжек про ООП и клин код и считающий, что это негласный стандарт языка. Хотя сам язык почему-то ничего не запрещает. Что уж говорить про то, что в шарп иногда залазят ребята из С, и пишут так, чтобы перформанс был, потому что это требуется. Самое глупое в видео - это попытка пересчитать заработок фрилансера за час кодинга на месячную зп. В офисе у тебя зп постоянно капает, работаешь ты или нет. А фрилансер большую часть времени заказы ищет.
чел, ты прав насчёт цены и стиля, который с исполнителем не обсуждался. Но например публичные поля это не просто до#б, это прямая уязвимость кода. Если не любишь ООП и его правила, то не юзай языки ООП, пиши на Си, радуйся жизни.
Фрилансеры потому и проводят бОльшую часть жизни в поисках заказов, потому что у очередного заказчика первый заказ становится последним, как раз потому что гуру фрилансер не делает анализа своих ошибок.
Можно конечно вести демагогию а имел ли он право делать видос из чужой работы и выставлять исполнителя дураком, но он бесплатно сделал ему ревью, которое, если фрилансер допетрит мотать на ус, сделает его ценник не 500 а 1500.
@@MaruskaStarshaya а в чем будет заключаться уязвимость кода?
@_dikiy_omlet_102 публичные поля могут все изменять и можно будет легко сделать подмену значений
@@TherryYT а понял, спасибо
вообще что то жестко, вот у нас есть список Кубов а что будет если другие кубы убьют пару кубов из этого списка, пока мы убиваем куб? Там будут указатели на null, или как это будет работать, или мы получим доступ к неправильной области памяти? Метод дестрой при уничтожении куба он наверно переведет его в другое состояние, но поскольку есть ссылка на объект, он не будет удален сборщиком мусора?
почему Вы не добавили в первом коде методы сеттеры начального состояния переменных?
37:39 в коде четверное перечисление IEnumerable это не очень хорошо, т.к. IEnumerable не означает, что его несколько раз можно перечислить. :)
Такой контракт либо явно через IList надо задавать, либо проверочки как-то по другому делать...
А в коде метода достаточно дернуть `source.Min(x => Vector3.Distance(x.position, to.Position))` вместо цикла.
Если уж одно перечисление хочется оставить, то там и эксепшны все нужные выпадут. Останется проверить если result == to => throw InvalidOperationException()
(В теле тоже, кстати, опечатка, в коде сравнивается another и another)
source.Min круто выглядит будет, из головы что-то вылетело совсем :)
37:58 Неявная зависимость на то, что Where проверяется в ходе цикла.
Если мы берем первый куб, ставим ему второй в противники, то мы пропускаем второй куб только потому, что там Where проверяет внутри себя по очереди элементы, а не сразу возвращает отфильтрованную коллекцию.
Считаю это не очень очевидным решением
@@emptysoul438 ничоси ты шаришь, будь моим наставником!
@@emptysoul438 Кстати не знал, что where отсекает на ходу. Думал по приоритетности задач, сначала отработает linq и создаст новую коллекцию, а потом уже цикл по ней будет спокойно работать по. Ну, теперь буду знать, что это не так.)
Хотя, догадывался об этом, когда читал конвенцию. Там вообще написано, что рекомендуется подобные действия с linq перед массивом выносить в отдельную переменную (разумеется с var) и писать в полной форсп. Мол, если пихать всякие цепочки прямо в цикл, то это не очевидно и когда цепочки длинные не читаемо.)
А как понял лучше писать примерно так:
var orher = (from cube in cubs where cube.enemy is null select cube);
//или
var other = cubs.Where(cube => cube is null);
foreach(Cube cube in other)
{
...
}
@@emptysoul438 не совсем понял о чём ты говоришь, в плане поведения ничего не изменится хоть ты сразу-же отфильтруешь или передашь в closest итератор where, в любом случае роман внутри closest идёт форичём по сурсу, соответсвенно он итерирует WhereIterator который нам вернёт уже элементы которые прошли по кондишину который в него передали, даже если бы Роман реализовал свой экстеншн по паттерну итератор (как в LINQ), то всё-равно кондишин романа в closest исполнялся только в том случае, если кондишн по текущему элементу в where вернёт true. Так что решение вполне очевидное, никаких проблем не вижу с точки зрения дизайна или поведения.
Самый лучший ролик на канале
как то начинал изучать c# забросил и через время пересел на Java и не могу найти канал похожий на твой ,очень все информативно , хорошо хоть языки похожие и можно все равно что то для себя подметить)))))
Я взял заказ на бирже , нужно было спарсить сайт.За 500руб, я написал код,парсил сутки,оказалось спарсились около 60%товаров,не понял что за дела,но потом оказывается на сайте верстка разных блоков отличается.Решил парсить по категориям, написал код под каждую из различий верстки,парсер работал оочень медленно, и нужно было чтобы ПК наверное 3 суток работал без перерывно,чтобы спарсить сайт.В итоге через часов 5 подумал "зачем оно мне надо за 3000р(заказчик предложил поднять цену)", и слился.
Андрей 17 лет.
Вот такого побольше, Ром) Это и полезно, и рожать ты можешь такого контента много, и сразу видно, к кому учиться надо идти)
ага, убрал геткомпонент в другой класс и вызывается он из апдейта в цикле
Спасибо за разбор
У меня вопрос. Я LINQ не пользуюсь в Unity. И вот, такое количество запросов в update не будет генерировать кучу мусора?
Они не в Update фактически, они выполняются для свободных кубов. Но то что код так грубо размещён в Update - это проблема которая создаёт такую путаницу
@@rsakutin понял, спасибо за ответ!
бедняга, как ты без линки со списками разбираешься?
Вот такой формат лучше всего! Кто-то написал криво и хрен с ним - нечего его хейтить... А ты показал как надо писать и объяснил почему да как... Вот за такое не лень Любо ставить
А почему Update private? Может не досмотрел где он используется в классе Cube?
Не ну кнш Linq в Update это жестко.
У меня аж глаз задергался)
Сакутин, давай несколько строчек кода с твоей игры, как это в процессе выглядит
А можно было просто вместо cooldownAttack сохранять время предыдущей атаки, а когда атакуем проверять, last - Time.deltaTime > 1, если это верно, то в last записать текущее deltaTime и атаковать?
Подскажите: как правильно получить все нужные объекты на сцене(как например в видео - получить список всех кубов)
Можешь создать ивент в старте по типу "я появился", а кто-то там уже его может обрабатывать. Или можешь производить инстанс обьекта вместе с добавлением в лист (главное после разрушения не забывай удалять). Ну или другие способы
Роман, вроде вы говорили что "мы никогда не используем статистические методы или классы" ?
Или я что то не понимаю?
Я думаю, что использовать LINQ в Unity должно быть запрещено. Потом всё равно придётся их выпиливать из-за бесконечных стартеров из-за GC. В идеале код вообще не должен выделять памяти в основном цикле, только на загрузке. Ну и то что дистанция вычисляется не квадратом длины и не кэшируется для самого близкого - кровь из глаз.
Рекомендую глянуть Tools, Tricks and Technologies for Reaching Stutter Free 60 FPS in INSIDE, чтобы разучится использовать foreach, linq, list и прочее.
@@jkot20 А List чем не угодил?
отличный формат
Ну, не соглашусь. Если ты за это заплатил 500 рублей, значит человек справился с задачей за час. Более того, ты заказал код на фрилансе, что само собой намекает на то, что проект не долгоиграющий, его нужно сделать и забыть (например, для курсача в универе). Тогда какой смысл думать о рефакторинге и тд? В этом смысла нет.
Чел реально годно справился с задачей по соотношению цена/качества. Он написал код, который кое-как, но работает, протестировал всё это дело. И справился с этим за час. У тебя пусть и с объяснениями ушло минут 40 только лишь на рефакторинг. А теперь посчитай, за сколько бы ты сделал задачу с нуля. Ушло бы часа 2-3. Теперь давай подумаем, стоит ли эта задача 3 часов? Если она прямолинейна, о масштабируемости говорить не приходиться? Нет, не стоит.
Я конечно не знаю, может, что в задаче было написано, но вряд ли: "Нужно сделать задачу с расчётом на то, что это долгоиграющий проект, его будут дорабатывать другие люди, сделай качественно, можешь хоть несколько часов это делать, не торопись."
Попахивает exception-ом при итерировании когда удалится элемент из _cubes. Подстройки перед вызовом функции под код внутри функции - печально. Постоянно дергать linq - печально.
Кулдаун не имеет смысла устанавливать в редакторе, так как после первого же обнуления он приравнивается 1. Не надо путать сам счётчик с его верхней границей. Нужна отдельная переменная.
Боже, хоть кто то заметил, я думал я один такой
Почему не включишь режим вима? Очень много работаешь мышкой, это все можно ускорить
KD-tree напрашивается для поиска ближайшего объекта
зачем нижнее подчеркивания в названии переменных?
Почему ты "служебные" методы поместил вначало а не в конец класса? По значимости они нулевые, когда файл открываешь каждый раз мотать вниз?
Менеджер кубов в апдейте не нуждается, тут надо сигналами работать. Если куб свободен, пусть посылает сигнал и вызывает поиск врага. Если куб сдох, пусть посылает сигнал, чтобы его могли удалить из списка. Нечего там апдейту делать.
Спойлер:
чувак переделал говнокод в еще больший говнокод с претензией на правильность
А тебя не смущает в методе расширения GetComponent вызываемый каждый кадр? Он насколько я знаю работает не так уж и быстро
Не каждый
Похоже джун не реализовался и открыл свой канал на ютубе)) Ты ТЗ выдал тебе на писали под твой ТЗ код, что не так?
Я думаю из-за того, что ты не захотел в этом видео разделять сущности, реализация CubeManager стала слишком мудрёной. Пока ты не начал добавлять методы расширения код и вправду стал очень понятным. Дальше мне кажется замудрил немного. Но Формат видео очень нравится. Жду выпуска про Бугаенко, очень интересно узнать твое мнение о нем.
"У мастера хороший код - единственный стиль", - японский Сенсей Аригоша Харидударь
В 360 код афигено видно
а почему только 360р?
Не лучше было бы в Cube поле с врагом заменить на рейкаст, а то выглядит очень странно?
Вы хотели мерседес по цене оки. Сколько платите то и получаете. 😁
Ошибка копипасты в 29-30 строчке в методе поиска ближайшего.
Можно было бы еще запоминать дальность от прошлого в переменную и с ней сравнивать. А еще квадрат магнитуды использовать вместо дистанции если хочется еще ускорить код )
Еще не уверен не будет ли просчитан куб у которого уже появился враг? мы выдаем текущему пустому кубу врага, и врагу говорим что мые го теперь враг. Но этот куб же дальше будет в листе свободных кубов в этом апдейте нет? Да и первый тоже останется. их по сути мне кажется удалять надо из листа заменив форич на фор.
Еще ошибка в кубе была. Просто переменную недопереименов кое-где
Что такое фасадирование?)
Всем привет!
Надеюсь, что тут есть знатоки, кто сможет подсказать: Какой конкретно вид платформера следующие игры - castle crashers, tmnt rescue palooza и т.д.
Вопрос конкретно в том, что это вроде как 2D платформер, но с возможностью вертикального перемещения или я совсем неправ?
Хочу попробовать игру создать такого типа, буду очень благодарен.
16:10 - почему паблик, почему не геттер и сеттер?
=> в Юнити не работает, это оператор Линк.
Nearby - читается "ниа-бай", а не "нёби"
12:58 почему _attackDistance и _speed объявлены как переменные, если они нигде не меняются? Их нужно было объявлять как константы.
readonly тоже самое считай
я не фрилансер, работаю на себя, но даже я лучше бы написал за спасибо😐, может поэтому я ничего не зарабатываю
Роман, как вам идея просто показать скорость времени компиляции кода фрилансера и вашего? Заранее спасибо
а какая разница сколько код компилируется?
@@reosfire возможно он имел ввиду перфоманс
я бы тоже хотел бы взглянуть на графики профайлера
Count() == 0, у тебя цикл по всей коллекции будет, лучше Any () == false
Такой вопрос. Не то чтобы я гений c#, но меня немного смущает сначала отбор через select, а потом хождение по всем трансформам. Ну, конечно по сравнению с тем что было это вообще не проблема. Но все таки может кто-то обьяснить, так действительно правильно делать, или лучше проходить через 1 цикл используя сразу трансформ
Ну вообще не очень такое корректно со стороны оптимизации. Там много таких штук
А с другой стороны если не требуется очень сильная оптимизация то почему нет(кстати вопрос как это дойдет до байт кода, там возможно умные алгоритмы шарпа развернут это дело в один красивый цикл)
Ты хотел типу var присвоить null? :)
Походу если после метода старт добавятся кубы на сцене, то старые кубы не будут их быть( А метод старт я так понял при инициализации объекта происходит
ManagerManager - ведь должен же кто-то контролировать этих менеджеров.
Я, будучи питонистом, немного обескуражен таким количеством вложенных итераторов, изменением размерности списка внутри цикла по нему, а так же наличием такого большого кол-ва повторяющихся проверок. будь этот скрипт написан на питоне, и в игре было бы 5 FPS от силы. Ну всё же я понимаю, что NNS - это вообще отдельная тема для разговора.
Ну c# явно быстрее питона, поэтому такое он может себе позволить)
Роман, хватит делать такие переходы. Смотреть невозможно, делай прямые склейки, так намного лучше
Closest всегда возвращает первый элемент списка, но это уже другая история KEKW
Aha, Classic.
Рефакторим код, делая из рабочего говна нерабочую конфетку.
Формат без говна намного приятнее, продолжай!
Код должен быстро и правильно работать. А с названиями переменных всем не угодишь)
Как говорил кто-то умный "ты не работаешь плохо, потому что тебе мало платят, а тебе мало платят, потому что ты работаешь плохо"
пиздеж, никто не будет платить дохуя просто за то что ты хорошо работаешь, можешь усраться ,но пока ты напрямую не скажешь - либо вы повышаете зарплату, либо я ухожу - никто тебе ничего не повысит
Ну, скажем так, твоя трудоспособность и трудолюбие подсознательно кореллируют с твоей самооценкой и твоими амбициями.
Если тебе или лень или сложна в "нормально делай - нормально будет" то и "доминируй, двигай тазом" тоже будет сложно и ты подсознательно согласишься с "да я говно, посему я готов работать за три копейки".
13:47 я б еще else if сделал одной инструкцией, не выделяя блок else и if отдельно, раз у if нет парного else, но тут уже на вкус и цвет, может показаться, что в одну инструкцию будет чуть менее читабельно и понятно, хоть и чуть короче и красивее визуально
Блин, это сильно повысит Аллоки, инициализации ексепшенов + линку которая тоже подбрасывает их.
предлагаю запретить if/for/while без фигурных скобок на законадательном уровне!
Вам python перейти языкe С блоки необходимы.
А может на 19:48 вместо Contains сделать !cube.HasEnemy? Ведь в another будут свободные кубы и если cube.HasEnemy будет false то это значит, что он находится в another.
Не проще вообще цикл foreach изменить таким образом:
...
if(!cube.HasEnemy)
throw new InvalidOperationException();
var nearby = others.First();
float minDistance = Vector3.Distance(cube.transfrom.position, nearby.transform.position);
foreach(var another in others) {
float distance = Vector3.Distance(cube.transfrom.position, another.transform.position);
if(distance < minDistance) {
nearby = another;
minDistance = distance;
}
}
...
minDistance можно инициализировать максимальным значением float или бесконечностью (вроде в C# есть такое понятие). Вроде выглядит намного лучше, тем более если инициализировать minDistance по другому. Хотя мне не самому не нравится cube.transform.position и т.д.
Так же метод findClosest является private и мы передаем в него IEnumerable без самого cube, но внутри проверяем чтобы его не было, для чего делается эта проверка? Мы же знаем, что передаем без cube. Это просто для себя?
И я заметил, что часто используют Linq, и хотел спросить, а это не долго? Ну вот в коде используется Linq, чтобы убрать сам куб из списка свободных, не проще в foreach просто пропускать его?
P.s. я C# учил несколько лет назад, и на нем уже давно ничего не писал, а с Unity ни разу не работал. И да писал в блокноте, скорей всего есть ошибки в коде, не стал вглядываться
У меня блин стилистика кода хорошая я знаю как делать не нужно, но я просто не могу программировать, я не знаю, что писать
надо сначала на отъебись делать, а потом рефакторить, или на карйний случай переписывать. По началу можно писать только быстро ИЛИ качественно.
Смотри другие каналы)
Кучу туториалов выполни и тогда придёт опыт. Ну свою стилистику и знания применяй.
Знать и уметь - это вообще разное.
Мечтаю, чтобы Рома купил код у меня да ещё и ошибки разобрал
Deep dark fantasy
По сравнению с предыдущими видосами этот на голову выше, т.к. видны рассуждения, которые приводят к хорошему коду
а что ты ожидал от кода за 500 рублей?
Философские рассуждения, какой бы ещё паттерн из ООП засунуть в этот кусочек кода
37:37
if(Vector3.Distance(another.position, another.position) < Vector3.Distance(another.position, another.position)) - лолчто?
У Ромы все всегда компилируется!
Ой да госпади мелочи, там такой хуйни валом. От события уничтоженого куба он не отписывается, для магического числа 0.1 он создал поле, но 0.1 так и осталось и т.д. Забей, не обращай внимание 😁
@@EvilYarik ну вот зачем, и зачем ты потратил свое время?каков позитивный момент?
@@DT-hn3xq , Что позитивозависимые наркоманы забыли на канале Ромы 😂? Вы не найдёте сдесь дозы, вам тут нечего ловить! Сама идея канала в нулевой терпимости к коду 😈. А я напротив посоветовал на мелочи внимания не обращать 😇.
@@EvilYarik простите моя ошибка,на лету нераспознал контекст
Ничерта непонятно, но очень интересно.
По-моему это уже код не на 500р в час, хотя не мне судить, я как раз пишу подобный говнокод как в начале...
Лайв гораздо понятнее😁
Рома когда про яндере дева проект
1. в проверке расстояния поломал логику
2. ближайший куб из списка - как-то нелогично, лучше ближайший из списка к кубу (cube.Closest(others))
14:08 "мы к этому вернёмся после менеджера" - вернулся? я, честно, пока смотрел уже забыл
Ну я понимаю, что сравнение нахождение дистанции между самим собой и проверка на то когда же она станет меньше самой себя это опечатка. Но блин. Называть метод Closest (где глагол?), запихивать в него геткомпонент и вызывать в апдейте это конечно мощно
@@PurpleDaemon_ до конца досмотри
@@PurpleDaemon_ еще кстати момент заметил. Он вызывает First(). По идее если число кубов будет нечетным, то последний куб, который будет искать себе пару вызовет First() для пустой коллекции (так как сам куб исключается) и вылетит эксепшн. Т.е. он отрефакторил по большей части все красивенько, но код теперь не работает
@@PurpleDaemon_ ну так он нагородил кучу исключений в методе расширения, чтобы потом еще проверки делать в апдейте? В результате рефакторинга все равно код как бы рабочий должен быть. Ну и здесь тесты как по мне излишни, да было бы лучше с ними, если это подразумевается как модуль для большой игры (Рома вроде что-то такое говорил), но на деле это как модуль не выглядит и близко
@@PurpleDaemon_ Наверное надо не забывать про 500 рублей в час. Если только "структурный рефакторинг" занял 30 минут, добавить сюда "сначала тесты писать", и получится, что решение задачи займет ..ну, допустим, час (конечно в "правильном" ее исполнении - как ожидалось за 500 рублей в час). Т.е. исполнитель оценивается в 8 * 500 * 20 = 80 тыс.рублей в месяц примерно (в наилучшем случае). ...не забываем еще вычесть налоги отсюда и, конечно, другие обязательные платежи :) .. т.е. в среднем выйдет где-то в районе 77 тыс в месяц. ...ну.. это в лучшем случае.. (когда ты по 8 часов 20 дней в месяц .. и 12 месяцев подряд)...
А так... конечно, если чисто для показать/посмотреть - всё очень красиво, правильно, весело, по-деловому и немного ошибок :)
7:04 Update писать двойной for это уже грех, FindTag :(( fps 0.1
за 500р простейшую игру какие там прайвиты, там же пять строк всего
Где драка кубиков???!
Скажите, почему public это плохо?
представь что твои органы стали public. это значит что в любой момент, без твоего ведома или разрешения у тебя могут что нибудь вырезать и не факт что что-то положат
Нарушение инкапсуляции, наверно
Я думал в начале хауди)
почему апдейт - приват?
поставь себе райдер
Зачем я это смотрю, я же джавист...
Кажется мой код хуже
Оооо да, 360p
да, только коддинг на 360 разбирать ну и графику можно