3 разных реализации одной и той же задачи в Unity на C#

3 разных реализации одной и той же задачи в Unity на C#

Роман Сакутин

4 года назад

20,021 Просмотров

Ссылки и html тэги не поддерживаются


Комментарии:

DATUMonsta
DATUMonsta - 09.04.2023 01:38

Ни один из.

Ответить
RedPakc
RedPakc - 25.01.2023 14:45

3 вариант лучше всего, но то что мы монетку обозначаем через пустой компонент а не тег меня немного напрягает

Ответить
Александр Чудин
Александр Чудин - 07.12.2022 02:30

По моему если брать в учёт условия игры, просто бегать и подбирать монетки тогда лучше кончено 3й вариант, т.к. не вижу необходимости во втором классе. Если мы говорим про какую-то рпг в которой могут быть монетки с разным весом по типу монетка/мешочек/брилиант тогда лучше 2й вариант ну и в рпг монетки могут иметь более глубокий смысл и им будет нужен отдельный класс, поправьте если где-то ошибся

Ответить
qqew
qqew - 27.08.2022 15:13

второй лучше

Ответить
Mark Nemirovich
Mark Nemirovich - 26.08.2022 09:45

3й вариант лучший, если его немного доработать. Вместо Coin использовать абстрактный класс-родитель с необходимым полем (public readinly Cost/Value/Worth) или вообще константой, которую при подборе будет считывать кошелёк. И от абстрактоного класса уже реализовывать наследников Coin, Bill и т. д.

Ответить
Fix 'Y
Fix 'Y - 12.09.2021 21:46

Первая наверное

Ответить
ILLIA VOLHA
ILLIA VOLHA - 05.03.2021 00:53

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

Ответить
Xalu Dadayev
Xalu Dadayev - 17.02.2021 02:37

Прочтите книгу "Чистый код" Роберт Мартин. По этой книге самый оптимальный это второй.

Ответить
Ярослав
Ярослав - 10.02.2021 10:20

я бы делал через интерфейс, это было бы и правильно и красиво

Ответить
Modjaid
Modjaid - 05.02.2021 11:51

работаю с юнити год, я походу синьор)

Ответить
Life is a prank
Life is a prank - 30.01.2021 21:33

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

Ответить
BlinderAffe
BlinderAffe - 21.01.2021 15:53

Второе самое понятное.

Ответить
Artem Semiletov
Artem Semiletov - 02.11.2020 08:35

Во втором примере не нужен Бехавер, там же ничего из него не берётся, а нагрузка от него лишняя.
Можно создавать объект класса в скрипте игрока, а триггер монетки проверять на компонент игрока.
Тогда можно использовать второй вариант.
А так третий, чтобы не было разбиения логики... хотел сказать бы я, но нафига там out Coin coin, лол.

Ответить
LinDahai88
LinDahai88 - 27.10.2020 20:17

ИМХО. Я бы вынес OnTriggerEnter/Exit в отдельный компонент CollisionDetector и сделал бы вызов UnityEvent'ов по этим событиям. А дальше уже у кошелька паблик метод Add(Coin coin). Так получается избавиться от юнитийных грязностей в коде который отвечает за игровую логику.

Ответить
Евгений Куликов
Евгений Куликов - 03.09.2020 00:01

