#c# #unity3d #input-field
#c# #unity-игровой движок #поле ввода
Вопрос:
Я пытаюсь создать простой текстовый редактор в Unity.
Прямо сейчас я пытаюсь переопределить стандартную End функциональность клавиш клавиатуры.
Я использую «новую» систему пользовательского интерфейса и InputField
в качестве текстового редактора. В нем включена многострочность. Обычно, когда вы нажимаете End (на обычной физической клавиатуре), когда фокус находится на InputField
, курсор переходит в конец всего TextField
. Я хочу, чтобы оно доходило только до конца текущей строки. В принципе, я хочу ту же функциональность, что и в обычных текстовых редакторах, таких как Notepad .
На данный момент у меня есть скрипт на InputField
, который выглядит следующим образом:
public InputField editor; // This is the InputField
void Update()
{
if (Input.GetKeyDown(KeyCode.End))
{
string code = editor.text;
int caretPos = editor.caretPosition;
int newLineIndex = FindEndOfLine(code, caretPos);
editor.caretPosition = newLineIndex;
}
}
int FindEndOfLine(string text, int startIndex)
{
for (int i = startIndex; i < text.Length; i )
{
Debug.Log(text[i]);
if (text[i] == 'n')
{
Debug.Log("FOUND IT: " i);
return i;
}
}
return text.Length;
}
Если я использую это для другого ключа, например KeyCode.Y
, то это работает довольно хорошо. Он находит правильное положение курсора и перемещает курсор в это место. Однако затем он также печатает символ Y
.
Когда я использую KeyCode.End
и нажимаю End клавишу, она просто переходит к концу всего TextField
. Итак, я думаю, что мой код работает, но он выполняет обычную End функциональность ключа после выполнения моего скрипта.
Как мне предотвратить это поведение по умолчанию? Я гуглил в течение 25 минут.
Ответ №1:
Пожалуйста, попробуйте следующее решение. Вы должны унаследовать InputField
класс, переопределить Rebuild
метод, чтобы сохранить CaretPosition
и переопределить LateUpdate
метод, чтобы изменить поведение End ключа. Когда вы закончите, замените InputField
компонент на вашем GameObject
на ваш CustomInputField
скрипт.
using UnityEngine;
using UnityEngine.UI;
public class CustomInputField : InputField
{
private int oldCaretPosition;
public override void Rebuild(CanvasUpdate update)
{
base.Rebuild(update);
oldCaretPosition = caretPosition;
}
protected override void LateUpdate()
{
base.LateUpdate();
if (Input.GetKeyDown(KeyCode.End))
{
int newLineIndex = FindEndOfLine(oldCaretPosition);
caretPosition = newLineIndex;
}
}
private int FindEndOfLine(int startIndex)
{
for (int i = startIndex; i < text.Length; i )
{
if (text[i] == 'n')
{
return i;
}
}
return text.Length;
}
}
Комментарии:
1. Сработало как по волшебству. Я собираюсь погуглить это, но не могли бы вы вкратце объяснить, что делают методы LateUpdate и Rebuild и почему мне нужно поместить обработчик KeyDown сюда, а не как отдельный скрипт?
2. Итак, логика следующая. Прежде всего, нам нужно сохранить положение курсора, прежде чем он будет перемещен в конец текста. Я попытался найти метод, который можно было бы переопределить и сохранить положение курсора. Оказалось, что
Rebuild
метод подходит для этой цели. Я выбрал этот метод только по моему предположению. Как говорится в документации,Rebuild
метод перестраивает геометрию полей ввода. (курсор и выделение).LateUpdate
вызывается после того, как были вызваны всеUpdate
функции. Таким образом, это дает мне возможность переместить курсор в конец строки после того, как он был перемещен в конец текста.