Как лучше спроектировать индикацию состояния в Unity, C#
Столкнулся со сверх тривиальной задачей, которая поставила меня в тупик. Есть 4 состояния, и есть некий прибор, который их отображает. В моем случае это классический селектор АКПП (без М режима). 4 состояния уже определены, их трогать нельзя. Если машина заведена, то горит одна из лампочек, а заглушена, то все лампочки не горят. И вот очень чешутся руки SOLID не нарушить. Первый способ, как это можно реализовать:
using UnityEngine;
namespace Core.Car
{
public class TransmissionSelector : MonoBehaviour
{
[SerializeField] private LightFixture _p;
[SerializeField] private LightFixture _r;
[SerializeField] private LightFixture _n;
[SerializeField] private LightFixture _d;
public bool Enabled { get; set; }
public TransmissionMode TransmissionMode { get; set; }
private void Update()
{
_p.SetLight(TransmissionMode == TransmissionMode.PARKING && Enabled);
_r.SetLight(TransmissionMode == TransmissionMode.REVERSE && Enabled);
_n.SetLight(TransmissionMode == TransmissionMode.NEUTRAL && Enabled);
_d.SetLight(TransmissionMode == TransmissionMode.DRIVING && Enabled);
}
}
}
Но данный код очень... прямолинейный. Хардкод. Никакой расширяемости. Пришла в голову другая идея, сделать два скрипта, первый - это универсальный селектор, а второй - лампочка, которая помнит состояние, на которое она реагирует и состояние включенности.
Класс селектора:
using UnityEngine;
namespace Core.Car
{
public class TransmissionSelector : MonoBehaviour
{
[SerializeField] private TransmissionSelectorLamp[] _lamps;
public bool Enabled { get; set; }
public TransmissionMode TransmissionMode { get; set; }
private void Update()
{
foreach (var lamp in _lamps)
{
lamp.Enabled = Enabled;
lamp.CurrentMode = TransmissionMode;
}
}
}
}
Класс лампочки:
using UnityEngine;
namespace Core.Car
{
[RequireComponent(typeof(LightFixture))]
public class TransmissionSelectorLamp : MonoBehaviour
{
[SerializeField] private TransmissionMode _mode;
private LightFixture _lamp;
public TransmissionMode CurrentMode { private get; set; }
public bool Enabled { private get; set; }
private void Awake()
{
_lamp = GetComponent<LightFixture>();
}
private void Update()
{
_lamp.SetLight(_mode == CurrentMode && Enabled);
}
}
}
И вот в чем проблема. Лампочка теперь знает, на какой сигнал она загорается! Это ужасное архитектурное решение. Зато расширяемое.
Оба эти решения больны тем, что имеется данная запись:
TransmissionMode == SomeMode && Enabled
Здесь уже нарушение человеческой логики! В одном логическом выражении состояние включенности и сравнение состояния режима трансмиссии. Это как говорить, что "Я подпрыгну, если у тебя красное яблоко и свет включен". Нерационально.
Вопрос. Как быть? Какой вариант оставить? Или есть нормальное решение данного вопроса?