Как сократить кол-во строк с "повторяющимися" функциями для кнопок Unity
У меня есть 10 кнопок. Нажав на каждую меняется текст. Вопрос заключается в том, можно ли как-то сократить кол-во функций и строк?
Мой код:
public void PreceptView()
{
PreceptViewManager("Заповедь №1\nСатана олицетворяет потворство, а не в-здержание!");
}
public void PreceptView1()
{
PreceptViewManager("За-ВедЬ №2\nСатана оли-цеоотворяет жизненную суть вместо несбыточных духовных мечтаний.");
}
public void PreceptView2()
{
PreceptViewManager("Заповedь №3\nSatan олицетворяет неOsквернённую мудрость вместо лицемерного самообмана!");
}
...
Ответы (2 шт):
Реализация через константы + enum + switch-case
Записи о заповедях хранятся в константах, в инспекторе нужно закрепить скрипт, и выбрать нужную заповедь через enum, на обьекте со скриптом должен быть Button, при старте он подпишиться на событие нажатия и вызовит метод используя выбранное enum значение через switch-case
private const string PRECEPT_1 = "Заповедь 1";
private const string PRECEPT_2 = "Заповедь 2";
private const string PRECEPT_3 = "Заповедь 3";
private const string PRECEPT_NULL = "Заповедь не обнаружена";
private Button _button;
[SerializeField] private PreceptNumber _preceptNumber;
public enum PreceptNumber
{
Precept1,
Precept2,
Precept3
}
public void Start()
{
_button = GetComponent<Button>();
_button.onClick.AddListener(ButtonClickHandler);
}
public void Destroy()
{
_button.onClick.RemoveListener(ButtonClickHandler);
}
public void ButtonClickHandler()
{
string message = "";
switch (_preceptNumber)
{
case PreceptNumber.Precept1:
message = PRECEPT_1;
break;
case PreceptNumber.Precept2:
message = PRECEPT_2;
break;
case PreceptNumber.Precept3:
message = PRECEPT_3;
break;
default:
message = "PRECEPT_NULL;
break;
}
PreceptViewManager(message);
}
Реализация через Dictionary<>
Вариант через словари, заполняем заранее заповеди, можно и в любой другой момент, показан для примера инициализация сразу
private Dictionary<PreceptNumber, string> _preceptMap =
new Dictionary<PreceptNumber, string>()
{
[PreceptNumber.Precept1] = "Заповедь 1",
[PreceptNumber.Precept2] = "Заповедь 2",
[PreceptNumber.Precept3] = "Заповедь 3",
[PreceptNumber.Precept4] = "Заповедь 4",
[PreceptNumber.Precept5] = "Заповедь 5",
};
private Button _button;
[SerializeField] private PreceptNumber _preceptNumber;
[System.Serializable]
public enum PreceptNumber
{
Precept1,
Precept2,
Precept3,
Precept4,
Precept5
}
public void Start()
{
_button = GetComponent<Button>();
_button.onClick.AddListener(ButtonClickHandler);
}
public void Destroy()
{
_button.onClick.RemoveListener(ButtonClickHandler);
}
public void ButtonClickHandler()
{
PreceptViewManager(_preceptMap[_preceptNumber]);
}
Реализация без хранения данных
Вызов через заполнение поля в инспекторе, заповеди нигде не хранятся
private Button _button;
[SerializeField] private string _precept;
public void Start()
{
_button = GetComponent<Button>();
_button.onClick.AddListener(ButtonClickHandler);
}
public void Destroy()
{
_button.onClick.RemoveListener(ButtonClickHandler);
}
public void ButtonClickHandler()
{
PreceptViewManager(_precept);
}
Использование enum позволяет удобно выбирает в инспекторе значение, исключает вероятность случайных ошибок
Самый простой вариант - создать словарь, у которого в качестве ключа будут номера заповедей, а в качестве значения - тексты заповедей:
private Dictionary<int, string> _precepts;
Затем при старте скрипта инициализируете этот словарь:
public void Start()
{
_precepts = new()
{
[1] = "Заповедь 1 ...",
[2] = "Заповедь 2 ...",
};
// или же можно инициализировать словарь из json-файла, если эти данные вам пригодятся и вне этого класса
}
Затем осталось использовать его:
public void PreceptView(int preceptNumber)
{
PreceptViewManager(_precepts[preceptNumber]);
}
P.S.
Не уверен, будет ли это так работать, но если вы установите этот ассет, то, возможно, вы сможете, вместо вписывания номера заповеди в инспекторе, выбирать номер из списка:
public void PreceptView([Dropdown(nameof(_precepts) + ".Keys")] int preceptNumber)
{
PreceptViewManager(_precepts[preceptNumber]);
}
