1) [RequireComponent(typeof(SpriteRenderer))]
[RequireComponent (typeof(Animator))] - можно в одном написать)
2) Проверку коллизий с монетами и аптечками я бы в отдельный компонент вынес.
3) if (collision.TryGetComponent(out EnemyDamager enemy))
_health.LoseHealth(enemy.Damage); - что у вас игрок мазахист какой-то? Зачем он сам себя бьет и создает для этого условия? Это врагу нужно ударить игрока, он пусть и проверяет, ищет и говорит игроку "я тебя ударил с таким-то уроном". Сам-то игрок врагов правильно бьет.Изменённый вариант: https://github.com/NoNameDeleted/PlatformerBattle/tree/bfdecb66eeb643dc8d023604bc78052c776bdca1
Мои комментарии по каждому пункту:
1) Для аниматора требуется спрайт рендер и можно не требовать спрайт рендерер заново если уже требуешь аниматор. Это не ошибка и по логике я всё написал правильно - в скрипте использовал два компонента и я потребовал два компонента. А то что написал ментор это что то из разряда топ 10 лайфхаков в юнити о которых вы точно не знали.
2) У меня в скрипте Player были две проверки коллизии при чём вместе проверка на подбор аптечек и проверка на столкновение с врагом. Я так понимаю логика в том чтобы по максимуму разгрузить ключевой компонент (Player, Enemy, PickUp) у каждого объекта и по максимуму всю логику вынести в отдельные компоненты (Mover, Collector, Patroller, Health, Attacker, Damager) В идеале ключевой компонент должен быть вообще пустой.
3) Программисты придумали огромное множество всяких инструментов (статическая типизация, тесты, IDE с подсказками, правила) которые помогают писать правильно и не допускать ошибок, но никакой инструмент никогда не сможет предостеречь от такой ошибки и ответить на вопрос Кто должен проверять столкновения - игрок "искать" врага и наносить себе урон от него или враг должен "искать" игрока и наносить ему урон? При условии что оба варианта в игре выглядят и работают абсолютно одинаково. И если для вас как и для ментора очевидно, что враг наносит урон и следовательно он обрабатывает взаимодействие с игроком, то надо вспомнить, что на уровне этих врагов может быть очень много и если каждый будет постоянно "искать" игрока, то это может повлиять на производительность, а игрок всегда один и следовательно если он будет обрабатывать взаимодействия с врагами, то это будет более оптимизированно.Таких примеров можно найти ещё очень много и всегда выбор: логика, красота, понятность и масштабируемость против оптимизации, веса и скорости.