Комментарии:
Ни один из.
Ответить3 вариант лучше всего, но то что мы монетку обозначаем через пустой компонент а не тег меня немного напрягает
ОтветитьПо моему если брать в учёт условия игры, просто бегать и подбирать монетки тогда лучше кончено 3й вариант, т.к. не вижу необходимости во втором классе. Если мы говорим про какую-то рпг в которой могут быть монетки с разным весом по типу монетка/мешочек/брилиант тогда лучше 2й вариант ну и в рпг монетки могут иметь более глубокий смысл и им будет нужен отдельный класс, поправьте если где-то ошибся
Ответитьвторой лучше
Ответить3й вариант лучший, если его немного доработать. Вместо Coin использовать абстрактный класс-родитель с необходимым полем (public readinly Cost/Value/Worth) или вообще константой, которую при подборе будет считывать кошелёк. И от абстрактоного класса уже реализовывать наследников Coin, Bill и т. д.
ОтветитьПервая наверное
ОтветитьТо чувство когда ты смотришь это видео на смартфоне и в комнату зашли люди на словах про пенис, яички и ствол😖😖😖
ОтветитьПрочтите книгу "Чистый код" Роберт Мартин. По этой книге самый оптимальный это второй.
Ответитья бы делал через интерфейс, это было бы и правильно и красиво
Ответитьработаю с юнити год, я походу синьор)
ОтветитьИнтуитивно как то хочется три класса и чтобы онтриггерентер висел на игроке, а он дальше вызывал события в кошельке, но с таким подходом наверн класс плеера будет перегружен всяким. Хазе.
ОтветитьВторое самое понятное.
ОтветитьВо втором примере не нужен Бехавер, там же ничего из него не берётся, а нагрузка от него лишняя.
Можно создавать объект класса в скрипте игрока, а триггер монетки проверять на компонент игрока.
Тогда можно использовать второй вариант.
А так третий, чтобы не было разбиения логики... хотел сказать бы я, но нафига там out Coin coin, лол.
ИМХО. Я бы вынес OnTriggerEnter/Exit в отдельный компонент CollisionDetector и сделал бы вызов UnityEvent'ов по этим событиям. А дальше уже у кошелька паблик метод Add(Coin coin). Так получается избавиться от юнитийных грязностей в коде который отвечает за игровую логику.
ОтветитьЯ к программированию имею такое же отношение, как пружины в сиденье к старту двигателя, но третий кажется более логичным. Как я понимаю, в нём движущийся объект (игрок) определяет, с чем он столкнулся и исходя из этого добавляет что-то куда-то или нет.
Подбирать, скорее всего, рано или поздно понадобится не только монеты. Да и триггер может не только на подбираемых вещах находиться. Тогда вместо того, чтобы в каждый новый класс дописывать код, можно будет скопипастить код подбора монеты в том же самом методе OnTriggerEnter, но поменять параметры (не Coin, а FirstAid, например. И не AddCoin, а RestoreHealth какое-нибудь.
Я считаю что 2 вариант отлично подойдёт гиперказуальным играм, где по сцене кроме игрока никто не движется или если и движется - то не пересекается с триггером монеты. Но если на сцене будет множество монет и множество движущихся оппонентов - то каждое вхождение в триггер стороннего компонента - будет снижать производительность, ведь GetComponent - высокой производительностью не славиться.
В таком случае - я бы применил 1 вариант + в него можно добавить проверку на то, попал ли в триггер враг.
Если объектов, которые могут пересечься с монетой и самих монет - много, но игра не заканчивается на столкновении игрока с любым объектом - то можно применить 3ий вариант.
Мой итог таков: каждый из семплов кода подойдёт для определённой ситуации
Третий вариант. Если ещё сделать AddCoin private, то тогда точно можно быть уверенным, что нам никто случайно не подкинет монеток из другого места🙂
ОтветитьВторое решие для меня самое разумное
ОтветитьВсе эти способы не полноценны потому что нет удаления монетки
Ответитья бы начал говнокодить с 1го, чтобы не делать преждевременных усложнений. 3ий вариант не ок, т.к. может появится какой-нибудь мешок монет, его пришлось бы if-ами вытаскивать из other collider-а. Так что можно остановиться на 2ом наверное. edit: но вообще в разных ситуациях может разное быть правильным. Если известно что железнобетонно будет один вид монеты, то почему бы и не 3ий вариант, идеально правильную архитектуру все равно не выстроить, либо придется обкладываться паттернами и делать код нечитаемым. везде trade-off-ы
ОтветитьМне логичней видится 3-й вариант. Монетка не должна следить за тем, чтобы её кто-то подобрал, тот, кто инициирует действие, и должен обрабатывать подбор. Ну вот если бы монету можно было бы не только подбирать, а делать с ней что-то ещё, например, стрелять по ней, она тогда тоже должна будет попадание в саму себя хэндлить? Ну мне это кажется корявым.
ОтветитьЗависит от того что дальше планируется делать с этим. Система эвентов вообще, без относительно юнити это или нет, означает что это "сквозной функционал". И наоборот, если нужен сквозной функционал, не относящийся напрямую к классу, то его лучше вынести. Удобство очевидно - несвязанный функционал отдельно. Минус не сразу очевиден - трудность в отладке. Когда эвентов становится много, то трудно отлавливать где чего вызывается и ловится. Поэтому тут нужна какая-то система слежения за ними. Я не знаю идеального варианта, я предпочитаю делать где-то список эвентов и там же хранить обработку. То есть тут должен быть отдельно обработчик который добавляет монетку куда-нибудь, но ни в монетке, ни в кошельке, ни в самом игроке.
ОтветитьВообще должны быть абстракции - "Подбираемое" и "подбиратель" и они должны взаимодействовать между собой. Монетка не должна нести логику, только свойство - ее ценность.
А вообще вот тебе одна из! простых "определялок":
Как определить кто перед тобой: Джун или Мидл/Сеньер ?, дай ему простую задачу, джун выдаст сложное решение, а М/С простое/элегантное. Как определить кто перед тобой: Мидл или Сеньор?, дай ему сложную задачу, мидл выдаст сложное решение, а сеньор простое/элегантное.
2-ой вариант лучше.
Третий вариант можно немного изменить, чтобы игрок подбирал монету, и добавлял счёт в кошелёк. + кошелёк уже не будет наследоваться от MonoBehaviour.
класс, поел и посмотрел что-то полезное, вот таких сравнений кодов мне не хватает.
Кто-нибудь может посоветовать такие же видео?
в стоимости
ОтветитьВторой вариант действительно лучше всего и выглядит, и спроектирован. В объектах не смешано поведение, которое было бы корректнее разделить. Плюс во втором варианте удобно расширять класс кошелька и добавить в него, к примеру, хранение каких-то драгоценностей или ещё чего. Первый вариант вообще жесть, S.O.L.I.D. тихо плачет в сторонке. Даже ради простоты мне кажется, что проектировать столь комплексные классы чревато и потом в этом всём коде будет сложно разобраться. Третий вариант относительно нейтрален, однако событие подбора монеты не должно храниться в кошельке, это ведь никак с ним не связано.
ОтветитьНичо не понял, но интересно.
ОтветитьТоплю за второй вариант с точки зрения проектирования. Конечно подвязка на события юнити так себе устроена, но как минимум можно выделить интерфейс IPickupable и подбирать уже не только монетки, но и бумажки. Я не знаю как правильно работать с Юнити (ковырялся в ней лет 7 назад), но важно понимать, какой вариант более производительнее, второй или третий. Один кошелек будет треггерить на все подряд и реагировать на монетки или на каждой монетке будет свой триггер. Что скажешь Роман? Есть разница в производительности?
ОтветитьВ 1 и 2 варианте монетка отслеживает всех, кто в нее попадает и срабатывает тогда, когда это кошелек. Мне кажется, всё же, лучше 3 вариант, когда кошелек отслеживает собрал ли он монетку, нежели монетки будут это делать. Конечно в большинстве случаев разницы не будет, но вдруг игрок на какое-то время не сможет собирать монетки(по каким-то геймплейным причинам), тогда соответственно кошелька на сцене не будет и монетки не будут производить лишний код. Хотя конечно в плане читаемости и разделения обязанностей 2 вариант смотрится симпатично. Если я не прав, а я действительно не знаю что делают с производительностью функции OnTriggerEnter, напишите пожалуйста
ОтветитьЯ бы выбрал первый вариант. Так как не**й усложнять всё на свете. Выделить в отдельный классы можно всегда. Ну конеееечно если хотите правильный и красивый код то второй вариант. Я бы ещё использовал третий для редких вещей, для ачивок или что то подобного.
ОтветитьНедавно только начал задумываться чтоб делать так, как во втором варианте. До этого всегда писал условно первый вариант. И даже не задумывался, что можно по другому это сделать)
ОтветитьКак по мне 2й самый удобный...
Class для монеты, Class для кошелька. Всё структурированно никакой путаницы.
Удобно расширять в случае необходимости (которая как правило возникает)
Хотелось бы как можно больше таких сравнений разных подходов, можно прям в отдельную еженедельную рубрику вывести. И еще хотелось бы посмотреть про тестирование
Ответить