Ich mache mehr Spiele und stelle mehr dumme Fragen.
Hoffentlich ist dieser sehr kurz. Ich mache eine sehr einfache Klasse, die nur ein Player-Objekt bewegt, indem sie Kraft auf einen starren Körper ausübt, aber ich habe mich gefragt, ob ich eine Klassenreferenz auf das rb oder nur eine lokale Variable in Update jedes Frames erstellen soll. (Beachten Sie, dass es bereits in der übergeordneten Klasse Monobehaviour.GameObject Unity vorhanden ist.)
Ich frage mich, ob das Ausführen vieler lokaler Variablen die Schleife als Ganzes verlangsamen würde (mit lokal meine ich innerhalb der Funktion selbst und nicht an der Spitze der Klasse - ich hoffe, ich verwende den richtigen Begriff).
Hier ist, was ich meine, die zwei Arten, wie ich es mir vorgestellt habe:
public class Player : MonoBehaviour {
private void FixedUpdate()
{
Rigidbody rb = GetComponent<Rigidbody>();
float v = Input.GetAxis("Vertical");
rb.AddForce(v * rb.transform.forward * Const.walkForce);
}
}
oder...
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);
}
}
Antworten:
Im Allgemeinen habe ich festgestellt, dass Sie den Umfang der Daten zunächst so eng wie möglich gestalten und erweitern sollten, wenn Sie feststellen, dass Sie dies benötigen. Das heißt , wenn Sie kann es sich um eine lokale Variable statt Mitglied machen, sollten Sie wahrscheinlich dort beginnen.
Dies liegt daran, dass ein engerer Bereich die Anzahl der Stellen im Code verringert, an denen Sie über diese Daten argumentieren müssen, und somit die Anzahl der Stellen verringert, an denen Sie falsch argumentieren können (was zu Fehlern führt).
Das Deklarieren lokaler Variablen allein wird praktisch nie ein Leistungsproblem sein: Sie sind billig, und moderne Compiler können sogar "Extras" optimieren.
Das Initialisieren kann ein Problem sein. In Ihrem Fall wird Ihr starrer Körper jedes Mal über nachgeschlagen
GetComponent
, was einige Kosten ungleich Null verursacht. Wenn Sie wissen, dass sich die Starrkörperkomponente für dieses bestimmte Spielobjekt nicht ändert , können Sie sie einmal nachschlagen und das Ergebnis in einer Mitgliedsvariablen speichern, um einen kleinen Aufwand pro Anruf zu vermeiden.Es ist unwahrscheinlich, dass der Overhead pro Anruf in diesem einen Fall erheblich sein wird, aber im Laufe der Zeit kann sich dies für viele Komponenten summieren. Sie möchten sicher einen Profiler anwenden.
Zusammenfassend
rb
lässt sichAwake
sagen, dass es im Allgemeinen standardmäßig darum geht, die Dinge so lokal wie möglich zu gestalten. In diesem Fall ist es jedoch wahrscheinlich sinnvoll, ein Mitglied zu erstellen, damit Sie die Suche einmal durchführen und vermeiden müssen, dass Sie sie bei jedemFixedUpdate
Anruf ausführen müssen .quelle
GetComponent
ist ziemlich schnell - es würde Ihnen schwer fallen, eine Suche mit vergleichbarer Geschwindigkeit durchzuführen . Wenn Sie keine Leistungsdaten haben, die darauf hindeuten, dass es sich um ein Problem handelt, halten Sie sich an den Ansatz "Dinge lokal halten". Sie können es später jederzeit optimieren. Siehe answers.unity.com/questions/185164/… Vergessen Sie nicht, dass das Caching auch nicht kostenlos ist - wenn Sie jedes einzelneGetComponent
in Ihrem Spiel zwischenspeichern, ist dies wahrscheinlich ein Nettoverlust. Messen. Identifizieren Sie, wo sich Optimierungen lohnen. Konzentriere dich darauf, ein großartiges Spiel zu machen :)Die Antwort von Josh Petrie ist sehr gut - hier ist eine ergänzende Perspektive.
Wenn Sie mit Code arbeiten, dessen Domäne Sie ziemlich gut verstehen, können Sie Variablen dort platzieren, wo sie sinnvoll sind.
Wenn ich beispielsweise eine
Person
Klasse mit einerwaveGoodbye
Methode habe, ist es möglich, dass meine Klasse zuvor keinhand
Objekt hatte und ich es daher lokal deklarieren kannwaveGoodbye
. Hier ist es offensichtlich, dass eine Person eine Hand hat, so dass Sie sie natürlich als Mitglied deklarieren können,Person
ohne darüber nachzudenken, aber das gleiche Problem gilt.Wenn Sie
hand
lokal deklarieren, können Sie später einekarateChop
Methode hinzufügen , für die ebenfalls eine Hand erforderlich ist. In diesem Fall kann das lokale Deklarieren von Variablen problematisch werden, da Junior-Entwickler häufig auf das Kopieren / Einfügen der Deklaration zurückgreifenwaveGoodbye
und jetzt dasselbe Konzept an zwei Stellen installiert ist. Alle Änderungenhand
müssen dann an beiden Stellen geändert werden und beginnen somit einenAmeisenbug-Hügel.Alles in allem also
Wenn Sie von der Platzierung Ihrer Erklärung überzeugt sind, legen Sie sie dort fest, wo es sinnvoll ist.
Wenn Sie sich nicht sicher sind, starten Sie local und stellen Sie sicher, dass Sie den Refactor verwenden, wenn Sie einen Hauch von Code-Wiederverwendung erhalten.
Bearbeiten: Oh und machen Sie nicht den gleichen Fehler, den ich habe, wenn Sie zu viel Zeit damit verbringen, herauszufinden, wo Sie Ihre Erklärungen einordnen können. Es ist schwierig, die Struktur Ihrer Daten im Voraus zu verstehen, und während Sie Ihren Code schreiben, kann sich die Struktur offenbaren.
quelle
Person
sollte das Element haben ,hand
wenn ihre maßgebenden in der Anwendung, hilft oft andere Entwickler (meistens Sie 6 Monate später) , um besser den Code zu verstehen. In diesem Fall scheint es logisch, einRigidbody
Mitglied von Ihnen zu haben,Player
und ich sage mehr, auch wenn dies eine schlechtere Leistung impliziert. In Videospielen ist dies ein relevanter Punkt, den ich berücksichtigen muss, aber ich denke, dass es im Code oft wichtiger ist, klar zu sein