То, что я пытаюсь понять и изучить здесь, является очень простой вещью: каков наиболее общий и наиболее удобный способ правильно различать одиночные и двойные щелчки для 3 основных кнопок мыши в Unity с использованием C #?
Мой акцент на слове правильно не зря. Хотя я был удивлен, что об этом, кажется, никогда раньше не спрашивали на этом сайте, конечно, я искал и нашел множество похожих вопросов на форумах Unity и собственных страницах вопросов-ответов Unity. Однако, как это часто бывает с ответами, размещенными на этих ресурсах, все они казались либо просто ошибочными, либо, по крайней мере, слишком любительскими.
Позволь мне объяснить. Предлагаемые решения всегда имели один из двух подходов и соответствующие им недостатки:
- каждый раз, когда происходит щелчок, вычисляют дельту времени с момента последнего щелчка, и если он был меньше заданного порога, будет обнаружен двойной щелчок. Однако это решение приводит к тому, что быстрый одиночный щелчок обнаруживается до того, как обнаружен двойной щелчок, что нежелательно в большинстве ситуаций, потому что тогда он активирует действия как одиночного, так и двойного щелчка.
Грубый пример:
float dclick_threshold = 0.25f;
double timerdclick = 0;
if (Input.GetMouseButtonDown(0)
{
if (Time.time - timerdclick) > dclick_threshold)
{
Debug.Log("single click");
//call the SingleClick() function, not shown
} else {
Debug.Log("double click");
//call the DoubleClick() function, not shown
}
timerdclick = Time.time;
}
- установить задержку ожидания для активации одним щелчком, что означает, что при каждом щелчке активировать действия одним щелчком можно только в том случае, если задержка с момента последнего щелчка превышает заданный порог. Однако это дает вялые результаты, поскольку ожидание до того, как можно заметить ожидание, прежде чем будут обнаружены одиночные щелчки. Хуже того, этот тип решения страдает от расхождений между машинами, поскольку он не учитывает, насколько медленным или быстрым является установка скорости двойного щелчка пользователя на уровне операционной системы.
Грубый пример:
float one_click = false;
float dclick_threshold = 0.25f;
double timerdclick = 0;
if (one_click && ((Time.time - timerdclick) > dclick_threshold))
{
Debug.Log("single click");
//call the SingleClick() function, not shown
one_click = false;
}
if (Input.GetMouseButtonDown(0))
{
if (!one_click)
{
dclick = -1;
timerdclick = Time.time;
one_click = true;
}
else if (one_click && ((Time.time - timerdclick) < dclick_threshold))
{
Debug.Log("double click");
//call the DoubleClick() function, not shown
one_click = false;
}
}
Поэтому мои вопросы становятся следующими. Существует ли более совершенный и надежный способ обнаружения двойных щелчков в Unity с использованием C #, помимо этих решений, и способ, который решает вышеупомянутые проблемы?
Ответы:
Сопрограммы это весело:
источник
Я не могу читать по-английски. Но UniRx может помочь вам.
https://github.com/neuecc/UniRx#introduction
источник
Control Panel → Mouse
.Задержка двойного щелчка по умолчанию для Windows составляет 500 мс = 0,5 секунды.
Как правило, в игре гораздо проще обрабатывать двойной щелчок на элементе управления, а не глобально. Если вы решите обрабатывать двойные щелчки по всему миру, вы должны применить обходные пути, чтобы избежать 2 очень нежелательных побочных эффектов:
Если вам нужно использовать глобальную реализацию, вам также нужно посмотреть на местоположение щелчка - если мышь переместилась слишком далеко, это не двойной щелчок. Обычно вы используете трекер фокусировки, который сбрасывает счетчик двойного щелчка при изменении фокуса.
На вопрос, следует ли вам ждать истечения времени ожидания двойного щелчка, это нужно обрабатывать по-разному для каждого элемента управления. У вас есть 4 разных события:
Когда бы ни было возможно, вы пытаетесь спроектировать взаимодействия GUI таким образом, чтобы последнее событие не использовалось: Windows File Explorer сразу выберет элемент одним щелчком мыши, откроет его двойным щелчком и ничего не изменит для подтвержденного одиночного события. нажмите кнопку.
Другими словами: вы используете оба предложенных вами варианта в зависимости от желаемого поведения элемента управления.
источник
Вышеуказанные решения работают для кликов, сделанных на весь экран. Если вы хотите обнаружить двойной щелчок на отдельных кнопках, я обнаружил, что эта модификация приведенного выше ответа работает хорошо:
Прикрепите этот скрипт к любому количеству кнопок. Затем в разделе редактора «По щелчку» (для каждой кнопки, к которой вы его прикрепляете), нажмите «+», добавьте кнопку к себе в качестве игрового объекта, а затем выберите «DoubleClickTest -> startClick ()» в качестве функции для вызова. когда кнопка нажата.
источник
Я искал подходящий обработчик двойного клика. Я нашел эту тему и собрал несколько действительно хороших идей. Итак, наконец, я пришел к следующему решению и хочу поделиться им с вами. Я надеюсь, что вы найдете этот метод полезным.
Я думаю, что это отличный способ использовать инспектор Unity, потому что таким образом ваш код становится более гибким, так как вы можете ссылаться на любой из ваших игровых объектов визуально и безопасно.
Сначала добавьте компонент Event System к любому из ваших игровых объектов. Это также добавит компонент Автономный модуль ввода . Это позаботится о событиях ввода, таких как щелчки мыши и касания. Я рекомендую делать это на отдельном игровом объекте.
Затем добавьте компонент Event Trigger к любому игровому объекту с поддержкой raycast . Как элемент пользовательского интерфейса или спрайт, 3D-объект с коллайдером . Это доставит событие click в наш скрипт. Добавьте тип события Pointer Click и установите игровой объект-приемник, в котором есть компонент сценария Click Controller, и, наконец, выберите его метод onClick () . (Также вы можете изменить скрипт, чтобы получать все клики в Update () и пропустить этот шаг.)
Таким образом, игровой объект-приемник, который, конечно, может быть объектом с триггером события, будет делать что-либо с событиями одиночного или двойного щелчка.
Вы можете установить ограничение по времени для двойного щелчка, нужную кнопку и пользовательские события для одиночного и двойного щелчка. Единственным ограничением является то, что вы можете выбрать только одну кнопку за раз для одного игрового объекта .
Сам скрипт запускает сопрограмму при каждом первом нажатии с двумя таймерами. FirstClickTime и currentTime синхронизируются с первым.
Эта сопрограмма повторяется один раз в конце каждого кадра, пока не истечет срок. Тем временем метод onClick () продолжает считать клики.
Когда срок истекает, он вызывает событие одинарного или двойного щелчка в соответствии с clickCounter. Затем он устанавливает этот счетчик на ноль, чтобы сопрограмма могла завершиться, и весь процесс начинается с самого начала.
источник
Я думаю, что нет никакого способа прочитать мысли пользователя, будь то щелчок одинарным или двойным, в конце концов мы должны ждать ввода. Хотя вы можете установить ожидание 0,01 секунды (как минимум) для второго щелчка. В связи с этим я бы пошел на вариант ожидания.
И ДА
Coroutines
это весело ...Альтернатива
источник