Lo que estoy tratando de entender y aprender aquí es algo muy básico: ¿cuál es la forma más general y pulida de diferenciar adecuadamente los clics simples y dobles para los 3 botones principales del mouse en Unity, usando C #?
Mi énfasis en la palabra correctamente no es para nada. Aunque me sorprendió que esto nunca haya sido preguntado en este sitio web, por supuesto, he buscado y encontrado numerosas preguntas similares en los foros de Unity y en las propias páginas de preguntas y respuestas de Unity. Sin embargo, como suele ser el caso con las respuestas publicadas en estos recursos, todos parecían estar completamente equivocados o al menos un poco demasiado aficionados.
Dejame explicar. Las soluciones propuestas siempre tuvieron cualquiera de los dos enfoques y sus defectos correspondientes:
- cada vez que ocurre un clic, calcule el delta de tiempo desde el último clic y si fuera más pequeño que un umbral dado, se detectaría un doble clic. Sin embargo, esta solución da como resultado que se detecte un solo clic rápido antes de que se detecte el doble clic, lo que no es deseable en la mayoría de las situaciones porque luego activa las acciones tanto de un solo clic como de doble clic.
Áspero ejemplo:
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;
}
- establezca un retraso de espera para que se active el clic único, lo que significa que, con cada clic, solo active las acciones de un solo clic si el tiempo transcurrido desde el último clic supera un umbral determinado. Sin embargo, esto da resultados lentos, ya que esperar antes de que sea posible notar la espera antes de que se detecten los clics únicos. Peor que eso, este tipo de solución adolece de discrepancias entre las máquinas, ya que no tiene en cuenta qué tan lenta o rápida es la configuración de velocidad de doble clic del usuario en el nivel del sistema operativo.
Áspero ejemplo:
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;
}
}
Por lo tanto, mis preguntas se convierten en lo siguiente. ¿Existe una forma más pulida y confiable de detectar los clics dobles en Unity usando C #, aparte de estas soluciones, y una que maneje los problemas antes mencionados?
Respuestas:
Las corutinas son divertidas:
fuente
No puedo leer ingles Pero UniRx puede ayudarlo.
https://github.com/neuecc/UniRx#introduction
fuente
Control Panel → Mouse
.El retraso de doble clic predeterminado de Windows es de 500 ms = 0,5 segundos.
En general, en un juego es mucho más fácil manejar el doble clic en el control que se está haciendo clic, no globalmente. Si decide manejar los clics dobles en todo el mundo, debe implementar soluciones alternativas para evitar 2 efectos secundarios muy indeseables:
Si tiene que usar una implementación global, también deberá mirar la ubicación del clic: si el mouse se movió demasiado, no es un doble clic. Normalmente implementaría un rastreador de enfoque que restablezca el contador de doble clic cada vez que cambie el enfoque.
A la pregunta de si debe esperar hasta que pase el tiempo de espera de doble clic, esto debe manejarse de manera diferente para cada control. Tienes 4 eventos diferentes:
Siempre que sea posible, intente diseñar las interacciones de la GUI de modo que el último evento no se use: el Explorador de archivos de Windows seleccionará un elemento con un solo clic de inmediato, lo abrirá con un doble clic y no hará nada en un solo confirmado hacer clic.
En otras palabras: usa ambas opciones que sugirió, dependiendo de cuál sea el comportamiento deseado del control.
fuente
Las soluciones anteriores funcionan para los clics realizados en toda la pantalla. Si desea detectar doble clic en botones individuales, he encontrado que esta modificación a una respuesta anterior está funcionando bien:
Adjunte este script a todos los botones que desee. Luego, en la sección Al hacer clic del editor (para cada botón al que adjunte esto), haga clic en '+', agregue el botón como el objeto del juego y luego seleccione "DoubleClickTest -> startClick () 'como la función para llamar cuando se presiona el botón.
fuente
Estaba buscando un controlador adecuado de un solo doble clic. Encontré este tema y reuní algunas ideas realmente buenas. Así que finalmente se me ocurrió la siguiente solución y quiero compartirla con ustedes. Espero que encuentre útil este método.
Creo que es un gran enfoque usar el inspector de Unity, porque de esta manera su código es más flexible, ya que puede hacer referencia a cualquiera de los objetos de su juego de forma visual y segura.
Primero agregue el componente Sistema de eventos a cualquiera de sus objetos de juego. Esto también agregará el Módulo de entrada independiente componente . Esto se encargará de los eventos de entrada como clics y toques del mouse. Recomiendo hacer esto en un objeto de juego individual.
A continuación, agregue el componente Disparador de eventos a cualquiera de sus objetos de juego habilitados para Raycast . Como un elemento UI o un sprite, un objeto 3D con un colisionador . Esto entregará el evento click a nuestro script. Agregue el tipo de evento Pointer Click y configure el objeto del juego del receptor que tiene el componente de script Click Controller y finalmente seleccione su onClick () método . (También puede modificar el script para recibir todos los clics en una Actualización () y omitir este paso).
Por lo tanto, el objeto del juego receptor, que por supuesto puede ser el que activa el evento, hará cualquier cosa con los eventos de clic simple o doble.
Puede establecer el límite de tiempo para doble clic, el botón deseado y los eventos personalizados para un solo clic y doble clic. La única limitación es que puedes elegir solo un botón a la vez para un objeto del juego .
El script en sí comienza una rutina en cada primer clic con dos temporizadores. FirstClickTime y currentTime sincronizados con el primero.
Esta rutina se repite una vez al final de cada cuadro hasta que expire el límite de tiempo. Mientras tanto, el método onClick () continúa contando los clics.
Cuando expira el límite de tiempo, llama al evento de uno o dos clics de acuerdo con el clickCounter. Luego establece este contador en cero para que la rutina pueda terminar y todo el proceso comience desde el principio.
fuente
Creo que no hay forma de leer la mente del usuario, ya sea que haga clic en simple o doble, después de todo, tenemos que esperar la entrada. Aunque puede establecer una espera de 0.01 segundos (tanto como mínimo) para el segundo clic. En este sentido, iría por la opción de espera.
Y si
Coroutines
son divertidos ...Una alternativa
fuente