2016-04-15 10 views
1

Ich brauche Hilfe beim Verständnis der Variablenzuweisung mit der C# -Sprache.Variablenzuordnung und Unity

Beim Scripten mit Monodevelop for Unity weise ich unter anderem RigidBody- und Collider-Komponenten von Spielobjekten lokalen Variablen zu. Wenn ich diese Variablen entweder durch Aufruf ihrer Methoden oder durch Änderung ihrer Attribute ändere, spiegeln sich diese Änderungen in den ursprünglichen Komponenten wider. Um klarer meinen Punkt Ich werde diesen Pseudo-Code unten verlassen:

void someMethod(Rigidbody rb) 
{ 
    Rigidbody localRigidBody; 
    localRigidBody = rb; //assigned external rb component to local rigidBody 
    localRigidBody.velocity = 10.0f; //changes are reflected in the original rb object! 
} 

Was ich verwirrt sind die Veränderungen im Spielobjekt, das die rb Rigibody Komponente „enthält“. Während ich weiß, dass dies funktioniert, sollte es nicht funktionieren, da localRigidBody eine lokale Variable ist und die Änderung der Geschwindigkeit von localRigidBody den Geschwindigkeitswert von rb nicht ändern sollte. Aber es ändert sich und es funktioniert, da das Objekt mit der rb-Komponente seine Geschwindigkeit ändert, wenn ich mein Programm starte. Kannst du mir erklären warum?

Bitte informieren Sie mich, wenn meine Frage nicht geklärt ist und ich versuchen werde, mich besser auszudrücken.

Vielen Dank.

+0

Denken einer Variablen als Zeiger beginnen. Der Speicher enthält die Felder und Eigenschaften der Instanz. Wenn Sie 2 Variablen haben und Sie 'a' zu' b' zuweisen, müssen Sie nur die Zeiger auf den gleichen Speicherbereich setzen. Wenn Sie also den Speicher ändern, auf den beide zeigen, haben beide denselben neuen Wert. –

+0

@RB also sind alle Variablen in C# Zeiger? Vielen Dank für Ihre Antwort. – Dayman75

+0

Ihr 'localRigidBody' wird in diesem Fall eine Referenz auf diesen Starrkörper sein, keine Kopie. Neben einigen Caching-Sachen kann dies als eine Art Lebensqualität angesehen werden, denn anstatt etwas wie "rb.AddForce" zu machen, müssten Sie sonst immer etwas wie "GameObject.FindWithTag (" Foo ") schreiben. GetComponent () .AddForce() '. –

Antwort

2

Einheit wird Rigidbody als Referenz übergeben. Wenn Sie ein copy oder clone von Rigidbody wollen, die völlig unabhängig von dem ursprünglichen Objekt (rb), die auf Ihre Methode übergeben wurden, kann man Instantiate verwenden:

void someMethod(Rigidbody rb) 
{ 
    Rigidbody localRigidBody = Instantiate<Rigidbody>(rb); 
    localRigidBody.velocity = 10.0f; 
} 

Ansonsten in Ihrem ursprünglichen, wie @RB angegeben, Ihre localRigidBody ist nur ein "Alias" für die ursprüngliche rb-Variable, da beide auf das gleiche Objekt (Speicherplatz) zeigen.

Sehen Sie diese SO Frage/Antwort, was vorbei "Referenz" zu verstehen ist: Passing Objects By Reference or Value in C#

Update:

Was passiert, wenn ich ein einfaches Skript erstellen, in dem ich eine Variable „int a = 10 deklarieren " und dann "int b = a" gefolgt von "b = 8". Wird "a" seinen Wert ändern? Oder ist "b" auch ein Alias?

Primitive Datentypen ein wenig anders behandelt werden ;-) Ich rate einige der Forschung auf primitive vs. Referenztypen tun würde, hat Microsoft einige großartige Artikel diese über ... Ihr Beispiel:

Code:

int a = 10; 
Console.WriteLine (a); 
int b = a; 
Console.WriteLine (b); 
b = 8; 
Console.WriteLine (a); 
Console.WriteLine (b); 

Ausgang:

10 
10 
10 
8 
Press any key to continue... 
+0

Vielen Dank für Ihre Zeit :) Nur noch eine Frage, wenn Sie Zeit haben: Was ist, wenn ich ein einfaches Skript erstellen, wo ich eine Variable deklariere "int a = 10;" und dann "int b = a" gefolgt von "b = 8". Wird "a" seinen Wert ändern? Oder ist "b" auch ein Alias? Vielen Dank. – Dayman75

+0

@ Dayman75, überprüfen Sie meine Antwort, ich aktualisierte es – SushiHangover

+1

Ziemlich viel Mühe :) Vielen Dank für Ihre Zeit. – Dayman75

0

Sie stolperte über eine grundlegende "Feature" der meisten Programmierung la nguages.

Es gibt zwei Möglichkeiten, eine Variable zu übergeben um:

Pass von Referenz

In C# Objekte werden als Referenz übergeben. Dies bedeutet, dass Sie, wenn Sie einem Objekt (z. B. Rigidbody rb) ein bereits vorhandenes Objekt einer Variablen zuweisen(), nicht ein neues Objekt erstellen.Stattdessen ist Ihre localRigidBody nur eine Referenz auf . Wenn Sie eine unabhängige Kopie von rb erstellen möchten, müssen Sie sie "klonen".

Pass von Wert

Typen wie int oder double werden von Wert übergeben. Sie erhalten immer eine frische und unabhängige Kopie des übergebenen Parameters.

Ich würde vorschlagen, dass Sie mit dem Lesen der auf einen Abschnitt des Speichers msdn article

+0

Verstanden. Deine Antwort hat einen tollen Job gemacht. Danke :) – Dayman75

+1

@ Dayman75 Ich glaube nicht, dass jemand die Frage tatsächlich beantwortet hat. in Einheit ** Klassen ** sind als Referenz bestanden. ** Strukturen ** werden als Wert übergeben. das ist eine absolute Grundlage des Milieus. – Fattie