это вопрос программирования C # в игровом движке Unity, но это может быть эксперт-делегат C # без опыта Unity, может знать, что я делаю неправильно?(Я уже писал на форуме Unity).
Я пытаюсь передать произвольную функцию для вызова внутри фиксированной функции, которая сама вызывается с использованием ключевого слова делегата через функцию AddListener
события InputField.onEndEdit
,Я новичок в делегатах, но, как я понимаю, мне нужно создать нового делегата, чтобы сделать это, и я немного запутался, прочитав несколько статей о делегатах, которые все еще застряли.В настоящее время код компилируется, но появляется ошибка ArgumentException
.К сожалению, с полной трассировкой стека в Unity Editor, это все трассировка стека, которую я получаю:
ArgumentException: Value does not fall within the expected range.
CharacterController3D..ctor () (at Assets/Entities/DungeonCell/Priest/CharacterController3D.cs:95)
Где имя сценария CharacterController3D.cs
.Конструктор строки 95 в этом классе, генерирующий эту ошибку:
Del marySuccess = question.MarySuccess;
Конечная цель: когда игрок вводит ответ на произвольный вопрос, заданный, когда игрок вызывает его в игре, функция ProcessAnswerвызовет пользовательскую функцию, обрабатывающую правильный ответ на каждый вопрос, т.е. каждый вопрос будет иметь свою функцию, связанную с правильным ответом.Аналогичным образом, функция ProcessAnswer будет вызывать другую пользовательскую функцию для этого вопроса, если игрок дает неправильный ответ и т. Д.
Ниже приведена функция ProcessAnswer с произвольным делегатом, переданным ей delegate1
, который в следующем коде выполняетсякогда дан правильный ответ:
private void ProcessAnswer (InputField input, string answer, float clockStart, Del delegate1)
{
if (String.Equals(answer, input.text.Trim(), StringComparison.OrdinalIgnoreCase)) // trim trailing spaces, accept any case in letters typed
{
countdownTimer.enabled = false; // stops timer
float timePoints = Mathf.Round(2000/(clockStart - countdownTimer.TimeStoppedTenthsSecond()));
delegate1();
}
else ....
Вышеупомянутая функция вызывается в том же скрипте следующим образом:
string answer = "grace";
clockStart = 90f;
inputField.onEndEdit.AddListener(delegate { ProcessAnswer(inputField, answer, clockStart, marySuccess); });
, где marySuccess
- параметр делегата в этом случае, определяемый как:
private delegate void Del();
Del marySuccess = question.MarySuccess;
Все еще в этом же скрипте, question
здесь объявлен как статический экземпляр отдельного скрипта компонента для того же объекта.Я понял, что должен сделать его статическим, чтобы делегат ссылался на него, в любом случае он не работал как нестатический:
private static Questions question;
и инициализировался в методе Awake, все в том же сценарии:
question = this.GetComponent<Questions>();
EDIT В качестве комментариев извинения за отсутствие самого кода метода MarySuccess (), который имеет ту же подпись, что и объявление делегата (без параметров, возвращает void):
public void MarySuccess()
{
string phrase1 = "a";
string phrase2 = "b";
string phrase3 = "c";
string phrase4 = "d";
thoughtText.color = new Color(0.55f, 0f, 0.03f); // now matches (141,0,8) colour of input text, was Color.red;
thoughtText.fontSize = 22;
StartCoroutine(player.FillThoughtBox(phrase1, 3, phrase2, 3, phrase3, 5, phrase4));
playerInputPanel.SetActive(false);
player.Invoke("MaryHailed", 10f);
Invoke("HideThoughtPanel", 22f);
}
// use Invoke() with desired delay, so that player can start moving and have more time to read the words before it disappears
private void HideThoughtPanel()
{
thoughtButtonPanel.SetActive(false);
}
РЕДАКТИРОВАТЬ2
Я проверил даже с public void MarySuccess () {}
пусто, все равно выдает ту же ошибку исключения.
Любые предложения очень благодарны, спасибо!