Я к программированию имею такое же отношение, как пружины в сиденье к старту двигателя, но третий кажется более логичным. Как я понимаю, в нём движущийся объект (игрок) определяет, с чем он столкнулся и исходя из этого добавляет что-то куда-то или нет.
Подбирать, скорее всего, рано или поздно понадобится не только монеты. Да и триггер может не только на подбираемых вещах находиться. Тогда вместо того, чтобы в каждый новый класс дописывать код, можно будет скопипастить код подбора монеты в том же самом методе OnTriggerEnter, но поменять параметры (не Coin, а FirstAid, например. И не AddCoin, а RestoreHealth какое-нибудь.

Ответить
VoidPtr
VoidPtr - 24.08.2020 23:55

Я считаю что 2 вариант отлично подойдёт гиперказуальным играм, где по сцене кроме игрока никто не движется или если и движется - то не пересекается с триггером монеты. Но если на сцене будет множество монет и множество движущихся оппонентов - то каждое вхождение в триггер стороннего компонента - будет снижать производительность, ведь GetComponent - высокой производительностью не славиться.
В таком случае - я бы применил 1 вариант + в него можно добавить проверку на то, попал ли в триггер враг.
Если объектов, которые могут пересечься с монетой и самих монет - много, но игра не заканчивается на столкновении игрока с любым объектом - то можно применить 3ий вариант.

Мой итог таков: каждый из семплов кода подойдёт для определённой ситуации

Ответить
Алексей Федоров
Алексей Федоров - 30.06.2020 00:13

Третий вариант. Если ещё сделать AddCoin private, то тогда точно можно быть уверенным, что нам никто случайно не подкинет монеток из другого места🙂

Ответить
Владислав Богер
Владислав Богер - 27.04.2020 12:41

Второе решие для меня самое разумное

Ответить
Light in The dark
Light in The dark - 17.03.2020 20:51

Все эти способы не полноценны потому что нет удаления монетки

Ответить
Ilya M
Ilya M - 19.02.2020 11:20

я бы начал говнокодить с 1го, чтобы не делать преждевременных усложнений. 3ий вариант не ок, т.к. может появится какой-нибудь мешок монет, его пришлось бы if-ами вытаскивать из other collider-а. Так что можно остановиться на 2ом наверное. edit: но вообще в разных ситуациях может разное быть правильным. Если известно что железнобетонно будет один вид монеты, то почему бы и не 3ий вариант, идеально правильную архитектуру все равно не выстроить, либо придется обкладываться паттернами и делать код нечитаемым. везде trade-off-ы

Ответить
Дмитрий Котусев
Дмитрий Котусев - 06.02.2020 15:54

Мне логичней видится 3-й вариант. Монетка не должна следить за тем, чтобы её кто-то подобрал, тот, кто инициирует действие, и должен обрабатывать подбор. Ну вот если бы монету можно было бы не только подбирать, а делать с ней что-то ещё, например, стрелять по ней, она тогда тоже должна будет попадание в саму себя хэндлить? Ну мне это кажется корявым.

Ответить
ezd
ezd - 26.01.2020 07:12

Зависит от того что дальше планируется делать с этим. Система эвентов вообще, без относительно юнити это или нет, означает что это "сквозной функционал". И наоборот, если нужен сквозной функционал, не относящийся напрямую к классу, то его лучше вынести. Удобство очевидно - несвязанный функционал отдельно. Минус не сразу очевиден - трудность в отладке. Когда эвентов становится много, то трудно отлавливать где чего вызывается и ловится. Поэтому тут нужна какая-то система слежения за ними. Я не знаю идеального варианта, я предпочитаю делать где-то список эвентов и там же хранить обработку. То есть тут должен быть отдельно обработчик который добавляет монетку куда-нибудь, но ни в монетке, ни в кошельке, ни в самом игроке.

Ответить
Roman 13
Roman 13 - 24.01.2020 01:59

Вообще должны быть абстракции - "Подбираемое" и "подбиратель" и они должны взаимодействовать между собой. Монетка не должна нести логику, только свойство - ее ценность.
А вообще вот тебе одна из! простых "определялок":
Как определить кто перед тобой: Джун или Мидл/Сеньер ?, дай ему простую задачу, джун выдаст сложное решение, а М/С простое/элегантное. Как определить кто перед тобой: Мидл или Сеньор?, дай ему сложную задачу, мидл выдаст сложное решение, а сеньор простое/элегантное.

Ответить
Link
Link - 22.01.2020 20:26

2-ой вариант лучше.
Третий вариант можно немного изменить, чтобы игрок подбирал монету, и добавлял счёт в кошелёк. + кошелёк уже не будет наследоваться от MonoBehaviour.

Ответить
nicetofaq
nicetofaq - 22.01.2020 17:44

класс, поел и посмотрел что-то полезное, вот таких сравнений кодов мне не хватает.
Кто-нибудь может посоветовать такие же видео?

Ответить
Игорь Поляков
Игорь Поляков - 22.01.2020 14:20

в стоимости

Ответить
Богдан Лошинський
Богдан Лошинський - 22.01.2020 10:01

Второй вариант действительно лучше всего и выглядит, и спроектирован. В объектах не смешано поведение, которое было бы корректнее разделить. Плюс во втором варианте удобно расширять класс кошелька и добавить в него, к примеру, хранение каких-то драгоценностей или ещё чего. Первый вариант вообще жесть, S.O.L.I.D. тихо плачет в сторонке. Даже ради простоты мне кажется, что проектировать столь комплексные классы чревато и потом в этом всём коде будет сложно разобраться. Третий вариант относительно нейтрален, однако событие подбора монеты не должно храниться в кошельке, это ведь никак с ним не связано.

Ответить
Иван Иванов
Иван Иванов - 22.01.2020 08:03

Ничо не понял, но интересно.

Ответить
Dmitriy Gavrilenko
Dmitriy Gavrilenko - 21.01.2020 14:32

Топлю за второй вариант с точки зрения проектирования. Конечно подвязка на события юнити так себе устроена, но как минимум можно выделить интерфейс IPickupable и подбирать уже не только монетки, но и бумажки. Я не знаю как правильно работать с Юнити (ковырялся в ней лет 7 назад), но важно понимать, какой вариант более производительнее, второй или третий. Один кошелек будет треггерить на все подряд и реагировать на монетки или на каждой монетке будет свой триггер. Что скажешь Роман? Есть разница в производительности?

Ответить
Stanislav Zatolokin
Stanislav Zatolokin - 21.01.2020 14:12

В 1 и 2 варианте монетка отслеживает всех, кто в нее попадает и срабатывает тогда, когда это кошелек. Мне кажется, всё же, лучше 3 вариант, когда кошелек отслеживает собрал ли он монетку, нежели монетки будут это делать. Конечно в большинстве случаев разницы не будет, но вдруг игрок на какое-то время не сможет собирать монетки(по каким-то геймплейным причинам), тогда соответственно кошелька на сцене не будет и монетки не будут производить лишний код. Хотя конечно в плане читаемости и разделения обязанностей 2 вариант смотрится симпатично. Если я не прав, а я действительно не знаю что делают с производительностью функции OnTriggerEnter, напишите пожалуйста

Ответить
Gulyaev Viktor
Gulyaev Viktor - 21.01.2020 14:07

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

Ответить
Wolf From The Woods
Wolf From The Woods - 21.01.2020 14:00

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

Ответить
Andrey Kidin
Andrey Kidin - 21.01.2020 13:44

Как по мне 2й самый удобный...
Class для монеты, Class для кошелька. Всё структурированно никакой путаницы.
Удобно расширять в случае необходимости (которая как правило возникает)

Ответить
Ericetto
Ericetto - 21.01.2020 13:35

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

Ответить