Was sind die Unterschiede zwischen der Verwendung von GetComponent <Transform> () und this.transform?

7

Ich habe einen Beispielcode gelesen und an meinen eigenen Sachen in Unity gearbeitet. Ich habe viel gesehen GetComponent<>(), und oft wird dies für die Transformation als getan Transform _transform = GetComponent<Transform>().

Ich hatte jedoch bereits Zugriff auf die angehängten Spielobjekte transform, as transform, this.transformor gameObject.transform. Ich kann die Verwendung GetComponent()in den meisten Fällen verstehen , aber warum sollten Sie die Funktion speziell für GameObjectund verwenden, Transformwenn die beiden Elemente zunächst über das Skript zugänglich sind?

Gnemlock
quelle
1
Es gibt keinen Unterschied im Endergebnis.
Savlon

Antworten:

11

Die Geschwindigkeit (schnell bis langsam):

cached _transform >> Component.transform >> Component.GetComponent<Transform>

Und wenn Sie eine UnityEngine.dll C # -Binärdatei zerlegen, sehen Sie, dass transform GetComponent (Mitglied der Komponentenklasse) nicht aufruft, sondern nur die interne Mono-Laufzeitmethode aufruft. Hier ist der Transformationscode.

// UnityEngine.Component
public Transform transform
{
    get
    {
        return this.InternalGetTransform();
    }
}

[WrapperlessIcall]
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern Transform InternalGetTransform();

Und hier ist die GetComponent-Methode der zerlegten Komponentenklasse.

public extern Component GetComponent(Type type);
public T GetComponent<T>() where T : Component
{
    return this.GetComponent(typeof(T)) as T;
}
[WrapperlessIcall]
[MethodImpl(MethodImplOptions.InternalCall)]
public extern Component[] GetComponents(Type type);

GetComponent ist eine Art Suchfunktion, die Generika verwendet. Es ist also etwas langsamer als das Caching.


Originalquelle :

public class Test : MonoBehaviour
{
    Transform _transform;
    void Start()
    {
        _transform = this.transform;
        _transform = gameObject.GetComponent<Transform>();
    }
}

Binär zerlegt:

public class Test : MonoBehaviour
{
    private Transform _transform;
    private void Start()
    {
        // == UnityEngine.Component::get_transform()
        this._transform = base.get_transform(); 

        // == UnityEngine.Component::GetComponent<UnityEngine.Transform>()
        this._transform = base.get_gameObject().GetComponent<Transform>();
    }
}
Jinbom Heo
quelle
8

Wie Jinbom sagte, ist der Hauptunterschied hier die Geschwindigkeit.

Es ist jedoch wichtig zu beachten, dass dies nur für die Transformationseigenschaft von GameObject der Fall ist. Andere Eigenschaften wie Kamera und Starrkörper sind nur Komfortmerkmale und rufen GetComponent <> unter der Haube auf, damit die Leistung identisch ist. Aus diesem Grund hat Unity diese "Helfer" -Eigenschaften in Unity beeinträchtigt, da es nicht sofort offensichtlich ist, dass Unity nach der Komponente suchen wird, anstatt eine zwischengespeicherte Version zurückzugeben.

Mit Ausnahme der in der Frage erwähnten Transformationseigenschaft sollten alle anderen Komponenten bei der ersten verfügbaren Opportunity mit GetComponent <> zwischengespeichert werden, und dieser zwischengespeicherte Wert sollte danach verwendet werden.

TJClifton
quelle
0

Im Moment können Sie davon ausgehen, dass jedes Spielobjekt aufgrund der this.transformSyntax die Transform-Komponente hat . Ich vermute, dass Unity seine API mit der GetComponent<>()Syntax aktualisiert hat, sodass Sie in Zukunft GameObjects ohne "spezielle" Komponenten wie Transform haben können.

Dann können Sie eine „reinere“ Architektur haben , wo Ihr Gameobjects nicht haben zu kommen mit Wandelt (obwohl der Editor noch sie standardmäßig als Konvention könnte hinzufügen).

John
quelle
Transform ist die einzige Komponente, die sich so verhält. Unabhängig davon denke ich nicht, dass das Vertrauen in zukünftige Spekulationen eine gute Antwort ist. Unity hat keinen Vorschlag gemacht, sich auf diese Weise zu bewegen, und ich persönlich bezweifle, dass dies der Fall sein wird (da für ein physisches Objekt in Ihrem Spiel erforderlich ist, dass dieses Objekt Informationen enthält, die für seinen physischen Zustand relevant sind, wie z. B. Position und Größe ).
Gnemlock
Dies scheint auch meine Frage zu kommentieren, beantwortet sie aber nicht.
Gnemlock
-1

Der einzige Grund, warum dies überhaupt this.transformfunktioniert, ist, dass MonoBehavior eine Convenience-Eigenschaft für die Transform-Komponente in dem GameObject implementiert, an das das Verhalten angehängt ist. ... Es ist ziemlich irreführend. Ich denke, das gameObject.transformist semantisch korrekter, aber das spaltet die Haare. Sie machen das Gleiche.

Grönland
quelle
Dies bietet nichts zur Beantwortung meiner eigentlichen Frage. Der einzige Grund , warum etwas funktioniert, ist, dass es eingerichtet wurde. Was ist Ihr Punkt? Ich frage nach dem Unterschied zwischen this.transformund GetComponent<Transform>(), nicht this.transformund gameObject.transform.
Gnemlock
Wieder machen sie das Gleiche.
Grönland