1
votes

comment minimiser l'utilisation des instructions else if?

Comment définir la valeur de la direction sans avoir à lancer toutes les autres options?

if (Input.GetKey(right_button)) { direction = 1; }
else if(Input.GetKey(left_button)) { direction = -1; }        
else { direction = 0; }
if (direction!=0) { rb.velocity = new Vector2(player_speed*direction, rb.velocity.y);  }

J'ai besoin de traduire l'entrée du joueur en mouvement. Je ne peux pas utiliser d'axes car je ne peux pas les modifier aussi facilement qu'en utilisant cette méthode.

Comment puis-je optimiser ce morceau de code?


0 commentaires

3 Réponses :


0
votes

Une autre façon d'écrire ce qui précède sans if / else serait la suivante:

// set the value of 0 to direction from the start and change it if it is needed
direction = 0;
if (Input.GetKey(right_button)) 
{ 
    direction = 1; 
}
if(Input.GetKey(left_button)) 
{ 
    direction = -1; 
}

Je ne sais pas si c'est plus lisible. Dans ce cas, je pense que c'est plutôt une préférence sur la façon dont vous voulez écrire ce morceau de code que d'être plus lisible à coup sûr. En d'autres termes, je ne pense pas que les instructions if / else ne soient pas lisibles - comme une légère modification, je vous suggère de placer le corps sur une autre ligne et pas dans la même ligne - mais c'est encore une préférence personnelle :).

if (Input.GetKey(right_button)) 
{ 
    direction = 1; 
}
else if(Input.GetKey(left_button)) 
{ 
    direction = -1; 
}
else 
{ 
    direction = 0; 
}

Concernant votre deuxième question, il n'y a aucun problème de performances dans votre code.

Une autre approche serait la suivante:

direction = Input.GetKey(right_button) 
                ? 1
                : Input.GetKey(left_button)
                      ? -1 
                      : 0;

Essentiellement, nous définissons la valeur de direction sur 0 depuis le début et nous redéfinissons la valeur uniquement si elle est nécessaire (soit Input.GetKey (right_button) ou Input.GetKey (left_button) renvoie true).


1 commentaires

Personnellement, j'utiliserais la troisième approche mais avec direction + = 1 et direction - = 1 de sorte que si les deux touches sont enfoncées, la direction résultante est toujours remise à zéro.



-1
votes

Vous pouvez définir une collection qui détermine quelles entrées fournissent quelle direction:

var direction = directionMap.SingleOrDefault(x => x.isInputPressed).directionalValue;

Et puis pour obtenir la direction, vous obtenez simplement la directionalValue à partir des enregistrements dans la collection où isInputPressed est vrai:

var direction = directionMap.Where(x => x.isInputPressed).Sum(x => x.directionalValue);

L'utilisation de .Where () ici pourrait potentiellement produire des résultats inattendus si les deux les boutons sont pressés à la fois. Si cela n'est jamais prévu, vous pouvez modifier ce qui précède pour utiliser .SingleOrDefault () à la place:

var directionMap = new List<(bool isInputPressed, int directionalValue)>
{
    (Input.GetKey(right_button), 1),
    (Input.GetKey(left_button), -1)
};

Notez que cela produira une exception si plus d'un bouton est enfoncé à la fois. Vous pouvez soit gérer cette exception dans un bloc try / catch. Ou vous pouvez vérifier qu'un seul est pressé avant d'appeler le .SingleOrDefault () puis procéder en conséquence.


6 commentaires

Vos valeurs de gauche sont évaluées uniquement au moment de leur ajout à la liste, elles ne changent donc jamais. Peut-être que vous vouliez stocker des délégués, par exemple. Func ?


Potentiellement. Si la liste est initialisée à chaque fois que la direction est calculée, cette approche fonctionnerait correctement. Sans en savoir plus sur la manière dont ce code est exécuté, dire que les valeurs de la liste doivent changer n'est qu'une hypothèse.


Nous savons que les valeurs de gauche dans la liste doivent changer, c'est un sondage pour les entrées de l'utilisateur qui pourrait changer dans n'importe quelle Update () ! (Vous noterez la balise Unity sur l'OP :) Ce qui signifie que la liste devrait être régénérée et ré-analysée à chaque image.


Dans ce cas, comme vous l'avez dit, chaque exécution de Update () créerait une nouvelle instance de la liste avec de nouvelles valeurs. Cela signifie que les valeurs de chaque instance de la liste n'auraient pas besoin d'être modifiées et qu'elles pourraient être évaluées en toute sécurité au moment de l'initialisation de la liste. Désolé si je suis dense, je ne vois tout simplement pas le problème.


Le terme technique est «sur-ingénierie». S'il est recréé chaque image (et détruit chaque image, donc aussi une tonne de travail GC supplémentaire), le principal problème est l'optimisation. Vous créez une liste d'éléments fixes puis l'itérez dessus pour tester ses valeurs, pourquoi ne pas simplement tester ses valeurs directement et enregistrer sur toute la gestion de la liste?


Parce qu'il fournit une solution à la question des OP: "comment minimiser l'utilisation des instructions else if?". Nulle part dans la question initiale la performance n'est mentionnée comme une préoccupation.



0
votes

Votre souci d'optimisation est prématuré. La réponse de @Christos est la meilleure en termes de performances (copiée ci-dessous)

// set the value of 0 to direction from the start and change it if it is needed
direction = 0;
if (Input.GetKey(right_button)) 
{ 
    direction = 1; 
}
if(Input.GetKey(left_button)) 
{ 
    direction = -1; 
}

C'est la seule optimisation car elle supprime une branche du chemin du code.

Je dirais que pour le style et la lisibilité, évitez les opérateurs terinaires (en utilisant la syntaxe bool? 1: 0). Ils conduisent généralement à un code plus déroutant pour tout ce qui n'a pas renvoyé une valeur clairement lisible avec une condition claire.

La chose à considérer dans ces différentes implémentations est si vous voulez que votre personnage ne bouge que dans quatre directions (en supposant que vous pourriez ajouter de haut en bas) ou soutenir le mouvement diagonal. La suppression des instructions «else» de votre code vous permettra de vous déplacer en diagonale. Si vous gardez le «sinon si», vous ne pourrez vous déplacer que dans des directions cardinales. Si vous voulez seulement vous déplacer à gauche et à droite, ce serait quelque chose de considérer ce qui se passe lorsque les deux sont pressés. Le joueur ne va-t-il nulle part? Le joueur se déplace-t-il dans le sens de la dernière pression? Si vous additionnez de haut en bas, comment faites-vous le suivi si 3 boutons sont pressés?


0 commentaires