КодПатруль #1: Unity, ИИ и ужасный код — разбор полётов

Разогревочный пример: логика в одну строку

Начнём с классического примера: попытки написать логику в одну строку, используя различные синтаксические приёмы. Результат часто оказывается малопонятным и трудночитаемым.

Рассмотрим пример: что-то настолько непонятное… закрыли логику кода вручную.

Разложим его на более многословную, но понятную конструкцию:

  1. Вычитание: сначала проверим условие: есть ли подключение и не пустая ли строка.
  2. Условие: если подключение есть и строка не пуста, запишем это в письмо. В противном случае вернём false.

Этот фрагмент можно сократить до:

return (подключение && строка != пустая строка);

Ещё один вариант, приближенный к исходному:

if (подключение && строка != пустая строка) return true; else return false;

Это уже более читаемо. Далее можно использовать тернарный оператор:

return (подключение && строка != пустая строка) ? true : false;

Можно ещё упростить, но приведенные варианты уже демонстрируют более читаемый код. Однако, в вариантах 1 и 2 дублируется код проверки подключение && строка != пустая строка. Это можно исправить, разделив код на две части: селектор данных и операцию. Например:

// Селектор данных
bool dataValid = (подключение && строка != пустая строка);

// Операция
return dataValid ? true : false; // или просто return dataValid;

Поиск и обновление объектов

Следующий пример – часто встречающаяся проблема с поиском и обновлением объектов. Попытки переписать такой код иногда приводят к ещё худшему результату.

Пример: ищутся объекты, представляющие машинки, и для каждой машинки создаётся отдельное поле. В апдейте с каждым объектом производится работа.

Оригинальный код предполагает наличие множества полей: … куча полей ….

Перепишем его. Во-первых, избавимся от множества полей, создав список cars:

List<GameObject> cars = new List<GameObject>();
// ... поиск объектов ...

Поиск можно реализовать циклом:

for (int i = 1; i <= 17; i++) {
  cars.Add(GameObject.Find("Машинка" + i));
}

В апдейте будем работать со списком cars:

foreach (GameObject car in cars) {
  // ... работа с каждым объектом ...
}

Однако, поиск объектов по имени – не самый эффективный способ. Лучше использовать теги или компонент. Создадим компонент, обрабатывающий движение машинок. Это позволит избежать поиска объектов по имени и централизовать управление скоростью, имитируя пробки и т.д.

Вместо множества отдельных компонентов для каждой машинки, лучше использовать один компонент для управления движением всех машинок. Можно найти все дочерние объекты, содержащие необходимый компонент, и управлять ими через этот родительский компонент.

Этот подход инкапсулирует логику движения и делает код более чистым и поддерживаемым.

Рассмотрели два примера плохого кода и переписали их. Присылайте свой код для разбора!

Что будем искать? Например,программа