Je fais plus de jeux et pose des questions plus stupides.
J'espère que celui-ci est très bref. Je crée une classe très basique qui déplace simplement un objet Player en appliquant une force à un corps rigide, mais je me suis demandé, devrais-je faire une référence de classe au rb ou juste une variable locale dans Mettre à jour chaque image? (en gardant à l'esprit qu'il existe déjà dans la classe parent d'unité Monobehaviour.GameObject).
Je me demande si faire de nombreuses variables locales ralentirait la boucle dans son ensemble (par local, je veux dire à l'intérieur de la fonction elle-même et non au sommet de la classe - j'espère utiliser le terme correct).
Voici ce que je veux dire, les deux façons dont je pensais le faire:
public class Player : MonoBehaviour {
private void FixedUpdate()
{
Rigidbody rb = GetComponent<Rigidbody>();
float v = Input.GetAxis("Vertical");
rb.AddForce(v * rb.transform.forward * Const.walkForce);
}
}
ou...
public class Player : MonoBehaviour {
Rigidbody rb;
private void Awake()
{
rb = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
float v = Input.GetAxis("Vertical");
rb.AddForce(v * rb.transform.forward * Const.walkForce);
}
}
Réponses:
En général, j'ai constaté que vous devez étendre les données aussi étroitement que possible pour commencer et élargir l'étendue selon vos besoins. Cela signifie que si vous pouvez en faire une variable locale au lieu d'un membre, vous devriez probablement commencer par là.
En effet, une portée plus étroite réduit le nombre d'emplacements dans le code où vous devez raisonner sur ces données, et réduit ainsi le nombre d'emplacements que vous pouvez raisonner incorrectement (ce qui conduit à des bogues).
En fait, déclarer des variables locales seules ne sera jamais pratiquement un problème de performances: elles sont bon marché et les compilateurs modernes peuvent même optimiser les "extras".
Leur initialisation peut être un problème; dans votre cas, votre corps rigide est recherché à chaque fois via
GetComponent
, ce qui a un coût non nul. Si vous savez que le composant de corps rigide ne changera pas pour cet objet de jeu particulier, vous pouvez le rechercher une fois et stocker le résultat dans une variable de membre et éviter une petite surcharge par appel.Il est peu probable que la surcharge par appel soit importante dans cette seule instance, mais au fil du temps, cette opération pour de nombreux composants peut s'additionner. Vous voudriez appliquer un profileur pour être sûr.
Donc, pour résumer: en général, par défaut pour rendre les choses aussi locales que possible, mais dans ce cas, il est probablement raisonnable de créer
rb
un membre afin que vous puissiez effectuer la recherche une foisAwake
et éviter d'avoir à le faire à chaqueFixedUpdate
appel.la source
GetComponent
est assez rapide - vous auriez du mal à faire tout type de recherche ayant une vitesse comparable. À moins que vous ne disposiez de données sur les performances qui suggèrent qu'il s'agit d'un problème, respectez l'approche «garder les choses locales». Vous pouvez toujours l'optimiser ultérieurement. Voir answers.unity.com/questions/185164/… N'oubliez pas que la mise en cache n'est pas non plus gratuite - si vous mettez en cache chaque élémentGetComponent
de votre jeu, ce sera probablement une perte nette. Mesure. Identifiez où les optimisations en valent la peine. Concentrez-vous sur la création d'un grand jeu :)La réponse de Josh Petrie est très bonne - voici une perspective complémentaire.
Lorsque vous travaillez avec du code dont vous comprenez assez bien le domaine, vous pouvez étendre les variables là où elles ont du sens.
Par exemple, si j'ai une
Person
classe avec unewaveGoodbye
méthode, il est possible que ma classe n'ait pas d'hand
objet auparavant et que je puisse le déclarer localement danswaveGoodbye
. Maintenant, il est évident qu'une personne a une main, vous pouvez donc naturellement la déclarer membrePerson
sans y penser, mais le même problème s'applique.Si vous déclarez
hand
localement, vous pouvez ajouter plus tard unekarateChop
méthode qui nécessite également un coup de main. C'est à ce moment que la déclaration de variables localement peut devenir problématique - car les développeurs débutants se rabattent souvent sur la copie / collage de la déclarationwaveGoodbye
et vous avez maintenant le même concept situé à deux endroits. Tout changement doithand
ensuite être modifié aux deux endroits et commence ainsi une colline de bogues defourmis.Donc dans l'ensemble,
Si vous êtes confiant dans le placement de votre déclaration, adaptez-la à l'endroit où cela a du sens.
Si vous n'êtes pas sûr, démarrez local et assurez-vous de refactoriser lorsque vous obtenez une bouffée de réutilisation de code.
Edit: Oh et ne faites pas la même erreur que j'ai de passer trop de temps à déterminer où étendre vos déclarations. Il est difficile de comprendre la structure de vos données à l'avance, et lorsque vous écrivez votre code, la structure a un moyen de se révéler.
la source
Person
devrait avoir le membrehand
si cela est pertinent dans l'application, aide souvent d'autres développeurs (la plupart du temps vous 6 mois plus tard) à mieux comprendre le code. Dans ce cas, il semble logique d'en avoir un enRigidbody
tant que membre de votrePlayer
et, je dis plus, même si cela implique de moins bonnes performances. Dans les jeux vidéo, c'est un point pertinent à considérer, mais je pense que dans le code , être clair est souvent plus important