Ce que j'essaie de comprendre et d'apprendre ici est une chose très basique: quelle est la façon la plus générale et la plus raffinée de différencier correctement les clics simples et les double-clics pour les 3 principaux boutons de la souris dans Unity, en utilisant C #?
Mon accent sur le mot correctement n'est pas pour rien. Bien que je sois surpris que cela semble n'avoir jamais été posé sur ce site Web auparavant, j'ai bien sûr cherché et trouvé de nombreuses questions similaires sur les forums d'Unity et les propres pages de questions-réponses d'Unity. Cependant, comme c'est souvent le cas avec les réponses publiées dans ces ressources, elles semblaient toutes être soit complètement fausses, soit au moins un peu trop amateures.
Laissez-moi expliquer. Les solutions proposées ont toujours eu l'une des deux approches et leurs défauts correspondants:
- chaque fois qu'un clic se produit, calculez le delta de temps depuis le dernier clic et s'il était inférieur à un seuil donné, un double clic serait détecté. Cependant, cette solution a pour résultat qu'un simple clic rapide est détecté avant que le double-clic ne soit détecté, ce qui n'est pas souhaitable dans la plupart des situations car il active alors les actions de simple et double-clic.
Exemple approximatif:
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;
}
- définissez un délai d'attente pour l'activation du simple clic, ce qui signifie qu'à chaque clic, n'activez les actions de simple clic que si le délai depuis le dernier clic est supérieur à un seuil donné. Cependant, cela donne des résultats lents, car une attente avant qu'il soit possible de remarquer l'attente avant que des clics simples ne soient détectés. Pire que cela, ce type de solution souffre de divergences entre les machines, car il ne prend pas en compte la vitesse ou la vitesse du paramètre de vitesse de double-clic de l'utilisateur au niveau du système d'exploitation.
Exemple approximatif:
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;
}
}
Par conséquent, mes questions deviennent les suivantes. Existe-t-il un moyen plus sophistiqué et plus fiable de détecter les doubles-clics dans Unity en utilisant C #, autre que ces solutions, et un autre qui gère les problèmes susmentionnés?
Réponses:
Les coroutines sont amusantes:
la source
Je ne peux pas lire l'anglais. Mais UniRx peut être en mesure de vous aider.
https://github.com/neuecc/UniRx#introduction
la source
Control Panel → Mouse
.Le délai de double-clic par défaut de Windows est de 500 ms = 0,5 seconde.
Généralement, dans un jeu, il est beaucoup plus facile de gérer le double-clic sur le contrôle sur lequel vous cliquez, pas de manière globale. Si vous décidez de gérer les doubles-clics globalement, vous devez implémenter des solutions de contournement pour éviter 2 effets secondaires très indésirables:
Si vous devez utiliser une implémentation globale, vous devrez également regarder l'emplacement du clic - si la souris s'est déplacée trop loin, ce n'est pas un double clic. Vous implémenteriez normalement un tracker de focus qui réinitialise le compteur de double-clic chaque fois que le focus change.
À la question de savoir si vous devez attendre la fin du délai de double-clic, cela doit être géré différemment pour chaque contrôle. Vous avez 4 événements différents:
Dans la mesure du possible, vous essayez de concevoir les interactions de l'interface graphique de telle sorte que le dernier événement ne soit pas utilisé: l'Explorateur de fichiers Windows sélectionnera immédiatement un élément en un seul clic, l'ouvrira en un double clic et ne fera rien sur un seul confirmé Cliquez sur.
En d'autres termes: vous utilisez les deux options que vous avez suggérées, en fonction du comportement souhaité du contrôle.
la source
Les solutions ci-dessus fonctionnent pour les clics effectués sur l'ensemble de l'écran. Si vous souhaitez détecter les double-clics sur des boutons individuels, j'ai trouvé que cette modification d'une réponse ci-dessus fonctionne bien:
Attachez ce script à autant de boutons que vous le souhaitez. Ensuite, dans la section On Click de l'éditeur (pour chaque bouton auquel vous l'attachez), cliquez sur '+', ajoutez le bouton à lui-même en tant qu'objet de jeu, puis sélectionnez "DoubleClickTest -> startClick () 'comme fonction à appeler lorsque le bouton est enfoncé.
la source
Je cherchais un bon gestionnaire de simple-double-clic. J'ai trouvé ce sujet et rassemblé de très bonnes idées. J'ai finalement trouvé la solution suivante et je veux la partager avec vous. J'espère que cette méthode vous sera utile.
Je pense que c'est une excellente approche pour utiliser l'inspecteur d'Unity, car de cette façon, votre code est plus flexible car vous pouvez référencer n'importe lequel de vos objets de jeu visuellement et en toute sécurité.
Ajoutez d'abord le composant Event System à l'un de vos objets de jeu. Cela ajoutera également le composant Module d'entrée autonome . Cela prendra en charge les événements d'entrée comme les clics et les touches de la souris. Je recommande de le faire sur un objet de jeu individuel.
Ajoutez ensuite le composant Event Trigger à l'un de vos objets de jeu compatibles avec la diffusion de rayons . Comme un élément d'interface utilisateur ou un sprite, un objet 3D avec un collisionneur . Cela fournira l'événement click à notre script. Ajoutez le type d'événement Pointer Click et définissez l'objet de jeu récepteur qui contient le composant de script Click Controller et enfin sélectionnez son onClick () méthode . (Vous pouvez également modifier le script pour recevoir tous les clics dans une mise à jour () et ignorer cette étape.)
Ainsi, l'objet de jeu récepteur, qui peut bien sûr être celui avec le déclencheur d'événement, fera tout avec les événements de clic simple ou double.
Vous pouvez définir la limite de temps pour le double-clic, le bouton souhaité et les événements personnalisés pour le simple et double-clic. La seule limitation est que vous ne pouvez choisir qu'un seul bouton à la fois pour un objet de jeu .
Le script lui-même démarre une coroutine à chaque premier clic avec deux temporisateurs. Le firstClickTime et le currentTime en synchronisation avec le premier.
Cette coroutine boucle une fois à la fin de chaque image jusqu'à l'expiration du délai. Pendant ce temps, la méthode onClick () continue de compter les clics.
Lorsque le délai expire, il appelle l'événement simple ou double-clic en fonction du clickCounter. Ensuite, il met ce compteur à zéro pour que la coroutine puisse se terminer et que tout le processus recommence depuis le début.
la source
Je pense qu'il n'y a aucun moyen de lire l'esprit de l'utilisateur, qu'il clique sur simple ou double, après tout, nous devons attendre l'entrée. Bien que vous puissiez définir une attente de 0,01 seconde (aussi faible) pour le deuxième clic. À cet égard, je choisirais l'option d'attente.
Et OUI,
Coroutines
c'est amusant ...Une alternative
la source