Как спроектировать архитектуру для персонажей с разными типами боя
Что проверяют
Умеете ли вы уйти от наследования к композиции, когда вариантов поведения становится много. Интервьюеру важно, выдержит ли ваша схема персонажа, который сочетает ближний бой и магию, и сможет ли геймдизайнер менять баланс без программиста. Следом обычно спрашивают, как добавить новый тип атаки, не трогая существующий код.
Как отвечать
Начните с того, почему прямое наследование (Warrior, Archer, Mage от Character) не работает: гибриду нужно множественное наследование, которого у классов C# нет, а общий код расползается по базовому классу. Дальше каркас:
- стратегия атаки: интерфейс
IAttackс методом вродеExecute(AttackContext ctx), реализацииMeleeAttack,ProjectileAttack,SpellAttack. Персонаж держит одну или несколько атак и выбирает между ними; - композиция: в Unity персонаж собирается из компонентов (здоровье, передвижение, набор способностей, выбор цели). Урон получает всё, что реализует
IDamageable, будь то враг, ящик или щит; - данные отдельно от логики: параметры атаки (урон, дальность, перезарядка, анимация) лежат в
ScriptableObjectили конфиге, и балансом занимается дизайнер; - поведение: смену режимов (преследование, атака, отступление) удобно вести конечным автоматом или деревом поведения, а не цепочкой
if; - связь с остальной игрой: события вроде
OnHitиOnDeathдля звука, эффектов и UI, чтобы атака ничего не знала про интерфейс.
Если осталось время, скажите про производительность: снаряды берутся из пула объектов, а не создаются через Instantiate на каждый выстрел.
Где спотыкаются
Пишут switch по enum типа боя внутри Character. Каждый новый тип меняет этот класс, и через полгода в нём тысяча строк.
Хранят состояние боя, например текущую перезарядку, прямо в ScriptableObject. Ассет общий, поэтому перезарядка одного персонажа блокирует всех, а в редакторе значения ещё и сохраняются после выхода из Play Mode.
Показывают стратегию из учебника, где Attack() пишет строку в консоль, и не объясняют, откуда атака знает о цели, дистанции и аниматоре. Без контекста атаки паттерн выглядит декорацией.